|
@@ -83,102 +83,179 @@
|
|
|
<el-dialog
|
|
|
title="售后跟进"
|
|
|
v-model="openFollow"
|
|
|
- width="500"
|
|
|
+ width="80%"
|
|
|
destroy-on-close
|
|
|
v-if="openFollow"
|
|
|
>
|
|
|
- <byForm
|
|
|
- :formConfig="formConfigAFollow"
|
|
|
- :formOption="formOption"
|
|
|
- v-model="formData.followData"
|
|
|
- :rules="followRules"
|
|
|
- ref="followDom"
|
|
|
- v-loading="submitLoading"
|
|
|
- >
|
|
|
- <template #listSlot>
|
|
|
- <div style="width: 100%">
|
|
|
- <TitleInfo
|
|
|
- content="原配件清单"
|
|
|
- style="margin-bottom: 20px"
|
|
|
- ></TitleInfo>
|
|
|
-
|
|
|
- <el-collapse v-model="activeNames">
|
|
|
- <el-collapse-item
|
|
|
- v-for="(item, index) in formData.followData.bomDetailList"
|
|
|
- :key="item.id"
|
|
|
- :name="item.id"
|
|
|
- >
|
|
|
- <template #title>
|
|
|
- <div style="width: 380px; display: flex">
|
|
|
- <div style="flex: 1">
|
|
|
- <el-icon
|
|
|
- v-if="
|
|
|
- submitData[item.productId].remark &&
|
|
|
- submitData[item.productId].fileList.length > 0
|
|
|
- "
|
|
|
- style="margin-right: 10px"
|
|
|
- ><WarnTriangleFilled
|
|
|
- /></el-icon>
|
|
|
- {{ item.productName }}
|
|
|
+ <div style="width: 100%; display: flex">
|
|
|
+ <div style="width: 48%; height: 70vh; overflow: auto; margin-right: 2%">
|
|
|
+ <byForm
|
|
|
+ :formConfig="formConfigDetail"
|
|
|
+ :formOption="formOption"
|
|
|
+ v-model="formData.detailData"
|
|
|
+ ref="detailDom"
|
|
|
+ >
|
|
|
+ <template #title1>
|
|
|
+ <div style="width: 100%">
|
|
|
+ <TitleInfo content="产品信息"></TitleInfo>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #title2>
|
|
|
+ <div style="width: 100%">
|
|
|
+ <TitleInfo content="售后信息"></TitleInfo>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #file>
|
|
|
+ <div style="width: 100%">
|
|
|
+ <el-upload
|
|
|
+ v-model:fileList="formData.detailData.fileList"
|
|
|
+ action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
+ :data="uploadData"
|
|
|
+ multiple
|
|
|
+ :before-upload="handleBeforeUpload"
|
|
|
+ :on-success="handleSuccess"
|
|
|
+ :on-preview="onPreviewFile"
|
|
|
+ >
|
|
|
+ <el-button type="primary" plain disabled>选择</el-button>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </byForm>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="width: 50%; height: 70vh; overflow: auto; padding-right: 20px"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ :model="formData.followData"
|
|
|
+ label-width="120px"
|
|
|
+ label-position="top"
|
|
|
+ ref="followDom"
|
|
|
+ :rules="followRules"
|
|
|
+ v-loading="submitLoading"
|
|
|
+ >
|
|
|
+ <div style="width: 100%">
|
|
|
+ <TitleInfo
|
|
|
+ content="配件问题"
|
|
|
+ style="margin: 20px 0 20px 0"
|
|
|
+ ></TitleInfo>
|
|
|
+ <el-collapse v-model="activeNames">
|
|
|
+ <el-collapse-item
|
|
|
+ v-for="(item, index) in formData.followData.bomDetailList"
|
|
|
+ :key="item.id"
|
|
|
+ :name="item.id"
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ <div style="width: 100%; display: flex">
|
|
|
+ <div style="flex: 1">
|
|
|
+ <el-icon
|
|
|
+ color="red"
|
|
|
+ v-if="
|
|
|
+ submitData[item.productId].quantity &&
|
|
|
+ submitData[item.productId].remark &&
|
|
|
+ submitData[item.productId].fileList.length > 0
|
|
|
+ "
|
|
|
+ style="margin-right: 10px"
|
|
|
+ ><WarnTriangleFilled
|
|
|
+ /></el-icon>
|
|
|
+ {{ item.productName }}
|
|
|
+ </div>
|
|
|
+ <div style="margin-right: 10px">
|
|
|
+ [ {{ item.quantity }} ]
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div>[ {{ item.quantity }} ]</div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <div>
|
|
|
- <el-form-item label="售后说明" prop="remark" required>
|
|
|
- <el-input
|
|
|
- v-model="submitData[item.productId].remark"
|
|
|
- type="textarea"
|
|
|
- :disabled="isDetail"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- label="现场照片"
|
|
|
- prop="remark"
|
|
|
- required
|
|
|
- style="margin-top: 20px"
|
|
|
- >
|
|
|
- <div>
|
|
|
- <el-upload
|
|
|
- v-model:fileList="submitData[item.productId].fileList"
|
|
|
- action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
- :data="uploadData"
|
|
|
- multiple
|
|
|
- :before-upload="handleBeforeUpload"
|
|
|
- :on-success="handleSuccess"
|
|
|
- :on-preview="onPreviewFile"
|
|
|
- >
|
|
|
- <el-button type="primary" plain :disabled="isDetail"
|
|
|
- >选择</el-button
|
|
|
+ </template>
|
|
|
+ <div>
|
|
|
+ <el-form-item label="售后数量">
|
|
|
+ <el-input-number
|
|
|
+ onmousewheel="return false;"
|
|
|
+ v-model="submitData[item.productId].quantity"
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 100%"
|
|
|
+ :precision="0"
|
|
|
+ :controls="false"
|
|
|
+ :min="0"
|
|
|
+ :disabled="isDetail"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="售后说明">
|
|
|
+ <el-input
|
|
|
+ v-model="submitData[item.productId].remark"
|
|
|
+ type="textarea"
|
|
|
+ :disabled="isDetail"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="现场照片" style="margin-top: 20px">
|
|
|
+ <div>
|
|
|
+ <el-upload
|
|
|
+ v-model:fileList="submitData[item.productId].fileList"
|
|
|
+ action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
+ :data="uploadData"
|
|
|
+ multiple
|
|
|
+ :before-upload="handleBeforeUpload"
|
|
|
+ :on-success="handleSuccess"
|
|
|
+ :on-preview="onPreviewFile"
|
|
|
>
|
|
|
- </el-upload>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template #fileSlot>
|
|
|
- <div style="width: 100%">
|
|
|
- <TitleInfo
|
|
|
- content="程序文件"
|
|
|
- style="margin-bottom: 20px"
|
|
|
- ></TitleInfo>
|
|
|
- <el-upload
|
|
|
- v-model:fileList="formData.followData.fileList"
|
|
|
- action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
- :data="uploadData"
|
|
|
- multiple
|
|
|
- :before-upload="handleBeforeUpload"
|
|
|
- :on-success="handleSuccess"
|
|
|
- :on-preview="onPreviewFile"
|
|
|
- >
|
|
|
- <el-button type="primary" plain disabled>选择</el-button>
|
|
|
- </el-upload>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </byForm>
|
|
|
+ <el-button type="primary" plain :disabled="isDetail"
|
|
|
+ >选择</el-button
|
|
|
+ >
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ </el-collapse>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div style="width: 100%; margin-top: 20px">
|
|
|
+ <TitleInfo content="其他问题"></TitleInfo>
|
|
|
+ </div>
|
|
|
+ <el-form-item label=" " prop="afterSalesRemark">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.followData.afterSalesRemark"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入"
|
|
|
+ :disabled="isDetail"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <div style="width: 100%">
|
|
|
+ <TitleInfo
|
|
|
+ content="售后金额"
|
|
|
+ style="margin-top: 20px"
|
|
|
+ ></TitleInfo>
|
|
|
+ </div>
|
|
|
+ <el-form-item label=" " prop="amount">
|
|
|
+ <el-input-number
|
|
|
+ onmousewheel="return false;"
|
|
|
+ v-model="formData.followData.amount"
|
|
|
+ placeholder="请输入"
|
|
|
+ style="width: 100%"
|
|
|
+ :precision="2"
|
|
|
+ :controls="false"
|
|
|
+ :min="0"
|
|
|
+ :disabled="isDetail"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <div style="width: 100%">
|
|
|
+ <TitleInfo
|
|
|
+ content="程序文件"
|
|
|
+ style="margin: 20px 0 20px 0"
|
|
|
+ ></TitleInfo>
|
|
|
+ <el-upload
|
|
|
+ v-model:fileList="formData.followData.fileListOne"
|
|
|
+ action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
+ :data="uploadData"
|
|
|
+ multiple
|
|
|
+ :before-upload="handleBeforeUpload"
|
|
|
+ :on-success="handleSuccess"
|
|
|
+ :on-preview="onPreviewFile"
|
|
|
+ >
|
|
|
+ <el-button type="primary" plain disabled>选择</el-button>
|
|
|
+ </el-upload>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<template #footer>
|
|
|
<el-button @click="openFollow = false" size="large">取 消</el-button>
|
|
|
<el-button
|
|
@@ -321,6 +398,7 @@ const formData = reactive({
|
|
|
afterSalesDetailList: [],
|
|
|
},
|
|
|
followData: {},
|
|
|
+ detailData: {},
|
|
|
});
|
|
|
const formOption = reactive({
|
|
|
inline: true,
|
|
@@ -418,9 +496,13 @@ const formConfig = computed(() => {
|
|
|
},
|
|
|
];
|
|
|
});
|
|
|
-const formConfigAFollow = computed(() => {
|
|
|
+const formConfigDetail = computed(() => {
|
|
|
return [
|
|
|
{
|
|
|
+ type: "slot",
|
|
|
+ slotName: "title1",
|
|
|
+ },
|
|
|
+ {
|
|
|
type: "input",
|
|
|
itemType: "text",
|
|
|
label: "售后编码",
|
|
@@ -454,17 +536,91 @@ const formConfigAFollow = computed(() => {
|
|
|
},
|
|
|
{
|
|
|
type: "slot",
|
|
|
+ slotName: "title2",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "select",
|
|
|
+ prop: "type",
|
|
|
+ label: "售后类型",
|
|
|
+ required: true,
|
|
|
+ itemWidth: 100,
|
|
|
+ // multiple: true,
|
|
|
+ data: afterSalesType.value,
|
|
|
+ style: {
|
|
|
+ width: "100%",
|
|
|
+ },
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "input",
|
|
|
+ itemType: "textarea",
|
|
|
+ prop: "remark",
|
|
|
+ label: "售后说明",
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "input",
|
|
|
+ itemType: "text",
|
|
|
+ prop: "contactName",
|
|
|
+ label: "客户联系人",
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "input",
|
|
|
+ itemType: "text",
|
|
|
+ prop: "contactInfo",
|
|
|
+ label: "客户联系方式",
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "select",
|
|
|
+ prop: "afterSalesPersonId",
|
|
|
+ label: "售后人员",
|
|
|
+ itemWidth: 100,
|
|
|
+ // multiple: true,
|
|
|
+ filterable: true,
|
|
|
+ data: userList.value,
|
|
|
+ style: {
|
|
|
+ width: "100%",
|
|
|
+ },
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "slot",
|
|
|
+ slotName: "file",
|
|
|
+ label: "售后附件",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+});
|
|
|
+const formConfigFollow = computed(() => {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ type: "slot",
|
|
|
slotName: "listSlot",
|
|
|
},
|
|
|
{
|
|
|
type: "slot",
|
|
|
+ slotName: "title1",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "input",
|
|
|
+ itemType: "textarea",
|
|
|
+ prop: "remark",
|
|
|
+ label: "",
|
|
|
+ disabled: false,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "slot",
|
|
|
slotName: "fileSlot",
|
|
|
},
|
|
|
];
|
|
|
});
|
|
|
|
|
|
const followRules = ref({
|
|
|
- remark: [{ required: true, message: "请输入售后说明", trigger: "blur" }],
|
|
|
+ afterSalesRemark: [
|
|
|
+ { required: true, message: "请输入其他问题", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ amount: [{ required: true, message: "请输入售后金额", trigger: "blur" }],
|
|
|
});
|
|
|
const formDom = ref(null);
|
|
|
const followDom = ref(null);
|
|
@@ -511,44 +667,66 @@ const submitForm = () => {
|
|
|
};
|
|
|
|
|
|
const submitFollow = () => {
|
|
|
- followDom.value.handleSubmit(() => {
|
|
|
- let arr = Object.values(submitData.value);
|
|
|
- for (let i = 0; i < arr.length; i++) {
|
|
|
- const e = arr[i];
|
|
|
- if (e.fileList.length == 0) {
|
|
|
- return ElMessage({
|
|
|
- message: `第${i + 1}个配件没传现场照片`,
|
|
|
- type: "info",
|
|
|
- });
|
|
|
+ followDom.value.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ let arr = Object.values(submitData.value);
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ const e = arr[i];
|
|
|
+ if (e.quantity || e.remark.trim() || e.fileList.length > 0) {
|
|
|
+ if (!e.quantity) {
|
|
|
+ return ElMessage({
|
|
|
+ message: `请填写${e.productName}配件的售后数量`,
|
|
|
+ type: "info",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!e.remark.trim()) {
|
|
|
+ return ElMessage({
|
|
|
+ message: `请填写${e.productName}配件的售后说明`,
|
|
|
+ type: "info",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (e.fileList.length == 0) {
|
|
|
+ return ElMessage({
|
|
|
+ message: `请上传${e.productName}配件的现场照片`,
|
|
|
+ type: "info",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- if (!e.remark.trim()) {
|
|
|
+
|
|
|
+ if (!(Number(formData.data.amount) > 0)) {
|
|
|
return ElMessage({
|
|
|
- message: `第${i + 1}个配件没填售后说明`,
|
|
|
+ message: `售后金额需大于0`,
|
|
|
type: "info",
|
|
|
});
|
|
|
}
|
|
|
- e.fileList = e.fileList.map((x) => x.raw);
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ const e = arr[i];
|
|
|
+ e.fileList = e.fileList.map((x) => x.raw);
|
|
|
+ }
|
|
|
+ submitLoading.value = true;
|
|
|
+ proxy
|
|
|
+ .post("/afterSalesRecord/afterSales", {
|
|
|
+ id: formData.followData.id,
|
|
|
+ afterSalesRemark: formData.followData.afterSalesRemark,
|
|
|
+ amount: formData.followData.amount,
|
|
|
+ afterSalesRecordDetailList: arr,
|
|
|
+ })
|
|
|
+ .then(
|
|
|
+ (res) => {
|
|
|
+ ElMessage({
|
|
|
+ message: "操作成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ openFollow.value = false;
|
|
|
+ submitLoading.value = false;
|
|
|
+ getList();
|
|
|
+ },
|
|
|
+ (err) => {
|
|
|
+ submitLoading.value = false;
|
|
|
+ }
|
|
|
+ );
|
|
|
}
|
|
|
- submitLoading.value = true;
|
|
|
- proxy
|
|
|
- .post("/afterSalesRecord/afterSales", {
|
|
|
- id: formData.followData.id,
|
|
|
- afterSalesRecordDetailList: arr,
|
|
|
- })
|
|
|
- .then(
|
|
|
- (res) => {
|
|
|
- ElMessage({
|
|
|
- message: "操作成功",
|
|
|
- type: "success",
|
|
|
- });
|
|
|
- openFollow.value = false;
|
|
|
- submitLoading.value = false;
|
|
|
- getList();
|
|
|
- },
|
|
|
- (err) => {
|
|
|
- submitLoading.value = false;
|
|
|
- }
|
|
|
- );
|
|
|
});
|
|
|
};
|
|
|
|
|
@@ -590,11 +768,29 @@ const isDetail = ref(false);
|
|
|
const handleFollow = (row) => {
|
|
|
isDetail.value = row.status == 0 ? false : true;
|
|
|
proxy.post("/afterSalesRecord/detail", { id: row.id }).then(async (res) => {
|
|
|
+ // 左侧售后信息
|
|
|
+ formData.detailData = res;
|
|
|
+ proxy
|
|
|
+ .post("/fileInfo/getList", {
|
|
|
+ businessIdList: [row.id],
|
|
|
+ })
|
|
|
+ .then((fileObj) => {
|
|
|
+ if (fileObj && fileObj[row.id]) {
|
|
|
+ formData.detailData.fileList = fileObj[row.id].map((x) => ({
|
|
|
+ raw: x,
|
|
|
+ name: x.fileName,
|
|
|
+ url: x.fileUrl,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 右侧跟进
|
|
|
if (row.status == 0) {
|
|
|
for (let i = 0; i < res.bomDetailList.length; i++) {
|
|
|
const e = res.bomDetailList[i];
|
|
|
submitData.value[e.productId] = {
|
|
|
accessoriesId: e.productId,
|
|
|
+ productName: e.productName,
|
|
|
+ quantity: null,
|
|
|
remark: "",
|
|
|
fileList: [],
|
|
|
};
|
|
@@ -608,6 +804,8 @@ const handleFollow = (row) => {
|
|
|
const e = res.bomDetailList[i];
|
|
|
submitData.value[e.productId] = {
|
|
|
accessoriesId: e.productId,
|
|
|
+ productName: e.productName,
|
|
|
+ quantity: e.afterSalesRecordDetail.quantity,
|
|
|
remark: e.afterSalesRecordDetail.remark,
|
|
|
fileList: [],
|
|
|
};
|
|
@@ -638,11 +836,13 @@ const handleFollow = (row) => {
|
|
|
proxy
|
|
|
.post("/fileInfo/getList", { businessIdList: [res.bomInfoId] })
|
|
|
.then((fileObj) => {
|
|
|
- formData.followData.fileList = fileObj[res.bomInfoId].map((item) => ({
|
|
|
- raw: item,
|
|
|
- name: item.fileName,
|
|
|
- url: item.fileUrl,
|
|
|
- }));
|
|
|
+ formData.followData.fileListOne = fileObj[res.bomInfoId].map(
|
|
|
+ (item) => ({
|
|
|
+ raw: item,
|
|
|
+ name: item.fileName,
|
|
|
+ url: item.fileUrl,
|
|
|
+ })
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
});
|
|
@@ -692,4 +892,7 @@ const onPreviewFile = (file) => {
|
|
|
display: block;
|
|
|
}
|
|
|
}
|
|
|
+::v-deep(.el-input-number .el-input__inner) {
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
</style>
|