guhongwei преди 2 години
родител
ревизия
8f6edee75f

+ 30 - 0
src/router/module/admin.ts

@@ -20,6 +20,36 @@ export default [
     meta: { title: '信息管理' },
     component: () => import('@/views/company/detail.vue')
   },
+  {
+    path: '/person/fixed',
+    meta: { title: '固定人员' },
+    component: () => import('@/views/person/fixed/index.vue')
+  },
+  {
+    path: '/person/fixed/detail',
+    meta: { title: '信息管理' },
+    component: () => import('@/views/person/fixed/detail.vue')
+  },
+  {
+    path: '/person/flow',
+    meta: { title: '流动人员' },
+    component: () => import('@/views/person/flow/index.vue')
+  },
+  {
+    path: '/person/flow/detail',
+    meta: { title: '信息管理' },
+    component: () => import('@/views/person/flow/detail.vue')
+  },
+  {
+    path: '/person/committee',
+    meta: { title: '学术委员会' },
+    component: () => import('@/views/person/committee/index.vue')
+  },
+  {
+    path: '/person/committee/detail',
+    meta: { title: '信息管理' },
+    component: () => import('@/views/person/committee/detail.vue')
+  },
   {
     path: '/policyfile',
     meta: { title: '政策文件' },

+ 33 - 0
src/views/person/committee/detail.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="detail">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">系统首页</van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+// import type { Ref } from 'vue';
+// reactive, ref, onMounted
+import { onMounted } from 'vue';
+// 接口
+import { TestStore } from '@common/src/stores/test';
+import type { IQueryResult } from '@/util/types.util';
+const testAxios = TestStore();
+// 分页数据
+const skip = 0;
+const limit = 10;
+// 请求
+onMounted(async () => {
+  await search({ skip, limit });
+});
+const search = async (e: { skip: number; limit: number }) => {
+  const info = { skip: e.skip, limit: e.limit };
+  const res: IQueryResult = await testAxios.query(info);
+  console.log(res);
+};
+</script>
+<style scoped lang="scss"></style>

+ 33 - 0
src/views/person/committee/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="index">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">系统首页</van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+// import type { Ref } from 'vue';
+// reactive, ref, onMounted
+import { onMounted } from 'vue';
+// 接口
+import { TestStore } from '@common/src/stores/test';
+import type { IQueryResult } from '@/util/types.util';
+const testAxios = TestStore();
+// 分页数据
+const skip = 0;
+const limit = 10;
+// 请求
+onMounted(async () => {
+  await search({ skip, limit });
+});
+const search = async (e: { skip: number; limit: number }) => {
+  const info = { skip: e.skip, limit: e.limit };
+  const res: IQueryResult = await testAxios.query(info);
+  console.log(res);
+};
+</script>
+<style scoped lang="scss"></style>

+ 315 - 0
src/views/person/fixed/detail.vue

@@ -0,0 +1,315 @@
+<template>
+  <div id="detail">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">
+          <van-form @submit="toSave" label-width="auto">
+            <van-cell-group>
+              <van-field
+                v-model="form.act_time"
+                is-link
+                readonly
+                name="act_time"
+                label="活动时间"
+                placeholder="点击选择"
+                @click="toPopup({ type: 'act_time' })"
+              />
+              <van-field v-model="form.lab_id" name="lab_id" style="display: none" />
+              <van-field v-model="form.lab_name" name="lab_name" label="实验室名称" placeholder="请输入实验室名称" readonly />
+              <van-field v-model="form.name" name="name" type="textarea" rows="1" autosize label="姓名" placeholder="请输入姓名" />
+              <van-field v-model="form.age" name="age" type="textarea" rows="1" autosize label="年龄" placeholder="请输入年龄" />
+              <van-field v-model="form.unit" name="unit" type="textarea" rows="1" autosize label="工作单位及部门" placeholder="请输入工作单位及部门" />
+              <van-field v-model="form.zwzc" name="zwzc" type="textarea" rows="1" autosize label="职务职称" placeholder="请输入职务职称" />
+              <van-field v-model="form.zwzc" name="zwzc" type="textarea" rows="1" autosize label="身份证号" placeholder="请输入身份证号" />
+              <van-field v-model="form.zwzc" name="zwzc" type="textarea" rows="1" autosize label="学历" placeholder="请输入学历" />
+              <van-field v-model="form.zwzc" name="zwzc" type="textarea" rows="1" autosize label="现从事专业" placeholder="请输入现从事专业" />
+              <van-field
+                v-model="form.direction"
+                is-link
+                readonly
+                name="direction"
+                label="研究方向"
+                placeholder="点击选择"
+                @click="toPopup({ type: 'direction' })"
+              />
+              <van-field v-model="form.is_show" is-link readonly name="is_show" label="是否公开" placeholder="点击选择" @click="toPopup({ type: 'is_show' })" />
+              <van-field name="logs" label="任职记录">
+                <template #input>
+                  <van-col span="24" class="logs">
+                    <van-col span="24" class="logs_1">
+                      <van-button type="primary" size="small" @click="addLogs()">添加记录</van-button>
+                    </van-col>
+                    <van-col span="24" class="logs_2">
+                      <van-col span="24" class="list" v-for="(i, index) in form.logs" :key="index">
+                        <van-col span="24" class="list_1">
+                          <van-col span="20" class="list_1_type">{{ index + 1 }}.{{ i.type }}</van-col>
+                          <van-col span="4" class="list_1_btn">
+                            <van-button type="danger" size="mini" @click="delLogs(i)">删除</van-button>
+                          </van-col>
+                        </van-col>
+                        <van-col span="24" class="list_2">时间:{{ i.time }}</van-col>
+                      </van-col>
+                    </van-col>
+                  </van-col>
+                </template>
+              </van-field>
+            </van-cell-group>
+            <div class="btn">
+              <van-button type="primary" size="small" native-type="submit"> 提交保存 </van-button>
+            </div>
+          </van-form>
+        </van-col>
+      </van-col>
+    </van-row>
+    <van-popup v-model:show="popup.show" position="bottom">
+      <template v-if="popup.type == 'act_time'">
+        <van-picker :columns="actList" :columns-field-names="{ text: 'name', value: '_id' }" @confirm="popChange" @cancel="toCancel" />
+      </template>
+      <template v-else-if="popup.type == 'direction'">
+        <van-picker :columns="directionList" :columns-field-names="{ text: 'name', value: '_id' }" @confirm="popChange" @cancel="toCancel" />
+      </template>
+      <template v-else-if="popup.type == 'is_show'">
+        <van-picker :columns="showList" :columns-field-names="{ text: 'dict_label', value: 'dict_value' }" @confirm="popChange" @cancel="toCancel" />
+      </template>
+    </van-popup>
+    <cPopup :popupInfo="popupInfo">
+      <template v-slot:info>
+        <van-col span="24" class="popup_one" v-if="popupInfo.type == '1'">
+          <van-form @submit="logsSave" label-width="auto">
+            <van-cell-group>
+              <van-field name="type" label="注册用户类型">
+                <template #input>
+                  <van-radio-group v-model="logsForm.type" direction="horizontal">
+                    <van-radio :name="i.value" v-for="i in typeList" :key="i.value">{{ i.label }}</van-radio>
+                  </van-radio-group>
+                </template>
+              </van-field>
+              <van-field v-model="logsForm.time" is-link readonly name="time" label="时间" placeholder="点击选择" @click="logsShow = true" />
+              <van-popup v-model:show="logsShow" position="bottom">
+                <van-date-picker :columns-type="['year', 'month', 'day']" @confirm="logstimeChange" @cancel="logsShow = false" />
+              </van-popup>
+              <div class="btn">
+                <van-button type="primary" size="small" native-type="submit"> 提交保存 </van-button>
+              </div>
+            </van-cell-group>
+          </van-form>
+        </van-col>
+      </template>
+    </cPopup>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+// import _ from 'lodash';
+import moment from 'moment';
+import type { Ref } from 'vue';
+import { onMounted, ref } from 'vue';
+import { useRoute } from 'vue-router';
+import { showToast } from 'vant';
+// 接口
+import { BasicStore } from '@common/src/stores/basic/basic';
+import { ActivitysStore } from '@common/src/stores/basic/activitys';
+import { FixedpersonnelStore } from '@common/src/stores/basic/fixedpersonnel';
+import { DirectionStore } from '@common/src/stores/basic/direction';
+import { DictDataStore } from '@common/src/stores/users/sysdictdata'; // 字典表
+
+import type { IQueryResult } from '@/util/types.util';
+import store from '@/stores/counter';
+const basicAxios = BasicStore();
+const actAxios = ActivitysStore();
+const fixedperAxios = FixedpersonnelStore();
+const directionAxios = DirectionStore();
+const dictAxios = DictDataStore();
+
+// 路由
+const route = useRoute();
+
+// 实验室基础信息
+const lab_id: Ref<any> = ref('');
+const basicInfo: Ref<any> = ref({});
+const labList: Ref<any> = ref([]);
+// 活动时间
+const actList: Ref<any> = ref([]);
+
+const id: Ref<any> = ref('');
+// 表单
+const form: Ref<any> = ref({ logs: [] });
+
+// 弹框
+const popup: Ref<any> = ref({ show: false, type: '' });
+// 弹出层
+const popupInfo: Ref<any> = ref({ show: false, type: '1', title: '任职记录' });
+// 任职记录
+const logsForm: Ref<any> = ref({});
+const logsShow: Ref<any> = ref(false);
+// 字典表
+const typeList: Ref<any> = ref([
+  { value: '入驻', label: '入驻' },
+  { value: '退出', label: '退出' }
+]);
+const directionList: Ref<any> = ref([]);
+const showList: Ref<any> = ref([]);
+
+// 请求
+onMounted(async () => {
+  // 实验室id
+  lab_id.value = store.getters.lab_id;
+  id.value = route.query.id;
+  // 查询基础信息
+  await searchBasic();
+  // 查询其他信息
+  await searchOther();
+  await search();
+});
+// 查询基础信息
+const searchBasic = async () => {
+  let res: IQueryResult = await basicAxios.fetch(lab_id.value);
+  if (res.errcode == '0') {
+    let data = res.data as any;
+    basicInfo.value = data;
+    labList.value = [data];
+    form.value.lab_id = data._id;
+    form.value.lab_name = data.name;
+    // 查询活动时间
+    const isInAct = store.state.isInAct;
+    if (!isInAct) searchAct(data);
+  }
+};
+// 查询活动时间
+const searchAct = async (e) => {
+  const query = { is_use: '0', type: '' };
+  if (e.status == '1') query.type = '-1';
+  else if (e.status == '2') query.type = '2';
+  else query.type = '1';
+  let res: IQueryResult = await actAxios.query(query);
+  if (res.errcode == '0') {
+    actList.value = res.data;
+  }
+};
+const search = async () => {
+  if (id.value) {
+    let res: IQueryResult = await fixedperAxios.fetch(id.value);
+    if (res.errcode == '0') {
+      let data = res.data as any;
+      form.value = data;
+      form.value.lab_name = basicInfo.value.name;
+      form.value.act_time = data.act_time._id;
+    }
+  }
+};
+// 选择
+const toPopup = (e) => {
+  popup.value = { show: true, type: e.type };
+};
+const popChange = (e) => {
+  let value = e.selectedValues;
+  if (popup.value.type == 'act_time') {
+    form.value.act_time = value[0];
+  } else if (popup.value.type == 'direction') {
+    form.value.direction = value[0];
+  } else if (popup.value.type == 'is_show') {
+    form.value.is_show = value[0];
+  }
+  toCancel();
+};
+// 关闭
+const toCancel = () => {
+  popup.value = { show: false };
+};
+// 添加记录
+const addLogs = () => {
+  popupInfo.value = { show: true, type: '1', title: '任职记录' };
+};
+// 选择时间
+const logstimeChange = (e) => {
+  let value = e.selectedValues;
+  logsForm.value.time = value.join('-');
+  logsShow.value = false;
+};
+// 任职记录保存
+const logsSave = (e) => {
+  let logs = form.value.logs || [];
+  logs.push({ ...e, id: moment().valueOf() });
+  form.value.logs = logs;
+  popupInfo.value = { show: false };
+};
+// 任职记录删除
+const delLogs = (e) => {
+  let logs = form.value.logs.filter((i: any) => i.id != e.id);
+  form.value.logs = logs;
+};
+// 保存
+const toSave = async (e) => {
+  let res: IQueryResult;
+  delete e.lab_name;
+  if (id.value) {
+    // if (_.isObject(e.act_time)) e.act_time = e.act_time._id;
+    e.logs = form.value.logs;
+    res = await fixedperAxios.update({ ...e, _id: id.value });
+  } else res = await fixedperAxios.create(e);
+  if (res.errcode == '0') {
+    showToast({ message: '信息删除成功', type: 'success', duration: 500 });
+    toBack();
+  } else {
+    showToast({ message: `${res.errmsg}`, type: 'fail', duration: 500 });
+  }
+};
+// 查询其他信息
+const searchOther = async () => {
+  let res: IQueryResult;
+  // 所属研究方向
+  res = await directionAxios.query({ lab_id: lab_id.value });
+  if (res.errcode == '0') {
+    directionList.value = res.data;
+  }
+  // 是否公开
+  res = await dictAxios.query({ dict_type: 'info_show' });
+  if (res.errcode == '0') {
+    showList.value = res.data;
+  }
+};
+
+// 返回;
+const toBack = () => {
+  window.history.go(-1);
+};
+</script>
+<style scoped lang="scss">
+.main {
+  .one {
+    .btn {
+      text-align: center;
+      margin: 10px 0;
+    }
+  }
+}
+.logs {
+  display: flex;
+  flex-direction: column;
+  .logs_1 {
+    margin: 0 0 5px 0;
+  }
+  .logs_2 {
+    .list {
+      border: 1px solid #858585;
+      border-radius: 5px;
+      margin: 0 0 5px 0;
+      padding: 5px;
+      .list_1 {
+        display: flex;
+        flex-direction: row;
+        .list_1_btn {
+          text-align: right;
+        }
+      }
+    }
+  }
+}
+.popup_one {
+  .btn {
+    text-align: center;
+    margin: 10px 0;
+  }
+}
+</style>

+ 258 - 0
src/views/person/fixed/index.vue

@@ -0,0 +1,258 @@
+<template>
+  <div id="index">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">
+          <van-col span="20" class="one_1">
+            <van-field v-model="searchForm.name" placeholder="请输入单位名称" @blur="toInput" />
+          </van-col>
+          <van-col span="4" class="one_2">
+            <van-button size="small" @click="toAdd" :disabled="isInAct">新增</van-button>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="two">
+          <van-col span="24" class="list" v-for="i in list" :key="i._id">
+            <van-col span="24" class="name">{{ i.name }}</van-col>
+            <van-col span="24" class="other">
+              <van-col span="24" class="other_1">
+                <span>年龄:</span>
+                <span>{{ i.age }}</span>
+              </van-col>
+              <van-col span="24" class="other_1">
+                <span>研究方向:</span>
+                <span>{{ getDict(i.direction, 'direction') }}</span>
+              </van-col>
+              <van-col span="24" class="other_1">
+                <span>身份证号:</span>
+                <span>{{ i.card }}</span>
+              </van-col>
+            </van-col>
+            <van-col span="24" class="btn">
+              <van-button type="primary" size="small" @click="toEdit(i)">信息编辑</van-button>
+              <van-button type="danger" size="small" @click="toDel(i)">信息删除</van-button>
+              <van-button type="warning" size="small" @click="toFile(i)">信息附件</van-button>
+            </van-col>
+          </van-col>
+        </van-col>
+        <van-col span="24" class="thr">
+          <cPage :total="total" :limit="limit" @search="search"> </cPage>
+        </van-col>
+      </van-col>
+    </van-row>
+    <cPopup :popupInfo="popupInfo">
+      <template v-slot:info>
+        <van-col span="24" class="popup_one" v-if="popupInfo.type == '1'">
+          <van-form @submit="toSave" label-width="auto">
+            <van-cell-group>
+              <van-field name="file" label="佐证资料">
+                <template #input>
+                  <vUpload :file="form.file" :count="2"></vUpload>
+                </template>
+              </van-field>
+            </van-cell-group>
+            <div class="btn">
+              <van-button type="primary" size="small" native-type="submit"> 提交保存 </van-button>
+            </div>
+          </van-form>
+        </van-col>
+      </template>
+    </cPopup>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+import _ from 'lodash';
+import type { Ref } from 'vue';
+import { onMounted, ref, getCurrentInstance } from 'vue';
+import { useRouter } from 'vue-router';
+import { showConfirmDialog, showToast } from 'vant';
+import store from '@/stores/counter';
+
+// 接口
+import { FixedpersonnelStore } from '@common/src/stores/basic/fixedpersonnel';
+import { DirectionStore } from '@common/src/stores/basic/direction';
+import type { IQueryResult } from '@/util/types.util';
+const fixedperAxios = FixedpersonnelStore();
+const directionAxios = DirectionStore();
+
+// 基本设置
+const { proxy } = getCurrentInstance() as any;
+
+// 路由
+const router = useRouter();
+
+// 实验室id
+const lab_id: Ref<any> = ref('');
+const isInAct: Ref<any> = ref(true);
+
+const list: Ref<any> = ref([]);
+const total: Ref<any> = ref(0);
+const skip = 0;
+const limit: number = proxy.$limit;
+// 查询
+const searchForm: Ref<any> = ref({});
+
+// 研究方向
+const directionList: Ref<any> = ref([]);
+
+// 弹出层
+const popupInfo: Ref<any> = ref({ show: false, type: '1', title: '佐证资料' });
+const form: Ref<any> = ref({});
+// 请求
+onMounted(async () => {
+  // 实验室id
+  lab_id.value = store.getters.lab_id;
+  // 是否可改
+  isInAct.value = store.state.isInAct;
+  // 查询其他信息
+  await searchOther();
+  // 查询列表
+  await search({ skip, limit });
+});
+const search = async (e: { skip: number; limit: number }) => {
+  if (!lab_id.value) {
+    toPoint();
+    return;
+  }
+  const { skip, limit } = e;
+  const condition = _.cloneDeep(searchForm.value);
+  let info = { limit: limit, skip: skip, ...condition, lab_id: lab_id.value };
+  let res: IQueryResult = await fixedperAxios.query(info);
+  if (res.errcode == 0) {
+    list.value = res.data as [];
+    total.value = res.total;
+  }
+};
+// 名称查询
+const toInput = () => {
+  search({ skip, limit });
+};
+const getDict = (e, model) => {
+  if (model == 'direction') {
+    const data = directionList.value.find((i: any) => i._id == e);
+    if (data) return data.name;
+    else return '暂无';
+  }
+};
+// 新增
+const toAdd = () => {
+  router.push({ path: '/person/fixed/detail' });
+};
+// 信息修改
+const toEdit = (e) => {
+  router.push({ path: '/person/fixed/detail', query: { id: e._id } });
+};
+// 信息删除
+const toDel = async (e) => {
+  showConfirmDialog({
+    title: '提示',
+    message: '您确认删除该数据?',
+    width: '100%'
+  })
+    .then(async () => {
+      let res: IQueryResult = await fixedperAxios.del(e._id);
+      if (res.errcode == '0') {
+        showToast({ message: '信息删除成功', type: 'success', duration: 500 });
+        search({ skip, limit });
+      } else {
+        showToast({ message: `${res.errmsg}`, type: 'fail', duration: 500 });
+      }
+    })
+    .catch(() => {});
+};
+// 信息附件
+const toFile = (e) => {
+  form.value = e;
+  popupInfo.value = { show: true, type: '1', title: '佐证资料' };
+};
+// 提交保存
+const toSave = async (e) => {
+  const obj = { _id: form.value._id, file: e.file };
+  const res: IQueryResult = await fixedperAxios.update(obj);
+  if (res.errcode == '0') {
+    showToast({ message: '附件维护成功', type: 'success' });
+    toClose();
+    search({ skip, limit });
+  } else {
+    showToast({ message: `${res.errmsg}`, type: 'fail' });
+  }
+};
+// 关闭弹框
+const toClose = () => {
+  popupInfo.value = { show: false, type: '1', title: '佐证资料' };
+};
+const toPoint = () => {
+  showToast({ message: `当前用户未维护基础信息,不可操作`, type: 'fail' });
+};
+// 查询其他信息
+const searchOther = async () => {
+  let res: IQueryResult;
+  // 所属研究方向
+  res = await directionAxios.query({ lab_id: lab_id.value });
+  if (res.errcode == '0') {
+    directionList.value = res.data;
+  }
+};
+</script>
+<style scoped lang="scss">
+.main {
+  height: 100vh;
+  overflow: hidden;
+  .one {
+    display: flex;
+    padding: 10px;
+    height: 9vh;
+    .one_1 {
+      .van-cell {
+        padding: 5px;
+        border: 1px solid #f1f1f1;
+      }
+    }
+    .one_2 {
+      .van-button {
+        width: 100%;
+        height: 4.8vh;
+      }
+    }
+  }
+  .two {
+    height: 85vh;
+    overflow-y: auto;
+    padding: 0 10px;
+    .list {
+      border: 1px solid #f1f1f1;
+      margin: 0 0 10px 0;
+      padding: 10px;
+      border-radius: 5px;
+      .name {
+        font-size: 16px;
+        font-weight: bold;
+        margin: 0 0 5px 0;
+      }
+      .other {
+        margin: 0 0 5px 0;
+        .other_1 {
+          font-size: 14px;
+        }
+      }
+      .btn {
+        text-align: center;
+        .van-button {
+          margin: 0 10px;
+        }
+      }
+    }
+  }
+  .thr {
+    height: 6vh;
+    overflow: hidden;
+  }
+}
+.popup_one {
+  .btn {
+    text-align: center;
+    margin: 10px 0;
+  }
+}
+</style>

+ 33 - 0
src/views/person/flow/detail.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="detail">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">系统首页</van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+// import type { Ref } from 'vue';
+// reactive, ref, onMounted
+import { onMounted } from 'vue';
+// 接口
+import { TestStore } from '@common/src/stores/test';
+import type { IQueryResult } from '@/util/types.util';
+const testAxios = TestStore();
+// 分页数据
+const skip = 0;
+const limit = 10;
+// 请求
+onMounted(async () => {
+  await search({ skip, limit });
+});
+const search = async (e: { skip: number; limit: number }) => {
+  const info = { skip: e.skip, limit: e.limit };
+  const res: IQueryResult = await testAxios.query(info);
+  console.log(res);
+};
+</script>
+<style scoped lang="scss"></style>

+ 33 - 0
src/views/person/flow/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="index">
+    <van-row>
+      <van-col span="24" class="main animate__animated animate__backInRight">
+        <van-col span="24" class="one">系统首页</van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+// 基础
+// import type { Ref } from 'vue';
+// reactive, ref, onMounted
+import { onMounted } from 'vue';
+// 接口
+import { TestStore } from '@common/src/stores/test';
+import type { IQueryResult } from '@/util/types.util';
+const testAxios = TestStore();
+// 分页数据
+const skip = 0;
+const limit = 10;
+// 请求
+onMounted(async () => {
+  await search({ skip, limit });
+});
+const search = async (e: { skip: number; limit: number }) => {
+  const info = { skip: e.skip, limit: e.limit };
+  const res: IQueryResult = await testAxios.query(info);
+  console.log(res);
+};
+</script>
+<style scoped lang="scss"></style>