Переглянути джерело

Merge branch 'sit' into dev

xiaodai2017 2 роки тому
батько
коміт
687965b0ac

+ 3 - 0
src/components/execlUpload/index.ts

@@ -0,0 +1,3 @@
+import execlUpload from "./src/execl-upload.vue";
+
+export { execlUpload };

+ 122 - 0
src/components/execlUpload/src/execl-upload.vue

@@ -0,0 +1,122 @@
+<script setup lang="ts">
+import { ref, reactive } from "vue";
+import {
+  ElMessage,
+  ElUpload,
+  UploadFile,
+  UploadProps,
+  ElLoading
+} from "element-plus";
+import { read, utils } from "xlsx";
+
+const uploadRef = ref<InstanceType<typeof ElUpload>>(null);
+const execlFile = ref<UploadFile | null>(null);
+const emit = defineEmits(["onSuccess"]);
+
+//上传文件改变
+const handleChange: UploadProps["onChange"] = uploadFile => {
+  const rawFile = uploadFile.raw;
+  if (!rawFile) return;
+  upload(rawFile);
+};
+
+const upload = rawFile => {
+  if (beforeUpload(rawFile)) {
+    readerData(rawFile);
+  }
+};
+const readerData = async uploadFile => {
+  const loading = ElLoading.service({
+    lock: true,
+    text: "Loading",
+    background: "rgba(0, 0, 0, 0.7)"
+  });
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onload = e => {
+      const data = e.target.result;
+      const workbook = read(data, { type: "array" });
+      const firstSheetName = workbook.SheetNames[0];
+      const worksheet = workbook.Sheets[firstSheetName];
+      const header = getHeaderRow(worksheet);
+      const results = utils.sheet_to_json(worksheet, { defval: "" });
+      emit("onSuccess", { header, results });
+      loading.close();
+      resolve({ isok: true });
+    };
+    reader.readAsArrayBuffer(uploadFile);
+  });
+};
+
+const getHeaderRow = sheet => {
+  const headers = [];
+  const range = utils.decode_range(sheet["!ref"]);
+  let C;
+  const R = range.s.r;
+  /* 从第一行开始 */
+  for (C = range.s.c; C <= range.e.c; ++C) {
+    /* 遍历范围中的每一列 */
+    const cell = sheet[utils.encode_cell({ c: C, r: R })];
+    /* 查找第一行中的单元格 */
+    let hdr = "UNKNOWN " + C; // <--替换为所需的默认值
+    if (cell && cell.t) hdr = utils.format_cell(cell);
+    headers.push(hdr);
+  }
+  return headers;
+};
+
+const beforeUpload: UploadProps["beforeUpload"] = async uploadFile => {
+  const isLt1M = uploadFile.size / 1024 < 500;
+  if (isLt1M) {
+    return true;
+  }
+  ElMessage.warning("请不要上传大于500KB的文件");
+  return false;
+};
+//删除穿文件
+const handleRemove: UploadProps["onRemove"] = () => (execlFile.value = null);
+
+defineExpose({
+  onDisplay: () => (execlFile.value = null)
+});
+</script>
+
+<template>
+  <el-upload
+    ref="uploadRef"
+    action="#"
+    accept=".xls,.xlsx"
+    drag
+    :auto-upload="false"
+    @change="handleChange"
+    @remove="handleRemove"
+    @before-upload="beforeUpload"
+    multiple
+  >
+    <!-- class="execl-uploader" -->
+    <div class="el-upload__text" v-if="!execlFile">点击此处,上传文件</div>
+  </el-upload>
+</template>
+
+<style lang="scss" scoped>
+.execl-uploader {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+
+  &:hover {
+    border-color: var(--el-color-primary);
+  }
+
+  .el-upload__text {
+    line-height: 200px;
+    font-size: 22px;
+  }
+}
+</style>

+ 6 - 1
src/utils/validate.ts

@@ -258,6 +258,10 @@ const isCreditCode = (s: string) => {
   return reg.test(s);
 };
 
+const isExcel = (s: string) => {
+  return /\.(xlsx|xls|csv)$/.test(s);
+};
+
 export {
   isExternal,
   validUsername,
@@ -289,5 +293,6 @@ export {
   isEmoticon,
   JudgeEnvironment,
   timestampToTime,
-  isCreditCode
+  isCreditCode,
+  isExcel
 };

+ 33 - 0
src/views/InvoiceSales/capitalClaim/components/execl-files-upload/columns-config.ts

@@ -0,0 +1,33 @@
+const initheaders = [
+  "收款方公司编号",
+  "收款方公司名称",
+  "收款方账户",
+  "交易时间",
+  "收入金额",
+  "账号余额",
+  "交易行名",
+  "对方省市",
+  "对方账号",
+  "对方户名",
+  "交易用途"
+];
+const columns = () => {
+  const list: any[] = [
+    {
+      type: "index",
+      width: "50",
+      fixed: "left",
+      label: "序号"
+    }
+  ];
+  initheaders.forEach((si, sii) => {
+    list.push({
+      prop: "value" + sii,
+      label: si,
+      minWidth: sii === 0 || sii === 1 ? "120px" : "90px"
+    });
+  });
+  return list;
+};
+
+export { initheaders, columns };

+ 172 - 0
src/views/InvoiceSales/capitalClaim/components/execl-files-upload/index.vue

@@ -0,0 +1,172 @@
+<script setup lang="ts">
+execlUpload;
+import { ref, reactive } from "vue";
+import { httpUpload } from "/@/api/InvoiceSales/capitalClaim";
+import { initheaders, columns } from "./columns-config";
+import { ElMessage, ElNotification } from "element-plus";
+import { responseHandle } from "/@/utils/responseHandle";
+import { useNav } from "/@/layout/hooks/nav";
+import { execlUpload } from "/@/components/execlUpload";
+const visible = ref(false);
+const loading = ref(false);
+const tableData = ref([]);
+const columnsConfig = columns();
+const { logout } = useNav();
+const emit = defineEmits(["onSuccess"]);
+
+const handleClose = () => {
+  // execlFile.value = null;
+  // uploadRef.value.clearFiles();
+};
+const Uploadsuccess = ({ results, header }) => {
+  loading.value = true;
+  console.log(results);
+  console.log(header);
+  if (results.length === 0) {
+    ElMessage.error("表格无有效数据!");
+    loading.value = false;
+    return;
+  }
+  let headok = true;
+  if (header.length !== initheaders.length) {
+    headok = false;
+  } else {
+    initheaders.forEach((si, sii) => {
+      if (si !== header[sii]) {
+        headok = false;
+      }
+    });
+  }
+  if (!headok) {
+    ElMessage.error("表头与导入模板不匹配!");
+    loading.value = false;
+    return;
+  }
+  tableData.value = [];
+
+  try {
+    results.forEach(v1 => {
+      const b = Object.values(v1);
+      let model = {};
+      b.forEach((si, sii) => {
+        model["value" + sii] = si + "";
+      });
+      tableData.value.push(model);
+    });
+    loading.value = false;
+  } catch (e) {
+    ElMessage.error("导入数据拼接有误!");
+    loading.value = false;
+  }
+};
+//提交
+const handleSubmit = async () => {
+  if (loading.value) return;
+  loading.value = true;
+  let isok = true,
+    isnum = true,
+    data = [];
+  tableData.value.forEach(key => {
+    let arr = [];
+    for (let i in key) {
+      if (!(i === "value1" || i === "value7" || i === "value10")) {
+        if (key[i] === "") {
+          isok = false;
+        }
+        if (i === "value4") {
+          let num = key[i] * 1;
+          console.log(num);
+          if (isNaN(num) || num < 0) {
+            isnum = false;
+          }
+        }
+      }
+      if (i !== "value1") {
+        arr.push(key[i] + "");
+      }
+    }
+    data.push(arr);
+  });
+  if (!isok) {
+    ElMessage.error("导入数据拼接有误!");
+    ElNotification({
+      title: "必填字段缺失!",
+      message: "除(收款方公司名称/对方省市/交易用途)外,都为必填项!",
+      type: "error"
+    });
+    loading.value = false;
+    return;
+  }
+  if (!isnum) {
+    ElMessage.error("收入金额只能为正数!");
+    loading.value = false;
+    return;
+  }
+
+  const { code, message } = await httpUpload({ data });
+  responseHandle({
+    code,
+    message,
+    logout,
+    handler: () => {
+      loading.value = false;
+      ElMessage.success("数据导入成功!");
+      emit("onSuccess");
+      visible.value = false;
+    }
+  });
+};
+const cancel = () => {
+  tableData.value = [];
+};
+defineExpose({
+  onDisplay: () => ((visible.value = true), (tableData.value = []))
+});
+</script>
+
+<template>
+  <el-dialog
+    v-model="visible"
+    title="导入表格数据"
+    width="1040px"
+    top="8vh"
+    center
+    @close="handleClose"
+  >
+    <execlUpload @on-success="Uploadsuccess" v-if="tableData.length === 0" />
+
+    <el-table
+      :data="tableData"
+      stripe
+      border
+      max-height="500px"
+      size="small"
+      style="width: 100%"
+    >
+      <el-table-column
+        v-for="(si, sii) in columnsConfig"
+        v-bind="si"
+        :key="sii"
+        show-overflow-tooltip
+      />
+    </el-table>
+    <div
+      flex
+      justify-end
+      gap-2
+      v-if="tableData.length !== 0"
+      style="padding: 10px 0 0 0"
+    >
+      <el-button size="small" @click="cancel">取消</el-button>
+      <el-button
+        size="small"
+        type="primary"
+        :loading="loading"
+        @click="handleSubmit"
+        >保存</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<style lang="scss" scoped></style>

+ 0 - 103
src/views/InvoiceSales/capitalClaim/components/execl-upload.vue

@@ -1,103 +0,0 @@
-<script setup lang="ts">
-import { ref } from "vue";
-import { ElMessage, ElUpload, UploadFile, UploadProps } from "element-plus";
-import { httpUpload } from "/@/api/InvoiceSales/capitalClaim";
-import { useResponseHandle } from "/@/hooks";
-import { getToken } from "/@/utils/auth";
-
-const visible = ref(false);
-const loading = ref(false);
-const uploadRef = ref<InstanceType<typeof ElUpload>>(null);
-const execlFile = ref<UploadFile | null>(null);
-const responseHandle = useResponseHandle();
-
-//上传成功关闭dialog
-const handleUploadSccess = async () => (visible.value = false);
-
-//上传文件改变
-const handleChange: UploadProps["onChange"] = uploadFile =>
-  (execlFile.value = uploadFile);
-
-//删除穿文件
-const handleRemove: UploadProps["onRemove"] = () => (execlFile.value = null);
-
-//上传方法
-const handleRequeset: UploadProps["httpRequest"] = async ({ file }) => {
-  const formData = new FormData();
-  const token = getToken();
-  formData.append("excel", file);
-  formData.append("token", token);
-  const { message, code } = await httpUpload(formData);
-
-  responseHandle({
-    message,
-    code,
-    handler: () => {
-      ElMessage.success("导入文件成功");
-      handleUploadSccess();
-    }
-  });
-};
-
-const handleClose = () => {
-  execlFile.value = null;
-  uploadRef.value.clearFiles();
-};
-
-//提交
-const handleSubmit = () => {
-  if (!execlFile.value) return ElMessage.error("请选择上传文件");
-  uploadRef.value.submit();
-};
-
-defineExpose({
-  onDisplay: () => (visible.value = true)
-});
-</script>
-
-<template>
-  <el-dialog v-model="visible" title="导入表格数据" center @close="handleClose">
-    <el-upload
-      ref="uploadRef"
-      action="#"
-      class="execl-uploader"
-      accept=".xls,.xlsx"
-      :auto-upload="false"
-      :http-request="handleRequeset"
-      @change="handleChange"
-      @remove="handleRemove"
-    >
-      <div class="el-upload__text" v-if="!execlFile">点击此处,上传文件</div>
-    </el-upload>
-
-    <div flex justify-end mt-2 gap-2>
-      <el-button type="primary" :loading="loading" @click="handleSubmit"
-        >保存</el-button
-      >
-      <el-button>取消</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<style lang="scss" scoped>
-.execl-uploader {
-  border: 1px dashed var(--el-border-color);
-  border-radius: 6px;
-  cursor: pointer;
-  position: relative;
-  overflow: hidden;
-  transition: var(--el-transition-duration-fast);
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-
-  &:hover {
-    border-color: var(--el-color-primary);
-  }
-
-  .el-upload__text {
-    line-height: 200px;
-    font-size: 22px;
-  }
-}
-</style>

+ 2 - 2
src/views/InvoiceSales/capitalClaim/index.vue

@@ -5,7 +5,7 @@ import { useRouter } from "vue-router";
 import { PageSearch, usePageSearch } from "/@/components/PageSearch";
 import { PageContent } from "/@/components/PageContent";
 import PagePower from "/@/components/PagePower/PagePower.vue";
-import ExeclUpload from "./components/execl-upload.vue";
+import ExeclUpload from "./components/execl-files-upload/index.vue";
 import searchFormConfig from "./config/search.config";
 import contentConfig from "./config/content.config";
 import { template } from "./config/xls-template";
@@ -199,7 +199,7 @@ const { permission, contentConfigRef } = usePermission({
       </div>
     </PagePower>
 
-    <ExeclUpload ref="execlUploadRef" />
+    <ExeclUpload ref="execlUploadRef" @onSuccess="handleResetClick" />
   </div>
 </template>