瀏覽代碼

新需求

cz 1 年之前
父節點
當前提交
f9bcc0218c

+ 43 - 14
src/views/JXSK/afterSales/add.vue

@@ -49,7 +49,7 @@ const rules = {
   productSn: [
     {
       required: true,
-      message: proxy.t("afterSales.pleaseEnterTheEquipmentSN"),
+      message: "请输入产品Sn",
     },
   ],
   afterSalesPersonId: [
@@ -61,7 +61,25 @@ const rules = {
   remark: [
     {
       required: true,
-      message: proxy.t("afterSales.pleaseEnterTheAfterSalesReason"),
+      message: "请输入售后说明",
+    },
+  ],
+  contactName: [
+    {
+      required: true,
+      message: "请输入客户联系人",
+    },
+  ],
+  contactInfo: [
+    {
+      required: true,
+      message: "请输入客户联系方式",
+    },
+  ],
+  type: [
+    {
+      required: true,
+      message: "请选择售后类型",
     },
   ],
 };
@@ -80,7 +98,7 @@ const formConfig = reactive([
     prop: "productSn",
     isNeedBlurMethon: true,
     blurMethon: (val) => {
-      // showScanData(val);
+      showScanData(val);
     },
     isNeedRightBtn: true,
     rightIcon: "scan",
@@ -88,7 +106,6 @@ const formConfig = reactive([
       handleScanCode();
     },
   },
-
   {
     type: "input",
     label: proxy.t("afterSales.productName"),
@@ -104,7 +121,7 @@ const formConfig = reactive([
   {
     type: "input",
     label: "客户名称",
-    prop: "productSpec",
+    prop: "customerName",
     readonly: true,
   },
   {
@@ -116,7 +133,7 @@ const formConfig = reactive([
   {
     type: "picker",
     label: "售后类型",
-    prop: "afterSalesPersonId",
+    prop: "type",
     itemType: "onePicker",
     showPicker: false,
     fieldNames: {
@@ -134,14 +151,12 @@ const formConfig = reactive([
   {
     type: "input",
     label: "客户联系人",
-    prop: "productSpec",
-    readonly: true,
+    prop: "contactName",
   },
   {
     type: "input",
     label: "客户联系方式",
-    prop: "productSpec",
-    readonly: true,
+    prop: "contactInfo",
   },
   {
     type: "picker",
@@ -155,12 +170,24 @@ const formConfig = reactive([
     },
     data: [],
   },
+  {
+    type: "upload",
+    label: "售后附件",
+    prop: "fileList",
+  },
 ]);
 const onClickLeft = () => history.back();
 
 const getDict = () => {
+  proxy.getDictOne(["after_sales_type"]).then((res) => {
+    formConfig[5].data = res["after_sales_type"].data.map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+
   proxy.get("/system/user/list?pageNum=1&pageSize=9999").then((res) => {
-    formConfig[3].data = res.rows.map((item) => {
+    formConfig[9].data = res.rows.map((item) => {
       return {
         label: item.userName,
         value: item.userId,
@@ -184,8 +211,7 @@ onMounted(() => {
   nextTick(() => {
     window.getVueMessage = (data) => {
       if (data) {
-        // showSuccessToast(data);
-        formData.data.productSn = data;
+        showScanData(data);
       }
     };
   });
@@ -215,8 +241,11 @@ const showScanData = (val) => {
   proxy.post("/productionTaskDetail/snInfo", { productSn: val }).then((res) => {
     if (res.data && res.data.productId) {
       formData.data.productId = res.data.productId;
-      formData.data.code = res.data.code;
+      formData.data.productSn = res.data.productSn;
+      formData.data.code = res.data.contractCode;
       formData.data.productName = res.data.productName;
+      formData.data.productSpec = res.data.productSpec;
+      formData.data.customerName = res.data.customerName;
     }
   });
 };

+ 168 - 27
src/views/JXSK/afterSales/edit.vue

@@ -24,7 +24,52 @@
 
       <template #list>
         <div style="width: 100%">
-          <div
+          <van-collapse v-model="activeNames">
+            <van-collapse-item
+              v-for="(item, index) in formData.data.bomDetailList"
+              :key="item.id"
+              :name="item.id"
+              :value="'[ ' + item.quantity + ' ]'"
+            >
+              <template #title>
+                <div>
+                  <van-icon
+                    name="warning-o"
+                    v-if="
+                      submitData[item.productId].remark &&
+                      submitData[item.productId].fileList.length > 0
+                    "
+                    color="#ee0a24"
+                    style="margin-right: 5px"
+                  />
+
+                  {{ item.productName }}
+                </div>
+              </template>
+              <div>
+                <van-field
+                  v-model="submitData[item.productId].remark"
+                  label="售后说明"
+                  type="textarea"
+                  placeholder="请输入"
+                  label-align="top"
+                  :rules="[{ required: true, message: '请填写售后说明' }]"
+                />
+                <van-field name="uploader" label="现场照片">
+                  <template #input>
+                    <van-uploader
+                      v-model="submitData[item.productId].fileList"
+                      :after-read="afterRead"
+                      multiple
+                      :max-size="5 * 1024 * 1024"
+                      @oversize="onOversize"
+                    />
+                  </template>
+                </van-field>
+              </div>
+            </van-collapse-item>
+          </van-collapse>
+          <!-- <div
             v-for="(item, index) in formData.data.bomDetailList"
             :key="index"
           >
@@ -39,7 +84,7 @@
               @onClickItem="handleClickItem(item)"
             >
             </ShowFormData>
-          </div>
+          </div> -->
         </div>
       </template>
     </testForm>
@@ -56,11 +101,17 @@ import ShowFormData from "@/components/ShowFormData.vue";
 const proxy = getCurrentInstance().proxy;
 const route = useRoute();
 const formDom = ref(null);
+const activeNames = ref([]);
 const formData = reactive({
   data: {},
 });
 const rules = {
-  customerId: [{ required: true, message:proxy.t('afterSales.pleaseSelectTheCustomerName'), }],
+  customerId: [
+    {
+      required: true,
+      message: proxy.t("afterSales.pleaseSelectTheCustomerName"),
+    },
+  ],
 };
 const formOption = reactive({
   readonly: false, //用于控制整个表单是否只读
@@ -77,7 +128,7 @@ const formConfig = reactive([
   },
   {
     type: "title",
-    title: proxy.t('afterSales.originalPartsList'),
+    title: proxy.t("afterSales.originalPartsList"),
   },
   {
     type: "slot",
@@ -85,7 +136,7 @@ const formConfig = reactive([
   },
   {
     type: "title",
-    title: proxy.t('afterSales.programFile'),
+    title: proxy.t("afterSales.programFile"),
   },
   {
     type: "upload",
@@ -97,48 +148,53 @@ const formConfig = reactive([
 
 const topConfig = ref([
   {
-    label: proxy.t('afterSales.afterSalesCode'),
+    label: proxy.t("afterSales.afterSalesCode"),
     prop: "code",
   },
   {
-    label: proxy.t('afterSales.productName'),
+    label: proxy.t("afterSales.productName"),
     prop: "productName",
   },
   {
-    label: proxy.t('afterSales.productSN'),
+    label: proxy.t("afterSales.productSN"),
     prop: "productSn",
   },
 ]);
 
 const listConfig = ref([
   {
-    label: proxy.t('afterSales.accessoriesName'),
+    label: proxy.t("afterSales.accessoriesName"),
     prop: "productName",
   },
   {
-    label: proxy.t('afterSales.quantity'),
+    label: proxy.t("afterSales.quantity"),
     prop: "quantity",
   },
 ]);
 
 const onClickLeft = () => history.back();
-
+const submitData = ref({});
 const getDetails = (id) => {
   proxy.post("/afterSalesRecord/detail", { id }).then((res) => {
     formData.data = res.data;
     const obj = JSON.parse(window.localStorage.getItem("jxstAfterSalesData"));
     for (let i = 0; i < formData.data.bomDetailList.length; i++) {
       const e = formData.data.bomDetailList[i];
-      if (e.afterSalesRecordDetail) {
-        e.productName = e.productName + proxy.t('afterSales.afterSales');
-      }
-      for (const key in obj) {
-        if (e.productId === key) {
-          e.accessoriesId = key;
-          e.remark = obj[key].remark;
-          e.fileList = obj[key].fileList;
-        }
-      }
+      submitData.value[e.productId] = {
+        accessoriesId: e.productId,
+        remark: "",
+        fileList: [],
+      };
+      // if (e.afterSalesRecordDetail) {
+      //   e.productName = e.productName + proxy.t("afterSales.afterSales");
+      // }
+      // for (const key in obj) {
+      //   if (e.productId === key) {
+      //     e.accessoriesId = key;
+      //     e.remark = obj[key].remark;
+      //     e.fileList = obj[key].fileList;
+      //   }
+      // }
     }
     if (res.data.bomInfoId) {
       proxy
@@ -163,18 +219,21 @@ onMounted(() => {
 });
 
 const onSubmit = () => {
+  let arr = Object.values(submitData.value);
+  for (let i = 0; i < arr.length; i++) {
+    const e = arr[i];
+    if (e.fileList.length == 0) {
+      return showFailToast(`第${i + 1}个配件没传现场照片`);
+    }
+  }
   proxy
     .post("/afterSalesRecord/afterSales", {
       id: formData.data.id,
-      afterSalesRecordDetailList: formData.data.bomDetailList.map((x) => ({
-        accessoriesId: x.accessoriesId,
-        remark: x.remark,
-        fileList: x.fileList,
-      })),
+      afterSalesRecordDetailList: arr,
     })
     .then(
       () => {
-        showSuccessToast(proxy.t('afterSales.operationSuccessful'));
+        showSuccessToast(proxy.t("afterSales.operationSuccessful"));
         setTimeout(() => {
           onClickLeft();
         }, 500);
@@ -205,9 +264,91 @@ const handleClickItem = (item) => {
     });
   }
 };
+
+const afterRead = (file) => {
+  if (file && file.length > 0) {
+    for (let i = 0; i < file.length; i++) {
+      file[i].status = "uploading";
+      file[i].message = "上传中...";
+      proxy.post("/fileInfo/getSing", { fileName: file[i].file.name }).then(
+        (res) => {
+          let forms = new FormData();
+          forms.append("file", file[i].file);
+          proxy
+            .post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", {
+              ...res.data.uploadBody,
+              file: forms.get("file"),
+            })
+            .then(
+              () => {
+                file[i].id = res.data.id;
+                file[i].url = res.data.fileUrl;
+                file[i].fileName = res.data.fileName;
+                delete file[i].status;
+                delete file[i].message;
+              },
+              () => {
+                file[i].status = "failed";
+                file[i].message = "上传失败";
+              }
+            );
+        },
+        () => {
+          file[i].status = "failed";
+          file[i].message = "上传失败";
+        }
+      );
+    }
+  } else {
+    file.status = "uploading";
+    file.message = "上传中...";
+    proxy.post("/fileInfo/getSing", { fileName: file.file.name }).then(
+      (res) => {
+        let forms = new FormData();
+        forms.append("file", file.file);
+        proxy
+          .post("https://winfaster.obs.cn-south-1.myhuaweicloud.com", {
+            ...res.data.uploadBody,
+            file: forms.get("file"),
+          })
+          .then(
+            () => {
+              file.id = res.data.id;
+              file.url = res.data.fileUrl;
+              file.fileName = res.data.fileName;
+              delete file.status;
+              delete file.message;
+            },
+            () => {
+              file.status = "failed";
+              file.message = "上传失败";
+            }
+          );
+      },
+      () => {
+        file.status = "failed";
+        file.message = "上传失败";
+      }
+    );
+  }
+};
+// 文件上传
+const onOversize = () => {
+  showToast("文件大小不能超过 5MB");
+};
 </script>
 <style lang="scss" scoped>
 .form {
   margin-bottom: 60px;
 }
+
+::v-deep {
+  .van-field--label-top .van-icon-arrow {
+    right: -2px;
+    top: -12px;
+  }
+  .van-cell__value {
+    padding-right: 10px;
+  }
+}
 </style>

+ 13 - 7
src/views/JXSK/afterSales/index.vue

@@ -6,7 +6,7 @@
     @click-left="onClickLeft"
     @click-right="onClickRight"
   >
-    <template #right> {{$t('common.add')}} </template>
+    <template #right> {{ $t("common.add") }} </template>
   </van-nav-bar>
   <van-search
     v-model="req.keyword"
@@ -48,19 +48,23 @@ const proxy = getCurrentInstance().proxy;
 const listData = ref([]);
 const listConfig = ref([
   {
-    label: proxy.t('afterSales.afterSalesCode'),
+    label: proxy.t("afterSales.afterSalesCode"),
     prop: "code",
   },
   {
-    label: proxy.t('afterSales.productName'),
+    label: proxy.t("afterSales.productSN"),
+    prop: "productSn",
+  },
+  {
+    label: proxy.t("afterSales.productName"),
     prop: "productName",
   },
   {
-    label: proxy.t('afterSales.productSN'),
-    prop: "productSn",
+    label: "规格型号",
+    prop: "productSpec",
   },
   {
-    label: proxy.t('afterSales.afterSalesStatus'),
+    label: proxy.t("afterSales.afterSalesStatus"),
     prop: "statusName",
   },
 ]);
@@ -102,7 +106,9 @@ const getList = (type) => {
     .then((res) => {
       res.data.rows = res.data.rows.map((x) => ({
         ...x,
-        statusName: x.status ? proxy.t('afterSales.processingCompleted') : proxy.t('afterSales.processing'),
+        statusName: x.status
+          ? proxy.t("afterSales.processingCompleted")
+          : proxy.t("afterSales.processing"),
       }));
       listData.value =
         type === "refresh"

+ 6 - 6
src/views/JXSK/salesContract/add.vue

@@ -38,12 +38,12 @@ const rules = {
       message: proxy.t("salesContract.pleaseSelectTheCustomerName"),
     },
   ],
-  deliveryDate: [
-    {
-      required: true,
-      message: proxy.t("salesContract.pleaseSelectTheDeliveryDeadline"),
-    },
-  ],
+  // deliveryDate: [
+  //   {
+  //     required: true,
+  //     message: proxy.t("salesContract.pleaseSelectTheDeliveryDeadline"),
+  //   },
+  // ],
   payMethod: [
     {
       required: true,

+ 15 - 12
src/views/MES/produce/plan/details.vue

@@ -11,7 +11,7 @@
     <div>
       <common-top :data="formData" :config="topConfig"> </common-top>
       <div style="line-height: 32px; color: #999999; padding: 0 15px">
-        {{$t('plan.productionTask')}}
+        {{ $t("plan.productionTask") }}
       </div>
       <common-body :data="formData.productionTaskList" :config="bodyConfig">
       </common-body>
@@ -47,35 +47,38 @@ const formData = ref({
 
 const topConfig = ref([
   {
-    label: proxy.t('plan.planTime'),
+    label: proxy.t("plan.planTime"),
     prop: "time",
   },
   {
-    label: proxy.t('plan.productName'),
+    label: proxy.t("plan.productName"),
     prop: "productName",
   },
-
   {
-    label: proxy.t('plan.planQuantity'),
+    label: "规格型号",
+    prop: "productSpec",
+  },
+  {
+    label: proxy.t("plan.planQuantity"),
     prop: "quantity",
   },
   {
-    label: proxy.t('plan.planStatus'),
+    label: proxy.t("plan.planStatus"),
     prop: "statusName",
   },
 ]);
 
 const bodyConfig = ref([
   {
-    label: proxy.t('plan.taskQuantity'),
+    label: proxy.t("plan.taskQuantity"),
     prop: "quantity",
   },
   {
-    label: proxy.t('plan.principal'),
+    label: proxy.t("plan.principal"),
     prop: "personLiableName",
   },
   {
-    label: proxy.t('plan.completionStatus'),
+    label: proxy.t("plan.completionStatus"),
     prop: "status",
   },
 ]);
@@ -87,11 +90,11 @@ const getDetails = (id) => {
     let status = res.data.status;
     res.data.statusName =
       status == 0
-        ? proxy.t('plan.notStarted')
+        ? proxy.t("plan.notStarted")
         : status == 1
-        ? proxy.t('plan.ongoing')
+        ? proxy.t("plan.ongoing")
         : status == 2
-        ? proxy.t('plan.complete')
+        ? proxy.t("plan.complete")
         : "";
 
     formData.value = res.data;