create-new-excel.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. <template>
  2. <hc-dialog
  3. v-model="isShow"
  4. is-footer-center
  5. :title="modelTitle"
  6. @close="dialogClose"
  7. @save="saveFormAndElementHandle"
  8. widths="56rem"
  9. :loading="submitLoading"
  10. >
  11. <el-form
  12. ref="formRef"
  13. :model="formModel"
  14. :rules="formRules"
  15. label-position="top"
  16. label-width="auto"
  17. v-if="!tableId"
  18. >
  19. <el-row :gutter="60">
  20. <el-col :span="12">
  21. <el-form-item label="表名" prop="tableName">
  22. <el-input v-model="formModel.tableName" />
  23. </el-form-item>
  24. </el-col>
  25. <el-col :span="12">
  26. <el-form-item label="填报率">
  27. <el-input v-model="formModel.fillRate" />
  28. </el-form-item>
  29. </el-col>
  30. </el-row>
  31. <el-row :gutter="60">
  32. <el-col :span="12">
  33. <el-form-item label="表类型:" prop="tableType">
  34. <el-select
  35. v-model="formModel.tableType"
  36. placeholder="选择表类型"
  37. filterable
  38. block
  39. >
  40. <el-option
  41. v-for="item in tableTypelist"
  42. :key="item.value"
  43. :label="item.label"
  44. :value="item.value"
  45. />
  46. </el-select>
  47. </el-form-item>
  48. </el-col>
  49. <el-col :span="12">
  50. <el-form-item label="所属方:" prop="tableOwner">
  51. <el-select
  52. v-model="formModel.tableOwner"
  53. placeholder="选择所属方"
  54. filterable
  55. block
  56. >
  57. <el-option
  58. v-for="item in ownerTypeList"
  59. :key="item.value"
  60. :label="item.label"
  61. :value="item.value"
  62. />
  63. </el-select>
  64. </el-form-item>
  65. </el-col>
  66. </el-row>
  67. </el-form>
  68. <hc-card-item>
  69. <template #header>
  70. <el-tooltip
  71. :visible="editVisible"
  72. effect="light"
  73. placement="bottom-start"
  74. >
  75. <template #content>
  76. <div class="text-sm text-red">
  77. 1.元素名称不能为空<br />
  78. 2.数据类型不能为空<br />
  79. 3.元素长度不能为空<br />
  80. 4.编辑元素信息请谨慎操作<br />
  81. </div>
  82. </template>
  83. <el-button
  84. type="danger"
  85. @mouseenter="editVisible = true"
  86. @mouseleave="editVisible = false"
  87. >
  88. <HcIcon name="question" />
  89. <span>编辑说明</span>
  90. </el-button>
  91. </el-tooltip>
  92. </template>
  93. <template #extra>
  94. <el-button size="small" type="success" @click="addRowClick"
  95. >新增</el-button
  96. >
  97. <el-button
  98. size="small"
  99. type="primary"
  100. @click="uploadClick"
  101. v-if="!tableId"
  102. >快捷导入</el-button
  103. >
  104. <el-button
  105. size="small"
  106. type="warning"
  107. v-if="!tableId"
  108. @click="downLoadFile"
  109. :loading="downloadLoading"
  110. >下载导入模板</el-button
  111. >
  112. </template>
  113. <hc-search-input
  114. v-model="queryValue"
  115. @search="getEditEleList"
  116. class="w-100 mb-4"
  117. v-if="tableId"
  118. />
  119. <hc-table :column="tableColumn" :datas="editEleList">
  120. <template #eName="{ row }">
  121. <hc-table-input v-model="row.eName" />
  122. </template>
  123. <template #eType="{ row }">
  124. <el-select
  125. v-model="row.eType"
  126. @change="setDefaultLength(row)"
  127. placeholder="请选择"
  128. >
  129. <el-option
  130. v-for="item in dataTypeList"
  131. :key="item.id"
  132. :label="item.label"
  133. :value="item.value"
  134. ></el-option>
  135. </el-select>
  136. </template>
  137. <template #eLength="{ row }">
  138. <hc-table-input v-model="row.eLength" />
  139. </template>
  140. <template #eAllowDeviation="{ row }">
  141. <div class="flex">
  142. <el-select
  143. v-model="row.allow"
  144. :popper-append-to-body="false"
  145. placeholder="请选择"
  146. >
  147. <el-option :key="1" label="-" value="-"></el-option>
  148. <el-option :key="2" label=">" value=">"></el-option>
  149. <el-option :key="3" label="<" value="<"></el-option>
  150. <el-option :key="4" label="≥" value="≥"></el-option>
  151. <el-option :key="5" label="≤" value="≤"></el-option>
  152. <el-option :key="6" label="±" value="±"></el-option>
  153. <el-option
  154. :key="7"
  155. label="【】"
  156. value="【】"
  157. ></el-option>
  158. </el-select>
  159. <hc-table-input v-model="row.deviation" />
  160. </div>
  161. </template>
  162. <template #eInspectionMethod="{ row }">
  163. <hc-table-input v-model="row.eInspectionMethod" />
  164. </template>
  165. <template #dynamicDict="{ row }" v-if="tableId">
  166. <el-select v-model="row.dynamicDict" placeholder="请选择">
  167. <el-option
  168. v-for="item in dynamicDictList"
  169. :key="item.id"
  170. :label="item.label"
  171. :value="item.value"
  172. ></el-option>
  173. </el-select>
  174. </template>
  175. <template #action="{ row, index }">
  176. <el-link
  177. type="danger"
  178. @click="rowDelClick(row, index)"
  179. v-if="row.id"
  180. >删除</el-link
  181. >
  182. <div v-else>
  183. <el-link
  184. v-if="tableId"
  185. type="primary"
  186. @click="addSaveClick(row, index)"
  187. :loading="addSaveLoading"
  188. >保存</el-link
  189. >
  190. <el-link
  191. type="danger"
  192. @click="rowDelClick(row, index)"
  193. :loading="rowDelLoading"
  194. >删除</el-link
  195. >
  196. </div>
  197. </template>
  198. </hc-table>
  199. </hc-card-item>
  200. </hc-dialog>
  201. <!-- 模板导入 -->
  202. <hc-dialog v-model="fileModal" title="模板导入" @save="saveFileImport">
  203. <hc-card-item>
  204. <template #header>
  205. <div class="text-sm text-red">
  206. 提示:必须按照系统要求的模版格式上传,否则系统识别无效
  207. </div>
  208. </template>
  209. <template #extra>
  210. <el-button
  211. size="small"
  212. type="primary"
  213. @click="downLoadFile"
  214. :loading="downloadLoading"
  215. >下载导入模板</el-button
  216. >
  217. <el-button
  218. size="small"
  219. type="primary"
  220. @click="importModalClick"
  221. :loading="uploadsLoading"
  222. >本地上传</el-button
  223. >
  224. </template>
  225. <hc-table :column="fileTableColumn" :datas="fileTableData">
  226. <template #elementAllowDeviation="{ row }">
  227. <div class="flex">
  228. <el-select
  229. v-model="row.allow"
  230. :popper-append-to-body="false"
  231. placeholder="请选择"
  232. >
  233. <el-option :key="1" label="-" value="-"></el-option>
  234. <el-option :key="2" label=">" value=">"></el-option>
  235. <el-option :key="3" label="<" value="<"></el-option>
  236. <el-option :key="4" label="≥" value="≥"></el-option>
  237. <el-option :key="5" label="≤" value="≤"></el-option>
  238. <el-option :key="6" label="±" value="±"></el-option>
  239. <el-option
  240. :key="7"
  241. label="【】"
  242. value="【】"
  243. ></el-option>
  244. </el-select>
  245. <hc-table-input v-model="row.elementAllowDeviation" />
  246. </div>
  247. </template>
  248. </hc-table>
  249. </hc-card-item>
  250. </hc-dialog>
  251. </template>
  252. <script setup>
  253. import { ref, watch } from "vue";
  254. import { getDictionaryData } from "~src/utils/tools";
  255. import mainApi from "~api/wbs/wbsforelement";
  256. import { useAppStore } from "~src/store";
  257. import { HcUploadFileApi, HcDelMsg } from "hc-vue3-ui";
  258. import { formValidate, getArrValue, downloadBlob } from "js-fast-way";
  259. const store = useAppStore();
  260. const userInfo = ref(store.getUserInfo);
  261. const props = defineProps({
  262. ownerTypeList: {
  263. type: Array,
  264. default: () => [],
  265. },
  266. tableTypelist: {
  267. type: Array,
  268. default: () => [],
  269. },
  270. wid: {
  271. type: [String, Number],
  272. default: "",
  273. },
  274. node: {
  275. type: Object,
  276. default: () => {},
  277. },
  278. title: {
  279. type: String,
  280. default: "",
  281. },
  282. tableId: {
  283. type: String,
  284. default: "",
  285. },
  286. initTableName: {
  287. type: String,
  288. default: "",
  289. },
  290. initTableId: {
  291. type: String,
  292. default: "",
  293. },
  294. eKey: {
  295. type: String,
  296. default: "",
  297. },
  298. });
  299. //事件
  300. const emit = defineEmits(["close"]);
  301. //双向绑定
  302. // eslint-disable-next-line no-undef
  303. const isShow = defineModel("modelValue", {
  304. default: false,
  305. });
  306. //监听显示
  307. watch(isShow, (val) => {
  308. if (val) {
  309. getDataTypelist();
  310. getDynamicDictList();
  311. } else {
  312. emit("close");
  313. }
  314. });
  315. const ownerTypeList = ref(props.ownerTypeList);
  316. const tableTypelist = ref(props.tableTypelist);
  317. const wbsId = ref(props.wid);
  318. const node = ref(props.node);
  319. const modelTitle = ref(props.title);
  320. const tableId = ref(props.tableId);
  321. const initTableName = ref(props.initTableName);
  322. const initTableId = ref(props.initTableId);
  323. const eKey = ref(props.eKey);
  324. //监听数据
  325. watch(
  326. () => [
  327. props.ownerTypeList,
  328. props.tableTypelist,
  329. props.wid,
  330. props.node,
  331. props.title,
  332. props.tableId,
  333. props.initTableName,
  334. props.initTableId,
  335. props.eKey,
  336. ],
  337. ([own, table, wbsid, nodeInfo, til, tid, tname, itid, ekey]) => {
  338. ownerTypeList.value = own;
  339. tableTypelist.value = table;
  340. wbsId.value = wbsid;
  341. node.value = nodeInfo;
  342. modelTitle.value = til;
  343. tableId.value = tid;
  344. initTableName.value = tname;
  345. initTableId.value = itid;
  346. eKey.value = ekey;
  347. },
  348. { deep: true }
  349. );
  350. watch(
  351. tableId,
  352. (val) => {
  353. console.log(val, "val11111111");
  354. if (val) {
  355. getEditEleList();
  356. tableColumn.value = [
  357. { key: "eName", name: "元素名称", width: 150 },
  358. { key: "eType", name: "数据类型", width: 120 },
  359. { key: "eLength", name: "长度" },
  360. { key: "eAllowDeviation", name: "允许偏差值", width: 180 },
  361. { key: "eInspectionMethod", name: "检查方法和频率" },
  362. { key: "dynamicDict", name: "动态字典" },
  363. { key: "action", name: "操作", width: 80, align: "center" },
  364. ];
  365. } else {
  366. editEleList.value = [];
  367. tableColumn.value = [
  368. { key: "eName", name: "元素名称", width: 150 },
  369. { key: "eType", name: "数据类型", width: 120 },
  370. { key: "eLength", name: "长度" },
  371. { key: "eAllowDeviation", name: "允许偏差值", width: 180 },
  372. { key: "eInspectionMethod", name: "检查方法和频率" },
  373. { key: "action", name: "操作", width: 80, align: "center" },
  374. ];
  375. }
  376. },
  377. { deep: true }
  378. );
  379. //表单
  380. const formRef = ref(null);
  381. const formRules = {
  382. tableName: {
  383. required: true,
  384. trigger: "blur",
  385. message: "请输入表单名称",
  386. },
  387. tableType: {
  388. required: true,
  389. trigger: "blur",
  390. message: "请选择表单类型",
  391. },
  392. tableOwner: {
  393. required: true,
  394. trigger: "blur",
  395. message: "请选择所属方",
  396. },
  397. wid: {
  398. type: [String, Number],
  399. default: "",
  400. },
  401. };
  402. const formModel = ref({});
  403. const editVisible = ref(false);
  404. const tableColumn = ref([
  405. { key: "eName", name: "元素名称", width: 150 },
  406. { key: "eType", name: "数据类型", width: 120 },
  407. { key: "eLength", name: "长度" },
  408. { key: "eAllowDeviation", name: "允许偏差值", width: 180 },
  409. { key: "eInspectionMethod", name: "检查方法和频率" },
  410. { key: "action", name: "操作", width: 80, align: "center" },
  411. ]);
  412. const editEleList = ref([]);
  413. const queryValue = ref("");
  414. const getEditEleList = async () => {
  415. const { data } = await mainApi.getTableElements({
  416. id: tableId.value,
  417. search: "",
  418. type: 1,
  419. });
  420. editEleList.value = getArrValue(data);
  421. const eleReg = /(-|>|<|≥|≤|±|【】)?([^≥≤±【】]*)/;
  422. editEleList.value.forEach((element) => {
  423. eleReg.exec(element.eAllowDeviation);
  424. element.allow = RegExp.$1 ? RegExp.$1 : "";
  425. element.deviation = RegExp.$2 ? RegExp.$2 : "";
  426. });
  427. };
  428. const dataTypeList = ref([]);
  429. const getDataTypelist = async () => {
  430. if (dataTypeList.value.length > 1) {
  431. return;
  432. }
  433. dataTypeList.value = await getDictionaryData("data_type", false);
  434. };
  435. const dynamicDictList = ref([]); //动态字典列表
  436. const getDynamicDictList = async () => {
  437. if (dynamicDictList.value.length > 1) {
  438. return;
  439. }
  440. dynamicDictList.value = await getDictionaryData("land_field_dict", false);
  441. };
  442. const setDefaultLength = (row) => {
  443. const dataTypeDefaultMap = {
  444. 1: 250, //字符串
  445. 2: 50, //整数
  446. 3: 50, //小数
  447. 4: 50, //日期
  448. 5: 50, //数值
  449. 6: 50, //签名
  450. 7: 100, //文件
  451. };
  452. row.eLength = dataTypeDefaultMap[row.eType];
  453. };
  454. const rowDelLoading = ref(false);
  455. const rowDelClick = async (row, index) => {
  456. if (!row.id) {
  457. editEleList.value.splice(index, 1);
  458. } else {
  459. HcDelMsg(async (resolve) => {
  460. //发起请求
  461. rowDelLoading.value = true;
  462. const { isRes } = await mainApi.removeElement({
  463. ids: row.id,
  464. initTableName: initTableName.value,
  465. eKey: row.ekey,
  466. });
  467. resolve(); //关闭弹窗
  468. if (!isRes) return;
  469. window?.$message?.success("操作成功");
  470. });
  471. }
  472. };
  473. const addRowClick = () => {
  474. editEleList.value.push({});
  475. };
  476. const addSaveLoading = ref(false);
  477. const addSaveClick = async (row) => {
  478. if (!row.eName) {
  479. window.$message.warning("请填写元素名称");
  480. return;
  481. }
  482. if (!row.eType) {
  483. window.$message.warning("请选择数据类型");
  484. return;
  485. }
  486. row.eAllowDeviation =
  487. (row.allow ? row.allow : "") + (row.deviation ? row.deviation : "");
  488. row.fId = initTableId.value;
  489. row.initTableName = initTableName.value;
  490. if (!row.eLength) {
  491. window.$message.warning("请填写长度");
  492. return;
  493. }
  494. addSaveLoading.value = true;
  495. const { error, code, data } = await mainApi.saveElement(row);
  496. addSaveLoading.value = false;
  497. if (!error && code === 200) {
  498. window?.$message?.success("操作成功");
  499. row.id = data.id;
  500. row.ekey = data.ekey;
  501. }
  502. };
  503. const submitLoading = ref(false);
  504. const saveFormAndElementHandle = async () => {
  505. if (!tableId.value) {
  506. const formRes = await formValidate(formRef.value);
  507. if (!formRes) return false;
  508. }
  509. formModel.value.wbsId = wbsId.value;
  510. formModel.value.tenantId = userInfo.value.tenant_id;
  511. formModel.value.nodeType = -1;
  512. formModel.value.type = 2; // '1'节点 '2'表
  513. formModel.value.parentId = node.value.id;
  514. formModel.value.nodeName = node.value.nodeName;
  515. for (let i = 0; i < editEleList.value.length; i++) {
  516. if (tableId.value) {
  517. if (!editEleList.value[i].id) {
  518. window.$message.warning("请先将新增的元素点击保存");
  519. return;
  520. }
  521. }
  522. if (!editEleList.value[i].eName) {
  523. window.$message.warning("请填写第" + (i + 1) + "条元素名称");
  524. return;
  525. }
  526. if (!editEleList.value[i].eType) {
  527. window.$message.warning("请选择第" + (i + 1) + "条数据类型");
  528. return;
  529. }
  530. if (!editEleList.value[i].eLength) {
  531. window.$message.warning("请填写第" + (i + 1) + "条数据长度");
  532. return;
  533. }
  534. }
  535. if (editEleList.value.length > 0) {
  536. editEleList.value.forEach((element) => {
  537. element.eAllowDeviation =
  538. (element.allow ? element.allow : "") +
  539. (element.deviation ? element.deviation : "");
  540. });
  541. submitLoading.value = true;
  542. formModel.value.elementList = editEleList;
  543. if (!tableId.value) {
  544. const { error, code } = await mainApi.saveFormAndElement({
  545. ...formModel.value,
  546. });
  547. submitLoading.value = false;
  548. if (!error && code === 200) {
  549. window?.$message?.success("操作成功");
  550. dialogClose();
  551. }
  552. } else {
  553. const { error, code } = await mainApi.updateBatchElements(
  554. editEleList.value,
  555. initTableName.value
  556. );
  557. submitLoading.value = false;
  558. if (!error && code === 200) {
  559. window?.$message?.success("操作成功");
  560. dialogClose();
  561. }
  562. }
  563. } else {
  564. window.$message.warning("请填写完整元素表信息");
  565. }
  566. };
  567. //关闭弹窗
  568. const dialogClose = () => {
  569. isShow.value = false;
  570. emit("close");
  571. };
  572. const fileModal = ref(false);
  573. const uploadClick = () => {
  574. fileModal.value = true;
  575. fileTableData.value = [];
  576. };
  577. const fileTableColumn = [
  578. { key: "elementName", name: "元素名称" },
  579. { key: "elementType", name: "数据类型" },
  580. { key: "elementLength", name: "长度" },
  581. { key: "elementAllowDeviation", name: "允许偏差值" },
  582. { key: "elementInspectionMethod", name: "检查方法和频率" },
  583. ];
  584. const fileTableData = ref([]);
  585. const downloadLoading = ref(false);
  586. const downLoadFile = async () => {
  587. downloadLoading.value = true;
  588. const { error, disposition, res } = await mainApi.getExportTem();
  589. //处理数据
  590. downloadLoading.value = false;
  591. if (!error) {
  592. if (disposition) {
  593. downloadBlob(res, disposition);
  594. } else {
  595. window.$message?.error("数据异常");
  596. }
  597. }
  598. };
  599. const uploadsLoading = ref(false);
  600. const importModalClick = () => {
  601. HcUploadFileApi({
  602. multiple: false,
  603. url: "/api/blade-manager/wbsFormElement/import-wbsElement",
  604. target: "/api/blade-manager/wbsFormElement/import-wbsElement",
  605. progress: () => {
  606. uploadsLoading.value = true;
  607. },
  608. success: (file, res) => {
  609. fileTableData.value = getArrValue(res.data);
  610. },
  611. error: (file) => {
  612. uploadsLoading.value = false;
  613. window.$message.error(`${file.name} 上传失败`);
  614. },
  615. finish: () => {
  616. uploadsLoading.value = false;
  617. window.$message.success("上传完成");
  618. },
  619. });
  620. };
  621. const saveFileImport = () => {
  622. fileModal.value = false;
  623. fileTableData.value.forEach((ele) => {
  624. editEleList.value.push({
  625. eName: ele.elementName,
  626. eAllowDeviation: ele.elementAllowDeviation,
  627. eName: ele.elementInspectionMethod,
  628. eLength: ele.elementLength,
  629. eType: ele.elementType,
  630. });
  631. });
  632. };
  633. </script>