|
@@ -24,7 +24,7 @@
|
|
|
<template #address="{ item }">
|
|
|
<div>
|
|
|
{{ item.countryName }}, {{ item.provinceName }} ,
|
|
|
- {{ item.cityName }}, {{ item.areaDetail }}
|
|
|
+ {{ item.cityName }}, {{ item.detailedAddress }}
|
|
|
</div>
|
|
|
</template>
|
|
|
</byTable>
|
|
@@ -43,7 +43,7 @@
|
|
|
ref="byform"
|
|
|
>
|
|
|
<template #address>
|
|
|
- <el-row :gutter="10" style="width: 100%">
|
|
|
+ <el-row style="width: 100%">
|
|
|
<el-col :span="8">
|
|
|
<el-form-item prop="countryId">
|
|
|
<el-select
|
|
@@ -91,8 +91,11 @@
|
|
|
</el-row>
|
|
|
<el-row style="margin-top: 20px; width: 100%">
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item prop="areaDetail">
|
|
|
- <el-input v-model="formData.data.areaDetail" type="textarea">
|
|
|
+ <el-form-item prop="detailedAddress">
|
|
|
+ <el-input
|
|
|
+ v-model="formData.data.detailedAddress"
|
|
|
+ type="textarea"
|
|
|
+ >
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
@@ -105,27 +108,39 @@
|
|
|
@click="openProduct = true"
|
|
|
style="margin-bottom: 10px"
|
|
|
>
|
|
|
- 添加产品
|
|
|
+ 添加
|
|
|
</el-button>
|
|
|
- <el-table :data="formData.data.stockWaitDetailsList">
|
|
|
- <el-table-column prop="name" label="产品名称" />
|
|
|
- <el-table-column prop="name" label="可拆分数量" />
|
|
|
- <el-table-column prop="quantity" label="本次拆分" min-width="150">
|
|
|
+ <el-table :data="formData.data.afterSaleDetailList">
|
|
|
+ <el-table-column prop="productCode" label="商品编码" />
|
|
|
+ <el-table-column prop="productName" label="商品名称" />
|
|
|
+ <el-table-column prop="productSpec" label="规格型号" />
|
|
|
+ <el-table-column prop="quantity" label="数量" min-width="150">
|
|
|
<template #default="{ row, $index }">
|
|
|
<el-form-item
|
|
|
- :prop="'stockWaitDetailsList.' + $index + '.quantity'"
|
|
|
+ :prop="'afterSaleDetailList.' + $index + '.quantity'"
|
|
|
:rules="rules.quantity"
|
|
|
:inline-message="true"
|
|
|
>
|
|
|
<el-input-number
|
|
|
v-model="row.quantity"
|
|
|
- :precision="4"
|
|
|
+ :precision="2"
|
|
|
:controls="false"
|
|
|
:min="0"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column prop="remark" label="备注" min-width="150">
|
|
|
+ <template #default="{ row, $index }">
|
|
|
+ <el-form-item
|
|
|
+ :prop="'afterSaleDetailList.' + $index + '.remark'"
|
|
|
+ :rules="rules.remark"
|
|
|
+ :inline-message="true"
|
|
|
+ >
|
|
|
+ <el-input v-model="row.remark" placeholder="请输入" />
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="zip" label="操作" width="100">
|
|
|
<template #default="{ $index }">
|
|
|
<el-button type="primary" link @click="handleRemove($index)"
|
|
@@ -136,6 +151,7 @@
|
|
|
</el-table>
|
|
|
</div>
|
|
|
</template>
|
|
|
+
|
|
|
<template #fileSlot>
|
|
|
<div>
|
|
|
<el-upload
|
|
@@ -145,7 +161,6 @@
|
|
|
action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
|
|
|
:data="uploadData"
|
|
|
:on-preview="handlePreview"
|
|
|
- :on-remove="handleRemove"
|
|
|
:on-success="handleSuccess"
|
|
|
:before-upload="handleBeforeUpload"
|
|
|
>
|
|
@@ -180,9 +195,9 @@
|
|
|
</el-button>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
- <!-- <el-dialog
|
|
|
+ <el-dialog
|
|
|
v-model="openProduct"
|
|
|
- title="选择产品"
|
|
|
+ title="选择商品"
|
|
|
width="70%"
|
|
|
append-to-body
|
|
|
>
|
|
@@ -192,17 +207,17 @@
|
|
|
<el-button @click="openProduct = false">取消</el-button>
|
|
|
</span>
|
|
|
</template>
|
|
|
- </el-dialog> -->
|
|
|
+ </el-dialog>
|
|
|
|
|
|
<el-dialog
|
|
|
v-model="dialogVisibleOne"
|
|
|
title="跟进记录"
|
|
|
- width="70%"
|
|
|
+ width="500"
|
|
|
append-to-body
|
|
|
>
|
|
|
<div style="padding-left: 40px; margin-bottom: 20px">
|
|
|
<el-button size="mini" @click="openModal('edit')">
|
|
|
- 添加物流记录
|
|
|
+ 添加跟进记录
|
|
|
</el-button>
|
|
|
</div>
|
|
|
<div>
|
|
@@ -215,9 +230,11 @@
|
|
|
>
|
|
|
<div>
|
|
|
跟进人:{{ activity.handleUserName }}
|
|
|
- <span>({{ activity.status ? "已完成" : "处理中" }})</span>
|
|
|
+ <span
|
|
|
+ >({{ dictDataEcho(activity.status, afterSalesStatus) }})</span
|
|
|
+ >
|
|
|
</div>
|
|
|
- <div style="margin-top: 5px">跟进记录: {{ activity.explain }}</div>
|
|
|
+ <div style="margin-top: 5px">跟进记录: {{ activity.remark }}</div>
|
|
|
</el-timeline-item>
|
|
|
</el-timeline>
|
|
|
</div>
|
|
@@ -234,6 +251,7 @@ import FileUpload from "@/components/FileUpload/index";
|
|
|
import { computed, defineComponent, ref } from "vue";
|
|
|
import { getToken } from "@/utils/auth";
|
|
|
import SelectProduct from "@/components/WDLY/product/SelectProduct";
|
|
|
+import useUserStore from "@/store/modules/user";
|
|
|
|
|
|
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload"); // 上传文件服务器地址
|
|
|
const headers = ref({ Authorization: "Bearer " + getToken() });
|
|
@@ -268,47 +286,43 @@ const checkContactNumber = (rule, val, callback) => {
|
|
|
// @input="(val) => val.replace(/[^\d]/g, '')"
|
|
|
};
|
|
|
let rules = ref({
|
|
|
- name: [{ required: true, message: "请输入供应商名称", trigger: "blur" }],
|
|
|
- type: [{ required: true, message: "请选择供应商类型", trigger: "change" }],
|
|
|
+ customerId: [
|
|
|
+ { required: true, message: "请选择客户名称", trigger: "change" },
|
|
|
+ ],
|
|
|
+ type: [{ required: true, message: "请选择售后类型", trigger: "change" }],
|
|
|
countryId: [{ required: true, message: "请选择国家", trigger: "change" }],
|
|
|
provinceId: [{ required: true, message: "请选择省/洲", trigger: "change" }],
|
|
|
cityId: [{ required: true, message: "请选择城市", trigger: "change" }],
|
|
|
- areaDetail: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
|
|
|
+ detailedAddress: [
|
|
|
+ { required: true, message: "请输入详细地址", trigger: "blur" },
|
|
|
+ ],
|
|
|
contactPerson: [{ required: true, message: "请输入联系人", trigger: "blur" }],
|
|
|
- // contactNumber: [{ validator: checkContactNumber, trigger: "blur" }],
|
|
|
contactNumber: [
|
|
|
{ required: true, message: "请输入联系电话", trigger: "blur" },
|
|
|
],
|
|
|
+ cause: [{ required: true, message: "请输入售后原因", trigger: "blur" }],
|
|
|
+ quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
|
|
|
+ remark: [{ required: true, message: "请输入备注", trigger: "blur" }],
|
|
|
+
|
|
|
+ status: [{ required: true, message: "请选择售后状态", trigger: "change" }],
|
|
|
+ handleTime: [
|
|
|
+ { required: true, message: "请选择跟进时间", trigger: "change" },
|
|
|
+ ],
|
|
|
+ handleUserId: [
|
|
|
+ { required: true, message: "请选择跟进人", trigger: "change" },
|
|
|
+ ],
|
|
|
});
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
const selectConfig = reactive([
|
|
|
{
|
|
|
label: "售后类型",
|
|
|
prop: "type",
|
|
|
- data: [
|
|
|
- {
|
|
|
- label: "贸易商",
|
|
|
- value: "1",
|
|
|
- },
|
|
|
- {
|
|
|
- label: "工厂",
|
|
|
- value: "2",
|
|
|
- },
|
|
|
- ],
|
|
|
+ data: [],
|
|
|
},
|
|
|
{
|
|
|
label: "售后状态",
|
|
|
- prop: "accountPeriodType",
|
|
|
- data: [
|
|
|
- {
|
|
|
- label: "有",
|
|
|
- value: "1",
|
|
|
- },
|
|
|
- {
|
|
|
- label: "无",
|
|
|
- value: "0",
|
|
|
- },
|
|
|
- ],
|
|
|
+ prop: "status",
|
|
|
+ data: [],
|
|
|
},
|
|
|
]);
|
|
|
const config = computed(() => {
|
|
@@ -319,39 +333,41 @@ const config = computed(() => {
|
|
|
prop: "type",
|
|
|
},
|
|
|
render(type) {
|
|
|
- return type === 1 ? "贸易商" : "工厂";
|
|
|
+ return proxy.dictDataEcho(type, afterSalesType.value);
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
attrs: {
|
|
|
label: "客户名称",
|
|
|
- prop: "name",
|
|
|
+ prop: "customerName",
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
attrs: {
|
|
|
label: "售后时间",
|
|
|
- prop: "name",
|
|
|
+ prop: "createTime",
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
attrs: {
|
|
|
label: "所在城市",
|
|
|
- prop: "remarks",
|
|
|
slot: "address",
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
attrs: {
|
|
|
label: "售后原因",
|
|
|
- prop: "name",
|
|
|
+ prop: "cause",
|
|
|
},
|
|
|
},
|
|
|
|
|
|
{
|
|
|
attrs: {
|
|
|
label: "售后状态",
|
|
|
- prop: "returnPeriod",
|
|
|
+ prop: "status",
|
|
|
+ },
|
|
|
+ render(type) {
|
|
|
+ return proxy.dictDataEcho(type, afterSalesStatus.value);
|
|
|
},
|
|
|
},
|
|
|
|
|
@@ -397,17 +413,29 @@ const configData = [
|
|
|
[
|
|
|
{
|
|
|
type: "select",
|
|
|
- prop: "name",
|
|
|
+ prop: "type",
|
|
|
label: "售后类型",
|
|
|
required: true,
|
|
|
itemWidth: 51,
|
|
|
+ data: [],
|
|
|
},
|
|
|
{
|
|
|
type: "select",
|
|
|
- prop: "name",
|
|
|
+ prop: "customerId",
|
|
|
label: "客户名称",
|
|
|
required: true,
|
|
|
itemWidth: 51,
|
|
|
+ isLoad: {
|
|
|
+ url: "/customer/page",
|
|
|
+ req: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 9999,
|
|
|
+ },
|
|
|
+ labelKey: "name",
|
|
|
+ labelVal: "id",
|
|
|
+ method: "post",
|
|
|
+ resUrl: "rows",
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
type: "slot",
|
|
@@ -419,7 +447,7 @@ const configData = [
|
|
|
{
|
|
|
type: "input",
|
|
|
label: "售后原因",
|
|
|
- prop: "remark",
|
|
|
+ prop: "cause",
|
|
|
itemType: "textarea",
|
|
|
},
|
|
|
{
|
|
@@ -431,32 +459,50 @@ const configData = [
|
|
|
[
|
|
|
{
|
|
|
type: "select",
|
|
|
- prop: "name",
|
|
|
+ prop: "status",
|
|
|
label: "售后状态",
|
|
|
required: true,
|
|
|
itemWidth: 51,
|
|
|
},
|
|
|
{
|
|
|
type: "select",
|
|
|
- prop: "name",
|
|
|
+ prop: "handleUserId",
|
|
|
label: "跟进人",
|
|
|
required: true,
|
|
|
itemWidth: 50,
|
|
|
+ isLoad: {
|
|
|
+ url: `/tenantUser/list?pageNum=1&pageSize=9999&tenantId=${
|
|
|
+ useUserStore().user.tenantId
|
|
|
+ }`,
|
|
|
+ labelKey: "nickName",
|
|
|
+ labelVal: "userId",
|
|
|
+ method: "get",
|
|
|
+ resUrl: "rows",
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
type: "date",
|
|
|
- prop: "name",
|
|
|
- itemType: "date",
|
|
|
+ prop: "handleTime",
|
|
|
+ itemType: "datetime",
|
|
|
label: "跟进时间",
|
|
|
required: true,
|
|
|
itemWidth: 50,
|
|
|
},
|
|
|
{
|
|
|
type: "select",
|
|
|
- prop: "name",
|
|
|
+ prop: "nextUserId",
|
|
|
label: "下一跟进人",
|
|
|
required: true,
|
|
|
itemWidth: 51,
|
|
|
+ isLoad: {
|
|
|
+ url: `/tenantUser/list?pageNum=1&pageSize=9999&tenantId=${
|
|
|
+ useUserStore().user.tenantId
|
|
|
+ }`,
|
|
|
+ labelKey: "nickName",
|
|
|
+ labelVal: "userId",
|
|
|
+ method: "get",
|
|
|
+ resUrl: "rows",
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
type: "input",
|
|
@@ -476,13 +522,10 @@ const getList = async (req) => {
|
|
|
sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
|
|
|
loading.value = true;
|
|
|
proxy
|
|
|
- .post("/supplierInfo/pageByWdly", sourceList.value.pagination)
|
|
|
+ .post("/afterSaleRecord/page", sourceList.value.pagination)
|
|
|
.then((message) => {
|
|
|
console.log(message);
|
|
|
- sourceList.value.data = message.rows.map((x) => ({
|
|
|
- ...x,
|
|
|
- ...JSON.parse(x.victoriatouristJson),
|
|
|
- }));
|
|
|
+ sourceList.value.data = message.rows;
|
|
|
sourceList.value.pagination.total = message.total;
|
|
|
setTimeout(() => {
|
|
|
loading.value = false;
|
|
@@ -494,37 +537,80 @@ const openModal = (type, row = {}) => {
|
|
|
if (type == "add") {
|
|
|
formConfig = configData[0];
|
|
|
formData.data = {
|
|
|
- type: "1",
|
|
|
countryId: "China",
|
|
|
+ afterSaleDetailList: [],
|
|
|
};
|
|
|
getCityData(formData.data.countryId, "20");
|
|
|
} else if (type == "edit") {
|
|
|
formConfig = configData[1];
|
|
|
+ formData.data = {
|
|
|
+ afterSaleRecordId: "",
|
|
|
+ };
|
|
|
+ fileList.value = [];
|
|
|
+ fileListCopy.value = [];
|
|
|
}
|
|
|
dialogVisible.value = true;
|
|
|
};
|
|
|
-
|
|
|
+const rowData = ref({});
|
|
|
const openModalOne = (row) => {
|
|
|
- dialogVisibleOne.value = true;
|
|
|
+ rowData.value = { ...row };
|
|
|
+ getRecordList();
|
|
|
};
|
|
|
|
|
|
+const getRecordList = () => {
|
|
|
+ proxy
|
|
|
+ .post("/afterSaleHandle/page", { afterSaleRecordId: rowData.value.id })
|
|
|
+ .then((res) => {
|
|
|
+ activities.value = res.rows;
|
|
|
+ dialogVisibleOne.value = true;
|
|
|
+ });
|
|
|
+};
|
|
|
const submitForm = () => {
|
|
|
byform.value.handleSubmit((valid) => {
|
|
|
- formData.data.fileList =
|
|
|
- fileListCopy.value.map((x) => ({
|
|
|
- id: x.id,
|
|
|
- fileName: x.fileName,
|
|
|
- })) || [];
|
|
|
+ if (modalType.value == "add") {
|
|
|
+ const list = formData.data.afterSaleDetailList;
|
|
|
+ if (!list.length > 0)
|
|
|
+ return ElMessage({
|
|
|
+ message: `请关联商品!`,
|
|
|
+ type: "info",
|
|
|
+ });
|
|
|
+ for (let i = 0; i < list.length; i++) {
|
|
|
+ const e = list[i];
|
|
|
+ if (e.quantity == 0) {
|
|
|
+ return ElMessage({
|
|
|
+ message: `数量不能为0!`,
|
|
|
+ type: "info",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ formData.data.fileList =
|
|
|
+ fileListCopy.value.map((x) => ({
|
|
|
+ id: x.id,
|
|
|
+ fileName: x.fileName,
|
|
|
+ })) || [];
|
|
|
+ formData.data.afterSaleRecordId = rowData.value.id;
|
|
|
+ }
|
|
|
+ const requestUrl =
|
|
|
+ modalType.value == "add"
|
|
|
+ ? "/afterSaleRecord/add"
|
|
|
+ : "/afterSaleHandle/add";
|
|
|
submitLoading.value = true;
|
|
|
- proxy.post("/supplierInfo/" + modalType.value, formData.data).then(
|
|
|
+ proxy.post(requestUrl, formData.data).then(
|
|
|
(res) => {
|
|
|
ElMessage({
|
|
|
- message: modalType.value == "add" ? "添加成功" : "编辑成功",
|
|
|
+ message: "添加成功",
|
|
|
type: "success",
|
|
|
});
|
|
|
fileList.value = [];
|
|
|
+ fileListCopy.value = [];
|
|
|
dialogVisible.value = false;
|
|
|
submitLoading.value = false;
|
|
|
+ if (modalType.value == "add") {
|
|
|
+ getList();
|
|
|
+ } else {
|
|
|
+ getRecordList();
|
|
|
+ }
|
|
|
getList();
|
|
|
},
|
|
|
(err) => {
|
|
@@ -610,16 +696,21 @@ const getCityData = (id, type, isChange) => {
|
|
|
});
|
|
|
};
|
|
|
const handleSelect = (row) => {
|
|
|
- const flag = formData.data.stockWaitDetailsList.some((x) => x.id === row.id);
|
|
|
+ const flag = formData.data.afterSaleDetailList.some(
|
|
|
+ (x) => x.productId === row.id
|
|
|
+ );
|
|
|
if (flag)
|
|
|
return ElMessage({
|
|
|
- message: "该物品已选择",
|
|
|
+ message: "该商品已选择",
|
|
|
type: "info",
|
|
|
});
|
|
|
- formData.data.stockWaitDetailsList.push({
|
|
|
- name: row.name,
|
|
|
- code: row.code,
|
|
|
- id: row.id,
|
|
|
+ formData.data.afterSaleDetailList.push({
|
|
|
+ productName: row.name,
|
|
|
+ productCode: row.code,
|
|
|
+ productSpec: row.spec,
|
|
|
+ productId: row.id,
|
|
|
+ quantity: null,
|
|
|
+ remark: "",
|
|
|
});
|
|
|
return ElMessage({
|
|
|
message: "选择成功",
|
|
@@ -628,15 +719,40 @@ const handleSelect = (row) => {
|
|
|
};
|
|
|
|
|
|
const handleRemove = (index) => {
|
|
|
- formData.data.stockWaitDetailsList.splice(index, 1);
|
|
|
+ formData.data.afterSaleDetailList.splice(index, 1);
|
|
|
return ElMessage({
|
|
|
message: "删除成功",
|
|
|
type: "success",
|
|
|
});
|
|
|
};
|
|
|
+const afterSalesType = ref([]);
|
|
|
+const afterSalesStatus = ref([]);
|
|
|
|
|
|
+const getDict = () => {
|
|
|
+ proxy.getDict(["after_sale_type", "after_sale_status"]).then((res) => {
|
|
|
+ afterSalesType.value = res["after_sale_type"];
|
|
|
+ configData[0][0].data = afterSalesType.value.map((x) => ({
|
|
|
+ label: x.dictValue,
|
|
|
+ value: x.dictKey,
|
|
|
+ }));
|
|
|
+ selectConfig[0].data = afterSalesType.value.map((x) => ({
|
|
|
+ label: x.dictValue,
|
|
|
+ value: x.dictKey,
|
|
|
+ }));
|
|
|
+ afterSalesStatus.value = res["after_sale_status"];
|
|
|
+ configData[1][0].data = afterSalesStatus.value.map((x) => ({
|
|
|
+ label: x.dictValue,
|
|
|
+ value: x.dictKey,
|
|
|
+ }));
|
|
|
+ selectConfig[1].data = afterSalesStatus.value.map((x) => ({
|
|
|
+ label: x.dictValue,
|
|
|
+ value: x.dictKey,
|
|
|
+ }));
|
|
|
+ });
|
|
|
+};
|
|
|
getCityData("0");
|
|
|
getList();
|
|
|
+getDict();
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|