| | |
| | | params: query, |
| | | }) |
| | | } |
| | | |
| | | // å®åå详æ
|
| | | export function getAfterSalesServiceById(id) { |
| | | return request({ |
| | | url: '/afterSalesService/getById', |
| | | method: 'get', |
| | | params: { id } |
| | | }) |
| | | } |
| | |
| | | ></PIMTable> |
| | | </div> |
| | | <form-dia ref="formDia" @close="handleQuery"></form-dia> |
| | | <view-dia ref="viewDia"></view-dia> |
| | | <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="after_sales_service" :record-id="recordId" /> |
| | | </div> |
| | | </template> |
| | |
| | | <script setup> |
| | | import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, defineAsyncComponent} from "vue"; |
| | | import FormDia from "@/views/customerService/afterSalesHandling/components/formDia.vue"; |
| | | import ViewDia from "@/views/customerService/components/viewDia.vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | afterSalesServiceListPage, |
| | |
| | | align: "center" |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | | prop: "productModelQuantities", |
| | | align: "center", |
| | | formatData: params => { |
| | | if (!params) return "0"; |
| | | return String(params).split(',').reduce((sum, val) => sum + (Number(val) || 0), 0); |
| | | } |
| | | }, |
| | | { |
| | | label: "é®é¢æè¿°", |
| | | prop: "proDesc", |
| | | width:300, |
| | |
| | | } |
| | | }, |
| | | { |
| | | name: "æ¥ç", |
| | | name: "详æ
", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | openForm("view", row); |
| | | viewDia.value?.openDialog(row); |
| | | }, |
| | | }, |
| | | // TODO ä¸ºåæ¥åæ·»å ç |
| | |
| | | selectedRows.value = selection; |
| | | }; |
| | | const formDia = ref() |
| | | const viewDia = ref() |
| | | const fileListRef = ref(null) |
| | | const fileListDialogVisible = ref(false) |
| | | const currentFileRow = ref(null) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="å®åå详æ
" width="80%" @close="closeDia"> |
| | | <div v-loading="loading"> |
| | | <span class="descriptions">åºç¡èµæ</span> |
| | | <el-descriptions :column="4" border style="margin-top: 10px;"> |
| | | <el-descriptions-item label="客æ·åç§°">{{ detail.customerName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å®åç±»å">{{ getDictLabel(classificationOptions, detail.serviceType) }}</el-descriptions-item> |
| | | <el-descriptions-item label="å
³èéå®åå·">{{ detail.salesContractNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="ç´§æ¥ç¨åº¦">{{ getDictLabel(degreeOfUrgencyOptions, detail.urgency) }}</el-descriptions-item> |
| | | <el-descriptions-item label="å·¥åç¼å·">{{ detail.afterSalesServiceNo || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¤çç¶æ"> |
| | | <el-tag :type="detail.status === 1 ? 'danger' : 'success'" size="small"> |
| | | {{ detail.status === 1 ? 'å¾
å¤ç' : 'å·²å¤ç' }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç»è®°äºº">{{ detail.checkNickName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å馿¥æ">{{ detail.feedbackDate || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="客æ·è¯æ±" :span="4">{{ detail.proDesc || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <div style="margin-top: 20px;"> |
| | | <span class="descriptions">å¤çä¿¡æ¯</span> |
| | | <el-descriptions :column="3" border style="margin-top: 10px;"> |
| | | <el-descriptions-item label="å¤ç人">{{ detail.disposeNickName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¤çæ¥æ">{{ detail.disDate || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¤çç»æ" :span="3">{{ detail.disRes || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | |
| | | <div style="margin-top: 20px;"> |
| | | <span class="descriptions">å
³è产å</span> |
| | | <el-table :data="tableData" border style="width: 100%; margin-top: 10px;"> |
| | | <el-table-column type="index" label="åºå·" width="60" align="center" /> |
| | | <el-table-column prop="productCategory" label="产å大类" align="center" /> |
| | | <el-table-column prop="specificationModel" label="è§æ ¼åå·" align="center" /> |
| | | <el-table-column prop="unit" label="åä½" align="center" /> |
| | | <el-table-column prop="expressCompany" label="å¿«éå
¬å¸" align="center" /> |
| | | <el-table-column prop="expressNumber" label="å¿«éåå·" align="center" /> |
| | | <el-table-column prop="shippingCarNumber" label="å货车ç" align="center" /> |
| | | <el-table-column prop="shippingDate" label="åè´§æ¥æ" align="center" /> |
| | | <el-table-column prop="quantity" label="å®åæ°é" align="center" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="closeDia">å
³é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance } from 'vue'; |
| | | import { getAfterSalesServiceById } from '@/api/customerService/index.js'; |
| | | |
| | | const { proxy } = getCurrentInstance(); |
| | | const dialogVisible = ref(false); |
| | | const loading = ref(false); |
| | | const detail = ref({}); |
| | | const tableData = ref([]); |
| | | |
| | | const { post_sale_waiting_list, degree_of_urgency } = proxy.useDict( |
| | | "post_sale_waiting_list", |
| | | "degree_of_urgency" |
| | | ); |
| | | const classificationOptions = computed(() => post_sale_waiting_list?.value || []); |
| | | const degreeOfUrgencyOptions = computed(() => degree_of_urgency?.value || []); |
| | | |
| | | const getDictLabel = (options, value) => { |
| | | if (!value) return '-'; |
| | | const item = options.find(i => String(i.value) === String(value)); |
| | | return item ? item.label : value; |
| | | }; |
| | | |
| | | const openDialog = (row) => { |
| | | dialogVisible.value = true; |
| | | loading.value = true; |
| | | detail.value = {}; |
| | | tableData.value = []; |
| | | |
| | | getAfterSalesServiceById(row.id).then(res => { |
| | | loading.value = false; |
| | | if (res.code === 200) { |
| | | detail.value = res.data || {}; |
| | | let productData = res.data?.salesLedgerDto?.productData || []; |
| | | const selectedIds = res.data.productModelIds ? String(res.data.productModelIds).split(",") : []; |
| | | tableData.value = productData.filter(item => selectedIds.includes(String(item.id))); |
| | | } |
| | | }).catch(() => { |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const closeDia = () => { |
| | | dialogVisible.value = false; |
| | | }; |
| | | |
| | | defineExpose({ |
| | | openDialog |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .descriptions { |
| | | 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; |
| | | border-radius: 2px; |
| | | } |
| | | </style> |
| | |
| | | {{ getShippingStatusText(row) }} |
| | | </el-tag> |
| | | </template> |
| | | <template #quantity="{ row }"> |
| | | <el-input-number v-model="row.quantity" :min="0" size="small" /> |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | </div> |
| | |
| | | salesContractNo: "", |
| | | proDesc: "", |
| | | customerName: "", |
| | | productModelQuantities: "", |
| | | }, |
| | | rules: { |
| | | customerName: [ |
| | |
| | | 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, |
| | | label: "æ°é", |
| | | prop: "quantity", |
| | | width: 140, |
| | | dataType: "slot", |
| | | slot: "quantity", |
| | | }, |
| | | { |
| | | dataType: "action", |
| | |
| | | id: item.id, |
| | | }) |
| | | ); |
| | | const opt = associatedSalesOrderNumberOptions.value.find( |
| | | item => item.value === form.value.salesContractNo |
| | | ); |
| | | if (opt) { |
| | | let restoredData = (opt.productData || []).map(normalizeProductRow); |
| | | const selectedIds = form.value.productModelIds ? String(form.value.productModelIds).split(",") : []; |
| | | const quantities = form.value.productModelQuantities ? String(form.value.productModelQuantities).split(",") : []; |
| | | tableData.value = restoredData.filter(item => selectedIds.includes(String(item.id))).map(item => { |
| | | let qIndex = selectedIds.indexOf(String(item.id)); |
| | | if (qIndex !== -1 && qIndex < quantities.length && quantities[qIndex] !== "") { |
| | | item.quantity = Number(quantities[qIndex]); |
| | | } |
| | | return item; |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | console.log(form.value); |
| | |
| | | form.value.productModelIds = tableData.value |
| | | .map(item => item.id) |
| | | .join(","); |
| | | form.value.productModelQuantities = tableData.value |
| | | .map(item => item.quantity || 0) |
| | | .join(","); |
| | | if (operationType.value === "add") { |
| | | afterSalesServiceAdd(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå"); |
| | |
| | | </div> |
| | | <form-dia ref="formDia" |
| | | @close="handleQuery"></form-dia> |
| | | <view-dia ref="viewDia"></view-dia> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | nextTick, |
| | | } from "vue"; |
| | | import FormDia from "@/views/customerService/feedbackRegistration/components/formDia.vue"; |
| | | import ViewDia from "@/views/customerService/components/viewDia.vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { |
| | | afterSalesServiceDelete, |
| | |
| | | align: "center", |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | | prop: "productModelQuantities", |
| | | align: "center", |
| | | formatData: params => { |
| | | if (!params) return "0"; |
| | | return String(params).split(',').reduce((sum, val) => sum + (Number(val) || 0), 0); |
| | | } |
| | | }, |
| | | { |
| | | label: "客æ·è¯æ±", |
| | | prop: "proDesc", |
| | | width: 300, |
| | |
| | | dataType: "action", |
| | | label: "æä½", |
| | | fixed: "right", |
| | | width: 180, |
| | | align: "center", |
| | | operation: [ |
| | | { |
| | | name: "详æ
", |
| | | type: "text", |
| | | clickFun: row => { |
| | | viewDia.value?.openDialog(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | |
| | | selectedRows.value = selection; |
| | | }; |
| | | const formDia = ref(); |
| | | const viewDia = ref(); |
| | | |
| | | // åå
¸è·å |
| | | /* |