cz 1 year ago
parent
commit
fbabaf1647

+ 5 - 1
src/components/byTable/index.vue

@@ -159,7 +159,7 @@
         :height="tableHeight"
       >
         <el-table-column
-          v-for="(item, index) in config"
+          v-for="(item, index) in configData"
           :key="index"
           v-bind="getAttrsValue(item)"
           :type="item.type || ''"
@@ -355,6 +355,9 @@ export default defineComponent({
 
   setup(props) {
     const { proxy } = getCurrentInstance();
+    // 过滤出有属性的
+    const configData = ref([]);
+    configData.value = proxy.config.filter((x) => x && x.attrs);
     const selectConfigCopy = computed(() => {
       return props.selectConfig.map((item) => {
         if (!item.labelCopy) item.labelCopy = { ...item }.label;
@@ -528,6 +531,7 @@ export default defineComponent({
     const hocElTable = ref();
 
     return {
+      configData,
       getParent,
       getPagination,
       renderTypeList,

+ 215 - 0
src/views/EHSD/saleContract/contractEHSD/index.vue

@@ -174,6 +174,94 @@
     >
       <ContractDetails :contractId="currentContractId"></ContractDetails>
     </el-dialog>
+
+    <el-dialog
+      :title="`售后记录`"
+      v-if="openRecords"
+      v-model="openRecords"
+      width="600"
+    >
+      <div style="padding-left: 50px; margin-bottom: 20px">
+        <el-button type="primary" plain @click="handleClickAddRecord()"
+          >添加记录</el-button
+        >
+      </div>
+      <el-timeline>
+        <el-timeline-item v-for="(activity, index) in recordsData" :key="index">
+          <div
+            style="
+              width: 100%;
+              display: flex;
+              justify-content: space-between;
+              color: #bfb9b9;
+            "
+          >
+            <div>售后时间:{{ activity.documentaryTime }}</div>
+            <div>{{ activity.userName }}</div>
+          </div>
+          <div style="width: 100%; margin-top: 8px">
+            售后记录:{{ activity.documentaryRemark }}
+          </div>
+          <div
+            style="width: 100%; margin-top: 8px"
+            v-if="activity.fileList && activity.fileList.length > 0"
+          >
+            <div v-for="(item, index) in activity.fileList" :key="index">
+              <div
+                style="cursor: pointer; color: #409eff"
+                @click="openFile(item)"
+              >
+                {{ item.fileName }}
+              </div>
+            </div>
+          </div>
+        </el-timeline-item>
+      </el-timeline>
+
+      <template #footer>
+        <el-button @click="openRecords = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      :title="`添加售后记录`"
+      v-if="openAddRecords"
+      v-model="openAddRecords"
+      width="600"
+    >
+      <byForm
+        :formConfig="recordsFormConfig"
+        :formOption="formOption"
+        v-model="formData.recordsFormData"
+        :rules="recordsRules"
+        ref="recordsForm"
+        v-loading="formLoading"
+      >
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="formData.recordsFormData.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile"
+            >
+              <el-button type="primary" plain>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openAddRecords = false" size="large"
+          >关 闭</el-button
+        >
+        <el-button type="primary" @click="submitRecords()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -457,6 +545,18 @@ const config = computed(() => {
               });
             },
           },
+          {
+            attrs: {
+              label: "售后",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              openRecords.value = true;
+              getRecordsData(row);
+            },
+          },
         ];
       },
     },
@@ -838,6 +938,121 @@ const PdfDom = ref(null);
 const exportExcel = () => {
   PdfDom.value.exportExcel();
 };
+
+const formData = reactive({
+  recordsFormData: {},
+});
+const formLoading = ref(false);
+const openRecords = ref(false);
+const openAddRecords = ref(false);
+const recordsLoading = ref(false);
+const recordsData = ref([]);
+const recordsForm = ref(null);
+const rowContractData = ref({});
+const recordsFormConfig = computed(() => [
+  {
+    type: "date",
+    itemType: "datetime",
+    prop: "documentaryTime",
+    label: "售后时间",
+    disabled: false,
+  },
+
+  {
+    type: "input",
+    prop: "documentaryRemark",
+    label: "售后记录",
+    itemType: "textarea",
+    disabled: false,
+  },
+  {
+    type: "slot",
+    slotName: "file",
+    label: "上传附件",
+  },
+]);
+const recordsRules = ref({
+  documentaryTime: [
+    { required: true, message: "请选择售后时间", trigger: "change" },
+  ],
+  documentaryRemark: [
+    { required: true, message: "请输入售后记录", trigger: "blur" },
+  ],
+});
+const getRecordsData = (row) => {
+  if (row && row.id) {
+    rowContractData.value = row;
+  }
+  proxy
+    .post("/contractDocumentary/page", {
+      businessId: rowContractData.value.id,
+      documentaryType: "-2",
+    })
+    .then((res) => {
+      recordsData.value = res.rows;
+      const idList = recordsData.value.map((x) => x.id);
+      // 请求文件数据并回显
+      if (idList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: idList,
+          })
+          .then((fileObj) => {
+            if (fileObj) {
+              for (let i = 0; i < recordsData.value.length; i++) {
+                const e = recordsData.value[i];
+                for (const key in fileObj) {
+                  if (e.id === key) {
+                    e.fileList = fileObj[key];
+                  }
+                }
+              }
+            }
+          });
+      }
+    });
+};
+const handleClickAddRecord = () => {
+  formData.recordsFormData = {
+    businessId: rowContractData.value.id,
+    businessType: "0",
+    documentaryType: "-2",
+    documentaryTime: proxy.parseTime(new Date()),
+    documentaryRemark: "",
+    fileList: [],
+  };
+  openAddRecords.value = true;
+};
+
+const submitRecords = () => {
+  recordsForm.value.handleSubmit(() => {
+    formLoading.value = true;
+    formData.recordsFormData.fileList = formData.recordsFormData.fileList.map(
+      (item) => {
+        return {
+          id: item.raw.id,
+          fileName: item.raw.fileName,
+          fileUrl: item.raw.fileUrl,
+          uploadState: item.raw.uploadState,
+        };
+      }
+    );
+    proxy
+      .post("/contractDocumentary/add", formData.recordsFormData)
+      .then((res) => {
+        ElMessage({
+          message: "操作成功",
+          type: "success",
+        });
+        formLoading.value = false;
+        openAddRecords.value = false;
+        getRecordsData();
+      });
+  });
+};
+const openFile = (item) => {
+  window.open(item.fileUrl, "_blank");
+};
 </script>
 
 <style lang="scss" scoped>

+ 112 - 41
src/views/EHSD/saleContract/exportTracking/index.vue

@@ -80,7 +80,12 @@
       <template #purchaseCode="{ item }">
         <div style="width: 100%">
           <div v-if="item.purchaseList && item.purchaseList.length > 0">
-            <div v-for="(purchase, index) in item.purchaseList" :key="index">
+            <div
+              v-for="(purchase, index) in item.purchaseList"
+              :key="index"
+              class="public-class"
+              @click="hdanlePushPurchase(purchase.code)"
+            >
               {{ purchase.code }}
             </div>
           </div>
@@ -600,8 +605,10 @@
 <script setup>
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
-import useUserStore from "@/store/modules/user";
 import { ElMessage, ElMessageBox } from "element-plus";
+import { computed } from "vue";
+import useUserStore from "@/store/modules/user";
+const userInfo = useUserStore();
 const tableHeight = ref(0);
 const getTableHeight = () => {
   tableHeight.value = window.innerHeight - 270;
@@ -684,14 +691,16 @@ const config = computed(() => {
         align: "center",
       },
     },
-    {
-      attrs: {
-        label: "客户",
-        slot: "customer",
-        "min-width": 140,
-        fixed: "left",
-      },
-    },
+    isShowSalesmanArrange.value
+      ? {
+          attrs: {
+            label: "客户",
+            slot: "customer",
+            "min-width": 140,
+            fixed: "left",
+          },
+        }
+      : {},
     {
       attrs: {
         label: "产品",
@@ -699,35 +708,41 @@ const config = computed(() => {
         width: 140,
       },
     },
-    {
-      attrs: {
-        label: "条款",
-        slot: "tags",
-        width: 80,
-      },
-    },
-    {
-      attrs: {
-        label: "定金",
-        prop: "earnest",
-        width: 100,
-      },
-      render(money) {
-        return proxy.moneyFormat(money, 2);
-      },
-    },
-    {
-      attrs: {
-        label: "定金到账时间",
-        prop: "claimTime",
-        width: 110,
-      },
-      render(time) {
-        if (time) {
-          return time.slice(0, 11);
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "条款",
+            slot: "tags",
+            width: 80,
+          },
         }
-      },
-    },
+      : {},
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "定金",
+            prop: "earnest",
+            width: 100,
+          },
+          render(money) {
+            return proxy.moneyFormat(money, 2);
+          },
+        }
+      : {},
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "定金到账时间",
+            prop: "claimTime",
+            width: 110,
+          },
+          render(time) {
+            if (time) {
+              return time.slice(0, 11);
+            }
+          },
+        }
+      : {},
     {
       attrs: {
         label: "交接单",
@@ -870,9 +885,41 @@ const headerList = ref([
     slot: "slot12",
   },
 ]);
+const isShowSalesmanArrange = ref(true);
+const isShowSalesFinancemanArrange = ref(true);
+const checkShow = () => {
+  // 当前账号角色如果不是业务总监、总经理、业务员,则不能查看
+  if (
+    !(
+      userInfo.roles.includes("salesDirector") ||
+      userInfo.roles.includes("ceo") ||
+      userInfo.roles.includes("salesman")
+    )
+  ) {
+    isShowSalesmanArrange.value = false;
+  }
+  // 当前账号角色如果不是业务总监、总经理、业务员、财务,则不能查看
+  if (
+    !(
+      userInfo.roles.includes("salesDirector") ||
+      userInfo.roles.includes("ceo") ||
+      userInfo.roles.includes("salesman") ||
+      userInfo.roles.includes("financeOfficer")
+    )
+  ) {
+    isShowSalesFinancemanArrange.value = false;
+  }
+};
+checkShow();
 const arrangeInit = () => {
   for (let i = 0; i < headerList.value.length; i++) {
     const element = headerList.value[i];
+    if (
+      ["9", "11", "12"].includes(element.value) &&
+      !isShowSalesmanArrange.value
+    ) {
+      continue;
+    }
     let width = 150;
     if (element.label.length > 5) {
       width = 250;
@@ -894,9 +941,11 @@ const arrangeInit = () => {
     isNeedHeaderSlot: false,
     width: 120,
   };
-  config.value.push({
-    attrs,
-  });
+  if (isShowSalesmanArrange.value) {
+    config.value.push({
+      attrs,
+    });
+  }
 };
 arrangeInit();
 const headerData = ref({});
@@ -1095,10 +1144,14 @@ const handleClickLook = (row, purchase, node) => {
   getRecordsData();
 };
 const handleClickAddRecord = () => {
+  recordsRules.value.documentaryRemark = [
+    { required: true, message: "请输入跟单记录", trigger: "blur" },
+  ];
   let type = selectNode.value.value;
   let label = "";
   if (type == "6") {
     label = "验货结论";
+    delete recordsRules.value.documentaryRemark;
   } else if (type == "8") {
     label = "是否收到";
   } else if (type == "10") {
@@ -1135,6 +1188,7 @@ const handleClickAddRecord = () => {
       type: "slot",
       slotName: "file",
       label: "上传附件",
+      required: type == "6" ? true : false,
     },
   ];
   formData.recordsFormData = {
@@ -1151,6 +1205,14 @@ const handleClickAddRecord = () => {
 
 const submitRecords = () => {
   recordsForm.value.handleSubmit(() => {
+    if (selectNode.value.value == "6") {
+      if (!formData.recordsFormData.fileList.length > 0) {
+        return ElMessage({
+          message: "请上传附件",
+          type: "info",
+        });
+      }
+    }
     formLoading.value = true;
     formData.recordsFormData.fileList = formData.recordsFormData.fileList.map(
       (item) => {
@@ -1292,6 +1354,15 @@ const handleClickHeader = (type) => {
   sourceList.value.pagination.documentarySearch = clickNum.value;
   getList();
 };
+
+const hdanlePushPurchase = (code) => {
+  proxy.$router.push({
+    name: "Purchased",
+    query: {
+      code: code,
+    },
+  });
+};
 </script>
 
 <style lang="scss" scoped>

+ 214 - 0
src/views/EHSD/saleContract/sampleEHSD/index.vue

@@ -174,6 +174,94 @@
         >
       </template>
     </el-dialog>
+
+    <el-dialog
+      :title="`售后记录`"
+      v-if="openRecords"
+      v-model="openRecords"
+      width="600"
+    >
+      <div style="padding-left: 50px; margin-bottom: 20px">
+        <el-button type="primary" plain @click="handleClickAddRecord()"
+          >添加记录</el-button
+        >
+      </div>
+      <el-timeline>
+        <el-timeline-item v-for="(activity, index) in recordsData" :key="index">
+          <div
+            style="
+              width: 100%;
+              display: flex;
+              justify-content: space-between;
+              color: #bfb9b9;
+            "
+          >
+            <div>售后时间:{{ activity.documentaryTime }}</div>
+            <div>{{ activity.userName }}</div>
+          </div>
+          <div style="width: 100%; margin-top: 8px">
+            售后记录:{{ activity.documentaryRemark }}
+          </div>
+          <div
+            style="width: 100%; margin-top: 8px"
+            v-if="activity.fileList && activity.fileList.length > 0"
+          >
+            <div v-for="(item, index) in activity.fileList" :key="index">
+              <div
+                style="cursor: pointer; color: #409eff"
+                @click="openFile(item)"
+              >
+                {{ item.fileName }}
+              </div>
+            </div>
+          </div>
+        </el-timeline-item>
+      </el-timeline>
+
+      <template #footer>
+        <el-button @click="openRecords = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      :title="`添加售后记录`"
+      v-if="openAddRecords"
+      v-model="openAddRecords"
+      width="600"
+    >
+      <byForm
+        :formConfig="recordsFormConfig"
+        :formOption="formOption"
+        v-model="formData.recordsFormData"
+        :rules="recordsRules"
+        ref="recordsForm"
+        v-loading="formLoading"
+      >
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="formData.recordsFormData.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile"
+            >
+              <el-button type="primary" plain>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openAddRecords = false" size="large"
+          >关 闭</el-button
+        >
+        <el-button type="primary" @click="submitRecords()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -457,6 +545,18 @@ const config = computed(() => {
               });
             },
           },
+          {
+            attrs: {
+              label: "售后",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              openRecords.value = true;
+              getRecordsData(row);
+            },
+          },
         ];
       },
     },
@@ -842,6 +942,120 @@ const PdfDom = ref(null);
 const exportExcel = () => {
   PdfDom.value.exportExcel();
 };
+const formData = reactive({
+  recordsFormData: {},
+});
+const formLoading = ref(false);
+const openRecords = ref(false);
+const openAddRecords = ref(false);
+const recordsLoading = ref(false);
+const recordsData = ref([]);
+const recordsForm = ref(null);
+const rowSampleData = ref({});
+const recordsFormConfig = computed(() => [
+  {
+    type: "date",
+    itemType: "datetime",
+    prop: "documentaryTime",
+    label: "售后时间",
+    disabled: false,
+  },
+
+  {
+    type: "input",
+    prop: "documentaryRemark",
+    label: "售后记录",
+    itemType: "textarea",
+    disabled: false,
+  },
+  {
+    type: "slot",
+    slotName: "file",
+    label: "上传附件",
+  },
+]);
+const recordsRules = ref({
+  documentaryTime: [
+    { required: true, message: "请选择售后时间", trigger: "change" },
+  ],
+  documentaryRemark: [
+    { required: true, message: "请输入售后记录", trigger: "blur" },
+  ],
+});
+const getRecordsData = (row) => {
+  if (row && row.id) {
+    rowSampleData.value = row;
+  }
+  proxy
+    .post("/contractDocumentary/page", {
+      businessId: rowSampleData.value.id,
+      documentaryType: "-1",
+    })
+    .then((res) => {
+      recordsData.value = res.rows;
+      const idList = recordsData.value.map((x) => x.id);
+      // 请求文件数据并回显
+      if (idList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: idList,
+          })
+          .then((fileObj) => {
+            if (fileObj) {
+              for (let i = 0; i < recordsData.value.length; i++) {
+                const e = recordsData.value[i];
+                for (const key in fileObj) {
+                  if (e.id === key) {
+                    e.fileList = fileObj[key];
+                  }
+                }
+              }
+            }
+          });
+      }
+    });
+};
+const handleClickAddRecord = () => {
+  formData.recordsFormData = {
+    businessId: rowSampleData.value.id,
+    businessType: "2",
+    documentaryType: "-1",
+    documentaryTime: proxy.parseTime(new Date()),
+    documentaryRemark: "",
+    fileList: [],
+  };
+  openAddRecords.value = true;
+};
+
+const submitRecords = () => {
+  recordsForm.value.handleSubmit(() => {
+    formLoading.value = true;
+    formData.recordsFormData.fileList = formData.recordsFormData.fileList.map(
+      (item) => {
+        return {
+          id: item.raw.id,
+          fileName: item.raw.fileName,
+          fileUrl: item.raw.fileUrl,
+          uploadState: item.raw.uploadState,
+        };
+      }
+    );
+    proxy
+      .post("/contractDocumentary/add", formData.recordsFormData)
+      .then((res) => {
+        ElMessage({
+          message: "操作成功",
+          type: "success",
+        });
+        formLoading.value = false;
+        openAddRecords.value = false;
+        getRecordsData();
+      });
+  });
+};
+const openFile = (item) => {
+  window.open(item.fileUrl, "_blank");
+};
 </script>
 
 <style lang="scss" scoped>