<template>
|
<div>
|
<el-dialog
|
v-model="dialogFormVisible"
|
title="新增售后单"
|
width="90%"
|
@close="closeDia"
|
>
|
<div>
|
<span class="descriptions">基础资料</span>
|
<el-form
|
:model="form"
|
label-width="140px"
|
label-position="top"
|
:rules="rules"
|
ref="formRef"
|
>
|
<el-row :gutter="30">
|
<el-col :span="4">
|
<el-form-item label="客户名称:" prop="customerName">
|
<el-select
|
v-model="form.customerName"
|
filterable
|
@change="customerNameChange"
|
>
|
<el-option
|
v-for="item in customerNameOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="4">
|
<el-form-item label="售后类型:" prop="serviceType">
|
<el-select
|
v-model="form.serviceType"
|
filterable
|
>
|
<el-option
|
v-for="dict in serviceTypeOptions"
|
:key="dict.value"
|
:label="dict.label"
|
:value="dict.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="4">
|
<el-form-item label="关联销售单号:" prop="salesContractNo">
|
<el-select
|
v-model="form.salesContractNo"
|
@change="associatedSalesOrderNumberChange"
|
filterable
|
>
|
<el-option
|
v-for="item in associatedSalesOrderNumberOptions"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="4">
|
<el-form-item label="紧急程度:" prop="urgency">
|
<el-select
|
v-model="form.urgency"
|
filterable
|
>
|
<el-option
|
v-for="dict in urgencyOptions"
|
:key="dict.value"
|
:label="dict.label"
|
:value="dict.value"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="4">
|
<el-form-item label="问题描述:" prop="disRes">
|
<el-input
|
v-model="form.disRes"
|
placeholder="请输入问题描述"
|
/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
<hr>
|
<div style="padding-top: 20px">
|
<div style="display: flex; justify-content: space-between">
|
<span class="descriptions">关联产品</span>
|
<el-button
|
type="primary"
|
style="margin-right: 12px; margin-bottom: 10px"
|
@click="isShowProductSelectDialog = true"
|
>
|
选择产品
|
</el-button>
|
</div>
|
<PIMTable
|
:isShowPagination="false"
|
rowKey="id"
|
:column="tableColumn"
|
:tableData="tableData"
|
>
|
<template #shippingStatus="{ row }">
|
<el-tag :type="getShippingStatusType(row)" size="small">
|
{{ getShippingStatusText(row) }}
|
</el-tag>
|
</template>
|
</PIMTable>
|
</div>
|
</div>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
<el-button @click="closeDia">取消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
<!-- 选择产品弹窗 -->
|
<ProductSelectDialog
|
v-model="isShowProductSelectDialog"
|
:products="currentSalesOrderProducts"
|
:selected-ids="currentSelectedProductIds"
|
@confirm="handleSelectProducts"
|
/>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, toRefs, getCurrentInstance, computed } from "vue";
|
import ProductSelectDialog from "./ProductSelectDialog.vue";
|
import useUserStore from "@/store/modules/user.js";
|
import {userListNoPageByTenantId} from "@/api/system/user.js";
|
import {afterSalesServiceAdd, afterSalesServiceUpdate, getAllCustomerList, getSalesLedger } from "@/api/customerService/index.js";
|
import { getCurrentDate } from "@/utils/index.js";
|
const { proxy } = getCurrentInstance()
|
const emit = defineEmits(['close'])
|
const dialogFormVisible = ref(false);
|
const operationType = ref('')
|
const formRef = ref(null)
|
const customerNameOptions = ref([])
|
const userStore = useUserStore();
|
|
const data = reactive({
|
form: {
|
topic: "",
|
serviceType: "",
|
urgency: "",
|
salesLedgerId: null,
|
productModelIds: "",
|
customerId: null,
|
salesContractNo: "",
|
disRes: "",
|
customerName: ""
|
},
|
rules: {
|
customerName: [{required: true, message: "请选择客户名称", trigger: "change"}],
|
serviceType: [{required: true, message: "请选择售后类型", trigger: "change"}],
|
urgency: [{required: true, message: "请选择紧急程度", trigger: "change"}],
|
feedbackDate: [{required: true, message: "请选择", trigger: "change"}],
|
}
|
})
|
|
// 自定义校验函数:判断是否需要校验售后编号
|
|
const { form, rules } = toRefs(data);
|
const userList = ref([])
|
|
const formatCurrency = (val) => {
|
if (val === null || val === undefined || val === '') return '-'
|
const num = Number(val)
|
return Number.isFinite(num) ? num.toFixed(2) : '-'
|
}
|
|
const { post_sale_waiting_list, degree_of_urgency } = proxy.useDict(
|
"post_sale_waiting_list",
|
"degree_of_urgency"
|
);
|
|
const serviceTypeOptions = computed(() => post_sale_waiting_list?.value || []);
|
const urgencyOptions = computed(() => degree_of_urgency?.value || []);
|
|
const tableColumn = ref([
|
{ label: "产品大类", prop: "productCategory" },
|
{ label: "规格型号", prop: "specificationModel" },
|
{ label: "单位", prop: "unit" },
|
{
|
label: "产品状态",
|
prop: "approveStatus",
|
width: 100,
|
align: "center",
|
dataType: "tag",
|
formatData: (v) => (v === 1 ? "充足" : "不足"),
|
formatType: (v) => (v === 1 ? "success" : "danger"),
|
},
|
{
|
label: "发货状态",
|
align: "center",
|
width: 140,
|
dataType: "slot",
|
slot: "shippingStatus",
|
},
|
{ label: "快递公司", prop: "expressCompany", width: 140 },
|
{ label: "快递单号", prop: "expressNumber", width: 160 },
|
{ label: "发货车牌", prop: "shippingCarNumber", minWidth: 100, align: "center" },
|
{ label: "发货日期", prop: "shippingDate", minWidth: 100, align: "center" },
|
{ label: "数量", prop: "quantity", width: 100 },
|
{ label: "税率(%)", prop: "taxRate", width: 100 },
|
{
|
label: "含税单价(元)",
|
prop: "taxInclusiveUnitPrice",
|
width: 160,
|
formatData: formatCurrency,
|
},
|
{
|
label: "含税总价(元)",
|
prop: "taxInclusiveTotalPrice",
|
width: 160,
|
formatData: formatCurrency,
|
},
|
{
|
label: "不含税总价(元)",
|
prop: "taxExclusiveTotalPrice",
|
width: 160,
|
formatData: formatCurrency,
|
},
|
{
|
dataType: "action",
|
label: "操作",
|
align: "center",
|
fixed: 'right',
|
operation: [
|
{
|
name: "删除",
|
type: "text",
|
clickFun: (row) => {
|
tableData.value = tableData.value.filter(i => i.id !== row.id)
|
},
|
|
},
|
],
|
},
|
])
|
const tableData = ref([])
|
// 选择产品弹窗
|
const isShowProductSelectDialog = ref(false)
|
const handleSelectProducts = (rows) => {
|
if (!Array.isArray(rows)) return
|
const existingIds = new Set(tableData.value.map(i => i.id))
|
const mapped = rows
|
.filter(r => !existingIds.has(r.id))
|
.map(r => ({
|
id: r.id,
|
productCategory: r.productName,
|
specificationModel: r.model,
|
unit: r.unit || '',
|
approveStatus: null,
|
shippingStatus: '',
|
expressCompany: '',
|
expressNumber: '',
|
shippingCarNumber: '',
|
shippingDate: '',
|
quantity: 0,
|
taxRate: 0,
|
taxInclusiveUnitPrice: 0,
|
taxInclusiveTotalPrice: 0,
|
taxExclusiveTotalPrice: 0,
|
}))
|
tableData.value = tableData.value.concat(mapped)
|
}
|
const currentSelectedProductIds = computed(() => {
|
return tableData.value.map(item => item.id)
|
})
|
|
const associatedSalesOrderNumberChange = () => {
|
const opt = associatedSalesOrderNumberOptions.value.find(
|
(item) => item.value === form.value.salesContractNo
|
)
|
tableData.value = opt?.productData || []
|
form.value.salesLedgerId = opt?.id || null
|
}
|
|
const associatedSalesOrderNumberOptions = ref([])
|
|
const currentSalesOrderProducts = computed(() => {
|
const opt = associatedSalesOrderNumberOptions.value.find(
|
(item) => item.value === form.value.salesContractNo
|
)
|
return opt?.productData || []
|
})
|
|
const customerNameChange = (val) => {
|
const opt = customerNameOptions.value.find(item => item.value === val);
|
if (opt) {
|
form.value.customerId = opt.id;
|
}
|
getSalesLedger({
|
customerName: form.value.customerName
|
}).then(res => {
|
if(res.code === 200){
|
associatedSalesOrderNumberOptions.value = res.data.records.map(item => ({
|
label: item.salesContractNo,
|
value: item.salesContractNo,
|
productData:item.productData,
|
id: item.id
|
}))
|
}
|
})
|
}
|
|
const getShippingStatusText = (row) => {
|
if (!row) return '待发货'
|
if (row.shippingDate || row.shippingCarNumber) {
|
return '已发货'
|
}
|
const status = row.shippingStatus
|
if (status === null || status === undefined || status === '') {
|
return '待发货'
|
}
|
const map = {
|
'待发货': '待发货',
|
'待审核': '待审核',
|
'审核中': '审核中',
|
'审核拒绝': '审核拒绝',
|
'审核通过': '审核通过',
|
'已发货': '已发货'
|
}
|
return map[String(status).trim()] || '待发货'
|
}
|
|
const getShippingStatusType = (row) => {
|
if (!row) return 'info'
|
if (row.shippingDate || row.shippingCarNumber) {
|
return 'success'
|
}
|
const status = row.shippingStatus
|
if (status === null || status === undefined || status === '') {
|
return 'info'
|
}
|
const map = {
|
'待发货': 'info',
|
'待审核': 'warning',
|
'审核中': 'warning',
|
'审核拒绝': 'danger',
|
'审核通过': 'success',
|
'已发货': 'success'
|
}
|
return map[String(status).trim()] || 'info'
|
}
|
|
// 打开弹框
|
const openDialog =async (type, row) => {
|
// 请求多个接口,获取数据
|
let res = await getAllCustomerList();
|
if(res.records){
|
customerNameOptions.value = res.records.map(item => ({
|
label: item.customerName,
|
value: item.customerName,
|
id: item.id
|
}));
|
}
|
|
|
operationType.value = type;
|
dialogFormVisible.value = true;
|
form.value = {}
|
proxy.resetForm("formRef");
|
form.value.checkUserId = userStore.id;
|
form.value.feedbackDate = getCurrentDate();
|
// 新增时清空已选关联产品
|
if (type === "add") {
|
tableData.value = []
|
}
|
userListNoPageByTenantId().then((res) => {
|
userList.value = res.data;
|
});
|
if (type === "edit") {
|
form.value = {...row}
|
if (form.value.customerName) {
|
const res = await getSalesLedger({ customerName: form.value.customerName })
|
if (res?.code === 200) {
|
console.log(res)
|
associatedSalesOrderNumberOptions.value = (res.data?.records || []).map(item => ({
|
label: item.salesContractNo,
|
value: item.salesContractNo,
|
productData: item.productData,
|
id: item.id
|
}))
|
}
|
}
|
console.log(form.value)
|
}
|
}
|
const submitForm = () => {
|
proxy.$refs["formRef"].validate(valid => {
|
if (valid) {
|
// 匹配产品型号IDs
|
form.value.productModelIds = tableData.value.map(item => item.id).join(",")
|
if (operationType.value === "add") {
|
afterSalesServiceAdd(form.value).then(response => {
|
proxy.$modal.msgSuccess("新增成功")
|
closeDia()
|
})
|
} else {
|
afterSalesServiceUpdate(form.value).then(response => {
|
proxy.$modal.msgSuccess("修改成功")
|
closeDia()
|
})
|
}
|
}
|
})
|
}
|
// 关闭弹框
|
const closeDia = () => {
|
proxy.resetForm("formRef");
|
dialogFormVisible.value = false;
|
emit('close')
|
};
|
defineExpose({
|
openDialog,
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.descriptions {
|
margin-bottom: 20px;
|
display: inline-block;
|
font-size: 1rem;
|
font-weight: 600;
|
padding-left: 12px;
|
position: relative;
|
}
|
|
.descriptions::before {
|
content: "";
|
position: absolute;
|
left: 0;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 4px;
|
height: 1rem;
|
background-color: #002FA7; /* Element 默认红色 */
|
border-radius: 2px;
|
}
|
</style>
|