98lxh il y a 6 mois
Parent
commit
e56935badc

Fichier diff supprimé car celui-ci est trop grand
+ 415 - 294
pnpm-lock.yaml


+ 59 - 0
src/views/InvoiceSales/invoiceApply/components/excel-files-upload-relation/columns-config.ts

@@ -0,0 +1,59 @@
+const initheaders = [
+  "发票明细ID",
+  "订单编号",
+  "订单主编号",
+  "商品名称",
+  "开票商品名称",
+  "商品类目编号",
+  "税率",
+  "本次开票金额",
+  "本次开票数量"
+];
+
+export const mapProp = {
+  value0: "itemId",
+  value1: "code",
+  value2: "code_2",
+  value3: "goodName",
+  value4: "openGoodName",
+  value5: "cat_code",
+  value6: "tax",
+  value7: "total_amount",
+  value8: "num",
+};
+
+
+export const mapWidth = {
+  value0: "100px",
+  value1: "160px",
+  value2: "160px",
+  value3: "160px",
+  value4: "160px",
+  value5: "120px",
+  value6: "140px",
+  value7: "140px",
+  value8: "220px",
+  value9: "140px"
+};
+
+
+//
+
+export const requireHeaders = ["itemId", "code", "num", "total_amount", "good_price" ,"companyNo"];
+
+const columns = () => {
+  const list: any[] = [{ type: "index", width: "50", fixed: "left", label: "序号" }];
+
+  initheaders.forEach((si, sii) => {
+    list.push({
+      minWidth: mapWidth["value" + sii],
+      prop: "value" + sii, 
+      label: si
+    });
+  });
+
+  console.log(list);
+  return list;
+};
+
+export { initheaders, columns };

+ 213 - 0
src/views/InvoiceSales/invoiceApply/components/excel-files-upload-relation/index.vue

@@ -0,0 +1,213 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import { ElMessage } from "element-plus";
+import { execlUpload } from "/@/components/execlUpload";
+import { httpInvoiceBatch } from "/@/api/purchase/ticketReturn";
+import { useResponseHandle } from "/@/hooks";
+import { useCompany } from "/@/hooks/core/useCompany";
+
+import { division } from "/@/utils/calc";
+
+
+import {
+  initheaders,
+  columns,
+  mapProp,
+  requireHeaders
+} from "./columns-config";
+
+const visible = ref(false);
+const loading = ref(false);
+const tableData = ref([]);
+const columnsConfig = columns();
+const emit = defineEmits(["onSuccess"]);
+
+const { currentCompany } = useCompany();
+
+const responseHandle = useResponseHandle();
+
+function validate(data: any[]){
+  let hasError = false
+  const requiredErrors = []
+  data.forEach((item,index) => {
+    const keys = Object.keys(item)
+    keys.forEach(key => {
+      if(requireHeaders.includes(key)){
+        const value = item[key]
+        if((!value || String(value).trim() === '' ) && !requiredErrors.includes(index + 1)) {
+          hasError = true
+          requiredErrors.push(index + 1)
+        }
+      }
+    })
+  })
+
+
+  if(hasError){  ElMessage.error('第 ' + requiredErrors.join(',') + ' 行' + '发票明细ID,订单编号,本次开票金额,本次开票数量不能为空') }
+  return hasError
+}
+
+const Uploadsuccess = ({ results, header }) => {
+  loading.value = true;
+  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]) {
+        console.log(si, header[sii])
+        headok = false;
+      }
+    });
+  }
+  if (!headok) {
+    ElMessage.error("表头与导入模板不匹配!");
+    loading.value = false;
+    return;
+  }
+  tableData.value = [];
+  try {
+    for (const v1 of results) {
+      const b = Object.values(v1);
+      let model = {};
+      b.forEach((si, sii) => {
+        model["value" + sii] = si + "";
+      });
+      tableData.value.push(model);
+    }
+    loading.value = false;
+  } catch (err) {
+    return err;
+  }
+  const data = []
+  tableData.value.forEach((key, index) => {
+    const obj: Record<string, string> = {};
+    for (let i in key) {
+      const prop = mapProp[i];
+      const value = key[i];
+      obj[prop] = value;
+    }
+    data.push(obj);
+  });
+  const isValid = validate(data)
+  if(isValid){
+    tableData.value = []
+  }
+};
+
+
+//提交
+const handleSubmit = async () => {
+  if (loading.value) return;
+  let list = []
+
+  const data = [];
+
+  tableData.value.forEach((key, index) => {
+    const obj: Record<string, string> = {};
+    for (let i in key) {
+      const prop = mapProp[i];
+      const value = key[i];
+      obj[prop] = value;
+    }
+    data.push(obj);
+  });
+  
+  data.forEach(item => {
+    const { itemId, code, num, total_amount } = item
+    const good_price = Number(division(total_amount, num)).toFixed(2)
+    list.push({ itemId, code, num, good_price , total_amount, remark: '' })
+  });
+
+  const { code, message } = await httpInvoiceBatch({ order_type: '1', list });
+
+  responseHandle({
+    code,
+    message,
+    handler: () => {
+      ElMessage.success("数据导入成功!");
+      emit("onSuccess");
+      visible.value = false;
+    }
+  });
+};
+const cancel = () => {
+  tableData.value = [];
+};
+defineExpose({
+  onDisplay: () => ((visible.value = true), (tableData.value = []))
+});
+</script>
+
+<template>
+  <el-dialog
+    :close-on-click-modal="false"
+    v-model="visible"
+    title="批量导入发票与订单关联结果"
+    width="1040px"
+    top="8vh"
+    center
+  >
+    <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"
+        :type="si.type"
+        :minWidth="si.minWidth"
+        :fixed="si.fixed"
+        :key="sii"
+        :prop="si.prop"
+        show-overflow-tooltip
+      >
+        <template #header>
+          <span
+            v-if="
+              !requireHeaders.includes(mapProp[si.prop]) || si.label === '序号'
+            "
+            >{{ si.label }}</span
+          >
+          <p v-else>
+            <span style="color: #f56c6c; font-size: 14px">* </span>
+            {{ si.label }}
+          </p>
+        </template>
+      </el-table-column>
+    </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>
+:deep(.el-upload-list__item) {
+  display: none !important;
+}
+</style>

+ 12 - 0
src/views/InvoiceSales/invoiceApply/config/xls-template.ts

@@ -8,3 +8,15 @@ export const template = {
   校验码: "",
   开票日期: "2020/12/17  0:00:00"
 };
+
+export const relationTemplate = {
+  发票明细ID: '1',
+  订单编号: '',
+  订单主编号: '',
+  商品名称: '',
+  开票商品名称: '',
+  商品类目编号: '',
+  税率: '',
+  本次开票金额: "",
+  本次开票数量: ""
+}

+ 34 - 3
src/views/InvoiceSales/invoiceApply/index.vue

@@ -11,7 +11,7 @@ import { httpSetPost, httpStatus } from "/@/api/InvoiceSales/invoiceApply";
 import { useAsync } from "/@/hooks/core/useAsync";
 import ExeclUpload from "./components/execl-files-upload/index.vue";
 import { httpRequsetExport } from "/@/utils/export";
-import { template } from "./config/xls-template";
+import { template, relationTemplate } from "./config/xls-template";
 import { usePermission } from "/@/hooks/core/usePermission";
 import ApprovalModal from "./components/approval-modal.vue";
 import BackModal from "./components/back-modal.vue";
@@ -19,13 +19,15 @@ import { ElMessage } from "element-plus";
 import { writeFile, utils } from "xlsx";
 import InvoiceModal from "./invoice-modal.vue"
 
+import ExcelUploadRelation from "./components/excel-files-upload-relation/index.vue"
+
 const PageName = "invoiceApply";
 
 //   { code: "040", name: "批量审核" },
 //   { code: "026", name: "导出发票申请信息" },
 //   { code: "027", name: "下载发票信息导入模板" },
 //   { code: "028", name: "批量导入财务开票结果(发票申请)" },
-
+const excelUploadRelationRef = ref<InstanceType<typeof ExcelUploadRelation> | null>(null)
 const { hasPermissionWithCode } = usePermission(PageName);
 const loading = ref(false);
 const baseUrl = "/InvoiceSales/invoiceApplyDetail";
@@ -85,6 +87,18 @@ function handleBatchApproval() {
   approvalModalRef.value.onDisplay(selected.value);
 }
 
+//导出模板
+function onDownloadRelationTemplate() {
+  //创建数据表
+  const workBook = utils.book_new();
+  const workSheet = utils.json_to_sheet([relationTemplate]);
+  utils.book_append_sheet(workBook, workSheet, "sheet");
+  //导出模板
+  writeFile(workBook, "发票与订单关联模板.xlsx", {
+    bookType: "xlsx"
+  });
+}
+
 function onDownloadTemplate() {
   //创建数据表
   const workBook = utils.book_new();
@@ -116,6 +130,21 @@ function onDownloadTemplate() {
         >
           财务批量审核(勾选)
         </ElButton>
+        <ElButton
+          size="small"
+          type="primary"
+          v-if="!isSuperUser"
+          :icon="useRenderIcon('arrow-up-line')"
+          @click="() => excelUploadRelationRef.onDisplay()"
+          >批量导入票与订单关联数据
+        </ElButton>
+
+        <ElButton 
+          size="small"
+          :icon="useRenderIcon('arrow-down-line')"
+          @click="onDownloadRelationTemplate"
+        >下载发票与订单关联模板</ElButton>
+
         <ElButton
           v-if="hasPermissionWithCode('026')"
           :icon="useRenderIcon('arrow-up-line')"
@@ -206,8 +235,10 @@ function onDownloadTemplate() {
       @onBatchApprovalComplete="() => instance.onSearch()"
     />
     <ExeclUpload ref="execlUploadRef" @on-success="() => instance.onSearch()" />
-    <back-modal ref="backModalRef" @refresh="() => instance.onSearch()" />
+
       
+    <back-modal ref="backModalRef" @refresh="() => instance.onSearch()" />
+    <ExcelUploadRelation ref="excelUploadRelationRef" @on-success="() => (instance as any).onSearch()" />
     <InvoiceModal ref="invModalRef" />
   </PageAuth>
 </template>

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff