message.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <script setup lang="ts">
  2. import { ref, reactive, nextTick, onMounted, onActivated } from "vue";
  3. import { ElMessageBox, ElMessage } from "element-plus";
  4. import { Calendar } from "@element-plus/icons-vue";
  5. import { getAssessmentDetails } from "@/api/assessment";
  6. import dayjs from "dayjs";
  7. // 获取医疗组的数据
  8. import { postPageGroup } from "@/api/userGroup";
  9. import { postAddAssessment, updateAssessment } from "@/api/assessment";
  10. import { postListTreeWithUser } from "@/api/department";
  11. import { getTemplateInfoAllList } from "@/api/templateInfo";
  12. import ElPicker from "@/components/ELPicker/index.vue";
  13. // 人员,医疗组,负责人
  14. import {
  15. postUserList,
  16. postOrganizationUserPage,
  17. getLeaderList
  18. } from "@/api/userSetting";
  19. const $emit = defineEmits(["addHandClick"]);
  20. const $props = defineProps({
  21. id: {
  22. type: String
  23. },
  24. bistatus: {
  25. type: Number,
  26. default: 1
  27. }
  28. });
  29. const params = reactive({
  30. id: $props.id
  31. });
  32. const dialogVisibleAdd = ref(false);
  33. const btn = ref(true);
  34. const btnShow = () => {
  35. btn.value = false;
  36. };
  37. // 季度 半年
  38. const ElPickerRef = ref();
  39. const form = reactive({
  40. name: "",
  41. cycle: "月度",
  42. cycleValue: "",
  43. assessmentType: null,
  44. scoreConversion: null,
  45. assessmentObjectList: [
  46. {
  47. assessmentObjectId: "",
  48. assessmentObjectName: "",
  49. assessmentModelId: "",
  50. assessmentModelName: ""
  51. }
  52. ]
  53. });
  54. const rules = reactive({
  55. name: [{ required: true, message: "请填写名称", trigger: "blur" }]
  56. });
  57. const formLeftRules = reactive({
  58. left: [{ required: true, message: "请选择考核指标", trigger: "blur" }],
  59. value: [{ required: true, message: "请选择被考核对象", trigger: "blur" }]
  60. });
  61. const formRightRules = reactive({
  62. left: [{ required: true, message: "请选择考核指标", trigger: "blur" }],
  63. right: [{ required: true, message: "请选择考核模板", trigger: "blur" }]
  64. });
  65. const handleClose = () => {
  66. btn.value = true;
  67. };
  68. // 添加部门保存
  69. const saveDepartment = async () => {
  70. updateAssessmentApi();
  71. };
  72. const addNew = () => {
  73. form.assessmentObjectList.push({
  74. assessmentObjectId: "",
  75. assessmentObjectName: "",
  76. assessmentModelId: "",
  77. assessmentModelName: ""
  78. });
  79. // form.assessmentObjectList.left.push({ value: "" });
  80. };
  81. const deleteItem = (index: any) => {
  82. form.assessmentObjectList.splice(index, 1);
  83. // form.assessmentObjectList.right.splice(index, 1);
  84. };
  85. // 单选
  86. const timeType = ref<any>("月度");
  87. const quarterValue = ref(true);
  88. const format = ref<any>("YYYY-MM");
  89. const pickerType = ref<any>("month");
  90. const handleRegionChange = (value: any) => {
  91. timeType.value = value;
  92. switch (value) {
  93. case "年度":
  94. format.value = "YYYY";
  95. pickerType.value = "year";
  96. break;
  97. case "月度":
  98. format.value = "YYYY-MM";
  99. pickerType.value = "month";
  100. break;
  101. case "日期":
  102. format.value = "YYYY-MM-DD";
  103. pickerType.value = "";
  104. break;
  105. case "季度":
  106. quarterValue.value = true;
  107. break;
  108. case "半年":
  109. quarterValue.value = false;
  110. break;
  111. }
  112. };
  113. const yearTime = ref<any>(dayjs(new Date()).format("YYYY"));
  114. const decreaseYear = () => {
  115. yearTime.value = dayjs().year(yearTime.value).subtract(1, "year").year(); // 减一年
  116. };
  117. const increaseYear = () => {
  118. yearTime.value = dayjs().year(yearTime.value).add(1, "year").year(); // 加一年
  119. };
  120. const monthOne = item => {
  121. let start = "";
  122. let end = "";
  123. switch (item) {
  124. case "一季度":
  125. start = `${yearTime.value}-01-01`;
  126. end = `${yearTime.value}-03-31`;
  127. break;
  128. case "二季度":
  129. start = `${yearTime.value}-04-01`;
  130. end = `${yearTime.value}-06-30`;
  131. break;
  132. case "三季度":
  133. start = `${yearTime.value}-07-01`;
  134. end = `${yearTime.value}-09-30`;
  135. break;
  136. case "四季度":
  137. start = `${yearTime.value}-10-01`;
  138. end = `${yearTime.value}-12-31`;
  139. break;
  140. case "上半年":
  141. start = `${yearTime.value}-01-01`;
  142. end = `${yearTime.value}-06-30`;
  143. break;
  144. case "下半年":
  145. start = `${yearTime.value}-07-01`;
  146. end = `${yearTime.value}-12-31`;
  147. break;
  148. }
  149. form.cycleValue = `${yearTime.value}年${item}`;
  150. // return `从 ${start} 到 ${end}`; // 设置时间区间
  151. };
  152. // 部门人员与考核模板数据
  153. const treeDept = ref([]);
  154. const templateparams = reactive({
  155. page: 1,
  156. pageSize: 100
  157. });
  158. const resTmp = ref([]);
  159. const postListTreeWithUserApi = async () => {
  160. const res = await postListTreeWithUser();
  161. const { data = [], code } = await getTemplateInfoAllList();
  162. resTmp.value = data;
  163. treeDept.value = [];
  164. treeDept.value = transformData(res.data);
  165. };
  166. const treeDept_person = ref([]);
  167. const transformData_person = (
  168. data,
  169. newDeptCodeKey = "userCodeNew",
  170. newDeptNameKey = "userNameNew"
  171. ) => {
  172. return data.map(item => {
  173. const newItem = { ...item };
  174. newItem.children = [
  175. ...(newItem.childrenUserRes || []).map(child => ({
  176. ...child
  177. }))
  178. ];
  179. delete newItem.childrenUserRes;
  180. delete newItem.childrenRes;
  181. // 重命名属性
  182. newItem.children = newItem.children.map(child => {
  183. const newChild = { ...child };
  184. newChild.userNameNew = child.realName;
  185. newChild.userCodeNew = child.userCode;
  186. return newChild;
  187. });
  188. // 递归处理子节点
  189. if (newItem.children && newItem.children.length) {
  190. newItem.children = transformData_person(
  191. newItem.children,
  192. newDeptCodeKey,
  193. newDeptNameKey
  194. );
  195. }
  196. return newItem;
  197. });
  198. };
  199. // 获取人员的数据
  200. const getPersonList = async () => {
  201. const res = await postListTreeWithUser();
  202. let treeList = res.data.map(item => {
  203. return {
  204. childrenRes: item.childrenRes,
  205. childrenUserRes: item.childrenUserRes,
  206. userCodeNew: item.deptCode,
  207. userNameNew: item.deptName
  208. };
  209. });
  210. treeDept_person.value = transformData_person(treeList);
  211. };
  212. postListTreeWithUserApi();
  213. function transformData(arr) {
  214. return arr.map(item => {
  215. const {
  216. deptName: userName,
  217. deptCode: userCode,
  218. childrenRes,
  219. ...rest
  220. } = item;
  221. return {
  222. userName,
  223. userCode,
  224. childrenRes: childrenRes ? transformData(childrenRes) : [],
  225. ...rest
  226. };
  227. });
  228. }
  229. // 详情
  230. const treeDeptList = ref([]);
  231. const optionValue = ref([]);
  232. // 考核对象
  233. const assessmentObjectList = ref([]);
  234. // 考核模板
  235. const assessmentModelList = ref([]);
  236. const getAssessmentDetailsApi = async () => {
  237. const { data, code, msg } = await getAssessmentDetails({ id: params.id });
  238. if (code === 200) {
  239. Object.assign(form, data);
  240. console.log(123123, form.assessmentObjectList);
  241. // 用于存放分组后的数组
  242. let groupedData = [];
  243. // 用于存储每个 `assessmentModelId` 的组
  244. let modelIdMap = {};
  245. // 遍历数据,将数据按 `assessmentModelId` 分组
  246. if (form.assessmentObjectList && form.assessmentObjectList.length > 0) {
  247. form.assessmentObjectList.forEach(item => {
  248. const modelId = item.assessmentModelId;
  249. // 如果该 modelId 已存在,则将数据加入对应的组
  250. if (!modelIdMap[modelId]) {
  251. modelIdMap[modelId] = [];
  252. }
  253. modelIdMap[modelId].push(item);
  254. });
  255. }
  256. // 将分组后的数据转为二维数组
  257. for (let modelId in modelIdMap) {
  258. groupedData.push(modelIdMap[modelId]);
  259. }
  260. // 打印结果
  261. console.log(groupedData);
  262. assessmentObjectList.value = groupedData;
  263. if (form.assessmentModelList && form.assessmentModelList.length > 0) {
  264. form.assessmentObjectList.map(item => {
  265. // assessmentObjectList.value.push({
  266. // assessmentObjectId: item.assessmentObjectId,
  267. // assessmentObjectName: item.assessmentObjectName
  268. // });
  269. assessmentModelList.value.push({
  270. assessmentModelId: item.assessmentModelId,
  271. assessmentModelName: item.assessmentModelName
  272. });
  273. });
  274. }
  275. // assessmentObjectList.value = Array.from(
  276. // new Map(
  277. // assessmentObjectList.value.map(item => [item.assessmentObjectId, item])
  278. // ).values()
  279. // );
  280. assessmentModelList.value = Array.from(
  281. new Map(
  282. assessmentModelList.value.map(item => [item.assessmentModelId, item])
  283. ).values()
  284. );
  285. if (form.assessmentObjectList) {
  286. form.assessmentObjectList.map(item => {
  287. optionValue.value.push(item.assessmentObjectId);
  288. });
  289. }
  290. if (form.assessmentType === 1) {
  291. postListTreeWithUserApi();
  292. } else if (form.assessmentType === 0) {
  293. getPersonList();
  294. } else if (form.assessmentType === 2) {
  295. const yiliao = await postPageGroup({
  296. pageNumber: 1,
  297. pageSize: 1000
  298. });
  299. treeDeptList.value = yiliao.data.records;
  300. }
  301. } else {
  302. ElMessage.error(msg);
  303. }
  304. };
  305. getAssessmentDetailsApi();
  306. // 修改
  307. const updateAssessmentApi = async () => {
  308. const { code, msg } = await updateAssessment({ id: params.id, ...form });
  309. if (code === 200) {
  310. btn.value = true;
  311. ElMessage.success("修改成功");
  312. } else {
  313. ElMessage.error(msg);
  314. }
  315. };
  316. onMounted(() => {
  317. console.log("onMountedsdada", $props.id);
  318. });
  319. </script>
  320. <template>
  321. <div class="w-[500px] m-auto">
  322. <el-form
  323. :model="form"
  324. label-width="auto"
  325. style="max-width: 600px"
  326. :rules="rules"
  327. label-position="top"
  328. >
  329. <el-form-item label="考核名称" prop="name">
  330. <el-input v-model="form.name" :disabled="btn" placeholder="请输入" />
  331. </el-form-item>
  332. <el-form-item label="考核周期">
  333. <el-radio-group
  334. v-model="form.cycle"
  335. disabled
  336. @change="handleRegionChange"
  337. >
  338. <el-radio value="月度" size="large">月度</el-radio>
  339. <el-radio value="季度" size="large">季度</el-radio>
  340. <el-radio value="半年" size="large">半年</el-radio>
  341. <el-radio value="年度" size="large">年度</el-radio>
  342. <el-radio value="日期" size="large">日期</el-radio>
  343. </el-radio-group>
  344. <el-date-picker
  345. v-if="
  346. timeType === '月度' || timeType === '日期' || timeType === '年度'
  347. "
  348. v-model="form.cycleValue"
  349. disabled
  350. :type="pickerType"
  351. :format="format"
  352. placeholder="请选择"
  353. />
  354. <el-dropdown
  355. v-else-if="timeType === '季度' || timeType === '半年'"
  356. trigger="click"
  357. >
  358. <span class="el-dropdown-link navbar-bg-hover select-none">
  359. <el-input
  360. v-model="form.cycleValue"
  361. style="width: 240px"
  362. placeholder="请选择"
  363. :prefix-icon="Calendar"
  364. disabled
  365. />
  366. </span>
  367. <template #dropdown>
  368. <el-dropdown-menu class="setting" style="width: 300px">
  369. <div class="flex justify-between align-center text-base mt-4">
  370. <div
  371. class="cursor-pointer ml-4 text-xs pt-2"
  372. @click="decreaseYear"
  373. >
  374. <el-icon>
  375. <DArrowLeft />
  376. </el-icon>
  377. </div>
  378. <div>{{ yearTime }}</div>
  379. <div
  380. class="cursor-pointer mr-4 text-xs pt-2"
  381. @click="increaseYear"
  382. >
  383. <el-icon>
  384. <DArrowRight />
  385. </el-icon>
  386. </div>
  387. </div>
  388. <div
  389. v-if="quarterValue"
  390. class="flex justify-center align-center mt-5 mb-5"
  391. >
  392. <el-dropdown-item @click="monthOne('一季度')">
  393. 一季度
  394. </el-dropdown-item>
  395. <el-dropdown-item @click="monthOne('二季度')">
  396. 二季度
  397. </el-dropdown-item>
  398. <el-dropdown-item @click="monthOne('三季度')">
  399. 三季度
  400. </el-dropdown-item>
  401. <el-dropdown-item @click="monthOne('四季度')">
  402. 四季度
  403. </el-dropdown-item>
  404. </div>
  405. <div v-else class="flex justify-around align-center mt-5 mb-5">
  406. <el-dropdown-item @click="monthOne('上半年')">
  407. 上半年
  408. </el-dropdown-item>
  409. <el-dropdown-item @click="monthOne('下半年')">
  410. 下半年
  411. </el-dropdown-item>
  412. </div>
  413. </el-dropdown-menu>
  414. </template>
  415. </el-dropdown>
  416. </el-form-item>
  417. <el-form-item label="是否支持得分换算" prop="scoreConversion">
  418. <el-radio-group v-model="form.scoreConversion" disabled>
  419. <el-radio :label="1">是</el-radio>
  420. <el-radio :label="0">否</el-radio>
  421. </el-radio-group>
  422. </el-form-item>
  423. <el-form-item label="被考核类型">
  424. <el-select
  425. v-model="form.assessmentType"
  426. placeholder="请选择被考核类型"
  427. disabled
  428. >
  429. <el-option label="员工" :value="0" />
  430. <el-option label="部门" :value="1" />
  431. <el-option label="医疗" :value="2" />
  432. <el-option label="部门负责人" :value="3" />
  433. </el-select>
  434. </el-form-item>
  435. <el-form-item
  436. label="被考核对象与模板设置"
  437. prop="form1"
  438. label-position="top"
  439. >
  440. <div class="w-full flex">
  441. <div class="w-1/3">
  442. <el-form
  443. label-position="top"
  444. :model="form.assessmentObjectList"
  445. :rules="formLeftRules"
  446. >
  447. <el-form-item label="被考核对象" prop="left">
  448. <div class="w-full mt-1 flex flex-wrap">
  449. <!-- 人员,负责人 -->
  450. <!-- <el-select
  451. v-if="form.assessmentType == 0 || form.assessmentType == 3"
  452. v-model="optionValue"
  453. multiple
  454. disabled
  455. >
  456. <el-option
  457. v-for="(it, id) in form.assessmentObjectList"
  458. :key="id"
  459. :label="it.assessmentObjectName"
  460. :value="it.assessmentObjectId"
  461. />
  462. </el-select> -->
  463. {{
  464. console.log("assessmentObjectList", assessmentObjectList)
  465. }}
  466. <div
  467. v-for="(item, index) in assessmentObjectList"
  468. :key="index"
  469. class="text-gray-400 w-full flex flex-wrap object mt-1"
  470. >
  471. <div v-for="(it, id) in item" :key="id" class="h-6">
  472. {{ it.assessmentObjectName }},
  473. </div>
  474. </div>
  475. </div>
  476. </el-form-item>
  477. </el-form>
  478. </div>
  479. <div class="w-1/2 ml-7">
  480. <el-form
  481. label-position="top"
  482. :model="form.assessmentObjectList"
  483. :rules="formRightRules"
  484. >
  485. <el-form-item label="考核模板" prop="right">
  486. <div class="w-full flex flex-wrap mt-1 aaa">
  487. <!-- <el-select
  488. v-model="item.assessmentModelId"
  489. disabled
  490. placeholder="请选择"
  491. filterable
  492. style="width: 180px"
  493. >
  494. <el-option
  495. v-for="itemTmp in form.assessmentObjectList"
  496. :key="itemTmp.assessmentModelId"
  497. :label="itemTmp.assessmentModelName"
  498. :value="itemTmp.assessmentModelId"
  499. />
  500. </el-select> -->
  501. <div
  502. v-for="(item, index) in assessmentModelList"
  503. :key="index"
  504. class="text-gray-400"
  505. >
  506. <div class="mt-2">{{ item.assessmentModelName }}</div>
  507. </div>
  508. </div>
  509. </el-form-item>
  510. </el-form>
  511. </div>
  512. </div>
  513. </el-form-item>
  514. </el-form>
  515. <el-button
  516. v-if="btn"
  517. class="float-right mt-4"
  518. type="warning"
  519. :disabled="bistatus == 0"
  520. @click="btnShow"
  521. >编辑</el-button
  522. >
  523. <div v-else class="float-right mt-4">
  524. <el-button @click="handleClose">取消</el-button>
  525. <el-button type="primary" @click="saveDepartment"> 确认 </el-button>
  526. </div>
  527. </div>
  528. </template>
  529. <style scoped>
  530. .aaa {
  531. font-size: 12px;
  532. div {
  533. overflow: hidden;
  534. /* 隐藏超出的部分 */
  535. text-overflow: ellipsis;
  536. /* 显示省略号 */
  537. white-space: nowrap;
  538. /* 防止文本换行 */
  539. div {
  540. font-weight: 500;
  541. border: 1px solid gray;
  542. border-radius: 5px;
  543. }
  544. }
  545. }
  546. .object {
  547. font-size: 12px;
  548. font-weight: 500;
  549. border: 1px solid gray;
  550. border-radius: 5px;
  551. }
  552. </style>