items.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <el-dialog v-model="visible" :title="`${form.projectName}-验收清单`" width="870" :close-on-click-modal="false" @closed="$emit('closed')">
  3. <el-form ref="formRef" :model="form" label-width="110px">
  4. <el-form-item required>
  5. <template #label>
  6. <el-tooltip placement="top">
  7. <i class="vxe-icon-question-circle-fill"></i>
  8. <template #content>
  9. &nbsp;&nbsp;&nbsp;&nbsp;A级智慧化工地:18项基础项<br />
  10. &nbsp;&nbsp;AA级智慧化工地:18项基础项、不少于10项推广项(包含必选项),2项非必选推广项可替代1项必选推广项<br />
  11. AAA级智慧化工地:18项基础项、不少于20项推广项(包含必选项)、2项提升项(包含必选项),2项非必选提升项可替代1项必选提升项
  12. </template>
  13. </el-tooltip>申报等级
  14. </template>
  15. <el-radio-group v-model="form.starLevel" @change="changeLevel">
  16. <el-radio label="A"></el-radio>
  17. <el-radio label="AA"></el-radio>
  18. <el-radio label="AAA"></el-radio>
  19. </el-radio-group>
  20. </el-form-item>
  21. <div class="items-statistic">{{ XEUtils.template(statisticTemp, statisticData) }}</div>
  22. <el-form-item label-width="0">
  23. <el-radio-group v-model="itemsLevel" @change="refreshTable">
  24. <el-radio-button label="基础项" />
  25. <el-radio-button v-if="form.starLevel == 'AA' || form.starLevel == 'AAA'" label="推广项" />
  26. <el-radio-button v-if="form.starLevel == 'AAA'" label="提升项" />
  27. </el-radio-group>
  28. </el-form-item>
  29. <scTable ref="xGridTable" :maxHeight="1048" :columns="columns" :options="options">
  30. <template #checked_content="{ row }">
  31. <el-checkbox v-model="row.checked"></el-checkbox>
  32. </template>
  33. <template #checked_replace="{ row }">
  34. <el-checkbox v-if="row.acceptItemType.includes('必选项')" v-model="row.replaceIds" true-value="1" :false-value="0"></el-checkbox>&nbsp;&nbsp;
  35. <!-- <div v-if="row.acceptItemType.includes('必选项')" class="replace-content">
  36. <el-select v-model="row.replaceIds" multiple collapse-tags collapse-tags-tooltip placeholder="选择替换推广项">
  37. <el-option v-for="item in XEUtils.filter(acceptItems, acc => acc.acceptItemType == '推广项')" :key="item.id" :label="item.acceptItem" :value="item.id"></el-option>
  38. </el-select>
  39. </div> -->
  40. </template>
  41. <template #date_picker_begin="{ row }">
  42. <el-date-picker v-model="row.beginTime" :disabled-date="date => disabledDate(date, row, 'beginTime')" value-format="YYYY-MM-DD 00:00:00" placeholder="选择开始时间"></el-date-picker>
  43. </template>
  44. <template #date_picker_end="{ row }">
  45. <el-date-picker v-model="row.endTime" :disabled-date="date => disabledDate(date, row, 'endTime')" value-format="YYYY-MM-DD 23:59:59" placeholder="选择结束时间"></el-date-picker>
  46. </template>
  47. </scTable>
  48. </el-form>
  49. <template #footer>
  50. <el-button :loading="isSaving" type="primary" auto-insert-space @click="submit">保存</el-button>
  51. <el-button auto-insert-space @click="visible = false">取消</el-button>
  52. </template>
  53. </el-dialog>
  54. </template>
  55. <script setup>
  56. import moment from "moment";
  57. import XEUtils from "xe-utils";
  58. import API from "@/api";
  59. import { categoryDic, statisticTemp } from "@/views/basic/acceptItems/main";
  60. const $emit = defineEmits(["success", "closed"]);
  61. const visible = ref(false);
  62. const isSaving = ref(false);
  63. const form = ref({
  64. projectId: null,
  65. projectName: null,
  66. starLevel: "A"
  67. });
  68. const itemsLevel = ref("基础项");
  69. const acceptItems = ref([]);
  70. const filterItem = value => XEUtils.filter(acceptItems.value, item => item.acceptItemType.includes(value))
  71. const statisticData = reactive({
  72. b_length: computed(() => filterItem("基础项").length),
  73. p_length: computed(() => filterItem("推广项").length),
  74. i_length: computed(() => filterItem("提升项").length),
  75. b_select: computed(() => XEUtils.filter(filterItem("基础项"), item => item.checked).length),
  76. p_select: computed(() => XEUtils.filter(filterItem("推广项"), item => item.checked).length),
  77. i_select: computed(() => XEUtils.filter(filterItem("提升项"), item => item.checked).length),
  78. p_required: computed(() => XEUtils.filter(filterItem("推广项"), item => item.acceptItemType.includes("必选项") && item.checked).length),
  79. i_required: computed(() => XEUtils.filter(filterItem("提升项"), item => item.acceptItemType.includes("必选项") && item.checked).length)
  80. })
  81. const options = reactive({
  82. align: "center",
  83. formConfig: { enabled: false },
  84. pagerConfig: { enabled: false }
  85. })
  86. const columns = reactive([
  87. { type: "seq", width: 60 },
  88. { field: "itemCategoryName", title: "验收项类别", minWidth: 120, formatter: ({ cellValue, row }) => cellValue || XEUtils.get(categoryDic, row.itemCategory) },
  89. { field: "acceptItem", title: "验收项名称", minWidth: 160 },
  90. { field: "acceptItemType", title: "验收项级别", minWidth: 160 },
  91. { field: "checked", title: "选择", width: 80, slots: { default: "checked_content" } },
  92. { visible: computed(() => itemsLevel.value == "推广项" || itemsLevel.value == "提升项"), field: "replaceIds", title: "验收项替换", minWidth: 100, slots: { default: "checked_replace" } },
  93. { field: "beginTime", title: "数据开始时间", width: 160, slots: { default: "date_picker_begin" } },
  94. { field: "endTime", title: "数据结束时间", width: 160, slots: { default: "date_picker_end" } },
  95. ])
  96. const disabledDate = (date, row, field) => {
  97. if (field == "beginTime" && XEUtils.get(row, "endTime")) return moment(date).diff(XEUtils.get(row, "endTime")) > 0
  98. if (field == "endTime" && XEUtils.get(row, "beginTime")) return moment(date).diff(XEUtils.get(row, "beginTime")) < 0
  99. return false
  100. }
  101. const open = () => visible.value = true;
  102. const setData = ({ fpiId, projectName }) => {
  103. open();
  104. form.value.projectId = fpiId;
  105. form.value.projectName = projectName;
  106. getAcceptItems(fpiId);
  107. }
  108. const xGridTable = ref();
  109. const refreshTable = () => {
  110. xGridTable.value.reloadColumn(columns);
  111. xGridTable.value.reloadData(filterItem(itemsLevel.value));
  112. xGridTable.value.toggleTableLoading(false);
  113. }
  114. const getAcceptItems = (projectId) => {
  115. nextTick(() => xGridTable.value?.toggleTableLoading(true));
  116. Promise.all([
  117. API.system.acceptItems.all({ orderBy: "itemCategory_asc,createTime_asc" }),
  118. API.system.project.bindItem.get({ projectId })
  119. ]).then(([itemsRes, infoRes]) => {
  120. let count = 0;
  121. XEUtils.arrayEach(itemsRes, item => {
  122. if (!XEUtils.get(infoRes, "data", []).length) {
  123. if (item.acceptItemType == "基础项" && count < 18) {
  124. item.checked = true;
  125. count++;
  126. }
  127. } else {
  128. form.value.starLevel = infoRes.starLevel;
  129. const selectInfo = XEUtils.find(XEUtils.get(infoRes, "data", []), info => info.itemId == item.id);
  130. selectInfo && XEUtils.merge(item, { checked: true, ...XEUtils.omit(XEUtils.pick(selectInfo, "beginTime", "endTime", "replaceIds"), val => XEUtils.isEmpty(val)) })
  131. }
  132. });
  133. acceptItems.value = itemsRes;
  134. refreshTable();
  135. }).catch(() => {
  136. nextTick(() => xGridTable.value?.toggleTableLoading(false));
  137. acceptItems.value = [];
  138. });
  139. }
  140. const changeLevel = e => {
  141. if (e == "A" || e == "AA" && itemsLevel.value == "提升项") {
  142. itemsLevel.value = "基础项";
  143. refreshTable();
  144. }
  145. };
  146. const formRef = ref();
  147. const submit = () => {
  148. if (statisticData.b_select < 18) return ElMessage.warning("基础项不足18项");
  149. if (form.value.starLevel == "AA" && statisticData.p_select < 10) return ElMessage.warning("推广项不足10项");
  150. if (form.value.starLevel == "AAA" && statisticData.p_select < 20) return ElMessage.warning("推广项不足20项");
  151. if (form.value.starLevel == "AAA" && statisticData.i_select < 2) return ElMessage.warning("提升项不足20项");
  152. const query = XEUtils.omit(form.value, "projectName");
  153. XEUtils.set(query, "data", XEUtils.map(acceptItems.value, item => ({ itemId: item.id, ...XEUtils.pick(item, "beginTime", "endTime", "replaceIds") })));
  154. isSaving.value = true;
  155. API.system.project.bindItem.add(query).then(res => {
  156. isSaving.value = false;
  157. ElMessage.success("操作成功");
  158. visible.value = false;
  159. }).catch(() => isSaving.value = false);
  160. }
  161. defineExpose({
  162. open,
  163. setData
  164. })
  165. </script>
  166. <style lang="scss" scoped>
  167. .el-form {padding-right: var(--el-message-close-size, 16px);}
  168. .el-form .el-main {padding: 0;}
  169. .el-form-item :deep(.el-form-item__label) {align-items: center;}
  170. .vxe-icon-question-circle-fill {cursor: help;margin-right: .25em;font-size: var(--vxe-ui-font-size-mini, 12px);}
  171. .items-statistic {margin-bottom: 18px;padding-left: 8px;font-size: 15px;color: var(--el-color-primary);}
  172. </style>