index.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <script setup lang="ts">
  2. import { ref } from "vue";
  3. import { ElMessage } from "element-plus";
  4. import { execlUpload } from "/@/components/execlUpload";
  5. import { httpBatchimport } from "/@/api/purchase/ticketReturn";
  6. import { useResponseHandle } from "/@/hooks";
  7. import { useCompany } from "/@/hooks/core/useCompany";
  8. import {
  9. initheaders,
  10. columns,
  11. mapProp,
  12. requireHeaders
  13. } from "./columns-config";
  14. const visible = ref(false);
  15. const loading = ref(false);
  16. const tableData = ref([]);
  17. const columnsConfig = columns();
  18. const emit = defineEmits(["onSuccess"]);
  19. const { currentCompany } = useCompany();
  20. const responseHandle = useResponseHandle();
  21. const Uploadsuccess = ({ results, header }) => {
  22. loading.value = true;
  23. if (results.length === 0) {
  24. ElMessage.error("表格无有效数据!");
  25. loading.value = false;
  26. return;
  27. }
  28. let headok = true;
  29. if (header.length !== initheaders.length) {
  30. headok = false;
  31. } else {
  32. initheaders.forEach((si, sii) => {
  33. if (si !== header[sii]) {
  34. headok = false;
  35. }
  36. });
  37. }
  38. if (!headok) {
  39. ElMessage.error("表头与导入模板不匹配!");
  40. loading.value = false;
  41. return;
  42. }
  43. tableData.value = [];
  44. try {
  45. for (const v1 of results) {
  46. const b = Object.values(v1);
  47. let model = {};
  48. b.forEach((si, sii) => {
  49. model["value" + sii] = si + "";
  50. });
  51. tableData.value.push(model);
  52. }
  53. loading.value = false;
  54. } catch (err) {
  55. return err;
  56. }
  57. };
  58. //提交
  59. const handleSubmit = async () => {
  60. if (loading.value) return;
  61. loading.value = true;
  62. const data = [];
  63. const errorStatus = [];
  64. const errorHp = [];
  65. const errorDz = [];
  66. tableData.value.forEach((key, index) => {
  67. const obj: Record<string, string> = {};
  68. for (let i in key) {
  69. const prop = mapProp[i];
  70. const value = key[i];
  71. if (prop === "status") {
  72. const trimValue = value.trim();
  73. if (trimValue !== "通过" && trimValue !== "驳回") {
  74. errorStatus.push(index + 1);
  75. } else {
  76. obj[prop] = trimValue === "通过" ? "4" : "7";
  77. }
  78. } else if (prop === "hpNo") {
  79. if (!value) errorHp.push(index + 1);
  80. obj[prop] = value;
  81. } else if (prop === "payNo") {
  82. if (!value) errorDz.push(index + 1);
  83. obj[prop] = value;
  84. } else {
  85. obj[prop] = value;
  86. }
  87. }
  88. data.push(obj);
  89. });
  90. const buyers = data.map(({ companyNo }) => companyNo);
  91. const setBuyers = [...new Set(buyers)];
  92. if (errorStatus.length > 0) {
  93. ElMessage.error(
  94. `第 ${errorStatus.join(",")} 行审核状态格式不正确,应该为'通过',或'驳回'`
  95. );
  96. loading.value = false;
  97. return;
  98. }
  99. if (errorHp.length > 0) {
  100. ElMessage.error(
  101. `第 ${errorHp.join(",")} 行格式不正确,回票申请编号为必填项`
  102. );
  103. loading.value = false;
  104. return;
  105. }
  106. if (errorDz.length > 0) {
  107. ElMessage.error(`第 ${errorDz.join(",")} 行格式不正确,对账编号为必填项`);
  108. loading.value = false;
  109. return;
  110. }
  111. if (setBuyers.length > 1) {
  112. ElMessage.error("买方公司编码不一致");
  113. loading.value = false;
  114. return;
  115. }
  116. if (setBuyers[0] !== currentCompany.value.companyNo) {
  117. ElMessage.error("买方公司编码与当前选择的公司不一致");
  118. loading.value = false;
  119. return;
  120. }
  121. data.forEach(item => {
  122. delete item["payNo"];
  123. delete item["companyNo"];
  124. });
  125. const { code, message } = await httpBatchimport({
  126. list: data
  127. });
  128. loading.value = false;
  129. responseHandle({
  130. code,
  131. message,
  132. handler: () => {
  133. ElMessage.success("数据导入成功!");
  134. emit("onSuccess");
  135. visible.value = false;
  136. }
  137. });
  138. };
  139. const cancel = () => {
  140. tableData.value = [];
  141. };
  142. defineExpose({
  143. onDisplay: () => ((visible.value = true), (tableData.value = []))
  144. });
  145. </script>
  146. <template>
  147. <el-dialog
  148. v-model="visible"
  149. title="批量导入认证结果"
  150. width="1040px"
  151. top="8vh"
  152. center
  153. >
  154. <execlUpload @on-success="Uploadsuccess" v-if="tableData.length === 0" />
  155. <el-table
  156. :data="tableData"
  157. stripe
  158. border
  159. max-height="500px"
  160. size="small"
  161. style="width: 100%"
  162. >
  163. <el-table-column
  164. v-for="(si, sii) in columnsConfig"
  165. :type="si.type"
  166. :minWidth="si.minWidth"
  167. :fixed="si.fixed"
  168. :key="sii"
  169. :prop="si.prop"
  170. show-overflow-tooltip
  171. >
  172. <template #header>
  173. <span
  174. v-if="
  175. !requireHeaders.includes(mapProp[si.prop]) || si.label === '序号'
  176. "
  177. >{{ si.label }}</span
  178. >
  179. <p v-else>
  180. <span style="color: #f56c6c; font-size: 14px">* </span>
  181. {{ si.label }}
  182. </p>
  183. </template>
  184. </el-table-column>
  185. </el-table>
  186. <div
  187. flex
  188. justify-end
  189. gap-2
  190. v-if="tableData.length !== 0"
  191. style="padding: 10px 0 0 0"
  192. >
  193. <el-button size="small" @click="cancel">取消</el-button>
  194. <el-button
  195. size="small"
  196. type="primary"
  197. :loading="loading"
  198. @click="handleSubmit"
  199. >保存</el-button
  200. >
  201. </div>
  202. </el-dialog>
  203. </template>
  204. <style lang="scss" scoped>
  205. :deep(.el-upload-list__item) {
  206. display: none !important;
  207. }
  208. </style>