feat: 完成 SN 溯源、销售管理和维修记录。
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@icon-park/vue-next": "^1.4.2",
|
"@icon-park/vue-next": "^1.4.2",
|
||||||
|
"@remixicon/vue": "^4.9.0",
|
||||||
"@vueuse/core": "^13.7.0",
|
"@vueuse/core": "^13.7.0",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"decimal.js": "^10.6.0",
|
"decimal.js": "^10.6.0",
|
||||||
|
|||||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
|||||||
'@icon-park/vue-next':
|
'@icon-park/vue-next':
|
||||||
specifier: ^1.4.2
|
specifier: ^1.4.2
|
||||||
version: 1.4.2(vue@3.5.18(typescript@5.9.2))
|
version: 1.4.2(vue@3.5.18(typescript@5.9.2))
|
||||||
|
'@remixicon/vue':
|
||||||
|
specifier: ^4.9.0
|
||||||
|
version: 4.9.0(vue@3.5.18(typescript@5.9.2))
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ^13.7.0
|
specifier: ^13.7.0
|
||||||
version: 13.7.0(vue@3.5.18(typescript@5.9.2))
|
version: 13.7.0(vue@3.5.18(typescript@5.9.2))
|
||||||
@@ -44,6 +47,9 @@ importers:
|
|||||||
qs:
|
qs:
|
||||||
specifier: ^6.14.0
|
specifier: ^6.14.0
|
||||||
version: 6.14.0
|
version: 6.14.0
|
||||||
|
remixicon:
|
||||||
|
specifier: ^4.9.1
|
||||||
|
version: 4.9.1
|
||||||
sortablejs:
|
sortablejs:
|
||||||
specifier: ^1.15.6
|
specifier: ^1.15.6
|
||||||
version: 1.15.6
|
version: 1.15.6
|
||||||
@@ -913,6 +919,11 @@ packages:
|
|||||||
'@polka/url@1.0.0-next.29':
|
'@polka/url@1.0.0-next.29':
|
||||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||||
|
|
||||||
|
'@remixicon/vue@4.9.0':
|
||||||
|
resolution: {integrity: sha512-4P0MY5ScL+MRLnHu1iT3xHAsliBwOGDIgSgHCZhSj2wkLa5NzqiQ4SGD/04VoHM+BRr8+xjmF7ZemkOUlMDJ3A==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: '>= 3'
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.26':
|
'@rolldown/pluginutils@1.0.0-beta.26':
|
||||||
resolution: {integrity: sha512-r/5po89voz/QRPDmoErL10+hVuTAuz1SHvokx+yWBlOIPB5C41jC7QhLqq9kaebx/+EHyoV3z22/qBfX81Ns8A==}
|
resolution: {integrity: sha512-r/5po89voz/QRPDmoErL10+hVuTAuz1SHvokx+yWBlOIPB5C41jC7QhLqq9kaebx/+EHyoV3z22/qBfX81Ns8A==}
|
||||||
|
|
||||||
@@ -4249,6 +4260,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==}
|
resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
remixicon@4.9.1:
|
||||||
|
resolution: {integrity: sha512-36gLSoujkabnCFZFDyP17VNh9piuBA/rsXUb4auSJWLGsHVXtmxLj/EM5FjaEAGnk8oIAj1Azob/DZ2N+90lAQ==}
|
||||||
|
|
||||||
repeat-element@1.1.4:
|
repeat-element@1.1.4:
|
||||||
resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==}
|
resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -6040,6 +6054,10 @@ snapshots:
|
|||||||
|
|
||||||
'@polka/url@1.0.0-next.29': {}
|
'@polka/url@1.0.0-next.29': {}
|
||||||
|
|
||||||
|
'@remixicon/vue@4.9.0(vue@3.5.18(typescript@5.9.2))':
|
||||||
|
dependencies:
|
||||||
|
vue: 3.5.18(typescript@5.9.2)
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.26': {}
|
'@rolldown/pluginutils@1.0.0-beta.26': {}
|
||||||
|
|
||||||
'@rolldown/pluginutils@1.0.0-beta.29': {}
|
'@rolldown/pluginutils@1.0.0-beta.29': {}
|
||||||
@@ -9657,6 +9675,8 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
set-function-name: 2.0.2
|
set-function-name: 2.0.2
|
||||||
|
|
||||||
|
remixicon@4.9.1: {}
|
||||||
|
|
||||||
repeat-element@1.1.4: {}
|
repeat-element@1.1.4: {}
|
||||||
|
|
||||||
repeat-string@1.6.1: {}
|
repeat-string@1.6.1: {}
|
||||||
|
|||||||
@@ -320,6 +320,7 @@ export default {
|
|||||||
customerName: "客户名称",
|
customerName: "客户名称",
|
||||||
customerId: "客户",
|
customerId: "客户",
|
||||||
partNumber: "物料编号",
|
partNumber: "物料编号",
|
||||||
|
productSpecs: "物料型号",
|
||||||
saleCount: "销售数量",
|
saleCount: "销售数量",
|
||||||
price: "单价",
|
price: "单价",
|
||||||
totalPrice: "总价",
|
totalPrice: "总价",
|
||||||
@@ -333,7 +334,7 @@ export default {
|
|||||||
serialNum: "序列号",
|
serialNum: "序列号",
|
||||||
productSn: "SN 号",
|
productSn: "SN 号",
|
||||||
repairMark: "返修记录",
|
repairMark: "返修记录",
|
||||||
outProductDate: "出货时间",
|
outProductDate: "出货日期",
|
||||||
productType: "型号",
|
productType: "型号",
|
||||||
mac: "MAC 地址",
|
mac: "MAC 地址",
|
||||||
alNum: "算法标志",
|
alNum: "算法标志",
|
||||||
@@ -354,6 +355,11 @@ export default {
|
|||||||
manufacturingDate: "生产日期",
|
manufacturingDate: "生产日期",
|
||||||
mark: "备注",
|
mark: "备注",
|
||||||
keyAccountId: "客户",
|
keyAccountId: "客户",
|
||||||
|
repairCount: "维修次数",
|
||||||
|
serialNum: "序列号",
|
||||||
|
softVersion: "软件版本",
|
||||||
|
alVersion: "算法版本",
|
||||||
|
createDate: "创建日期",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
systemset: {
|
systemset: {
|
||||||
@@ -456,6 +462,7 @@ export default {
|
|||||||
reject_success: "反审成功",
|
reject_success: "反审成功",
|
||||||
reject_fail: "反审失败",
|
reject_fail: "反审失败",
|
||||||
reject_cannel: "反审取消",
|
reject_cannel: "反审取消",
|
||||||
|
all_customers: "所有客户",
|
||||||
},
|
},
|
||||||
warehouse: {
|
warehouse: {
|
||||||
warehouse_item: {
|
warehouse_item: {
|
||||||
@@ -680,15 +687,6 @@ export default {
|
|||||||
input_productSn: "请输入SN号",
|
input_productSn: "请输入SN号",
|
||||||
input_mac: "请输入MAC地址",
|
input_mac: "请输入MAC地址",
|
||||||
},
|
},
|
||||||
repairrecord: {
|
|
||||||
input_productSn: "请输入SN号",
|
|
||||||
input_mac: "请输入MAC地址",
|
|
||||||
input_repairStatus: "请选择维修状态",
|
|
||||||
input_repairDate: "请输入维修日期",
|
|
||||||
input_manufacturingDate: "请输入生产日期",
|
|
||||||
input_mark: "请输入备注",
|
|
||||||
input_repairMark: "请输入返修记录",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
purchase: {
|
purchase: {
|
||||||
purchase_plan: {
|
purchase_plan: {
|
||||||
@@ -780,6 +778,24 @@ export default {
|
|||||||
import_fail: "导入失败",
|
import_fail: "导入失败",
|
||||||
delete_message: "删除销售订单",
|
delete_message: "删除销售订单",
|
||||||
},
|
},
|
||||||
|
repairrecord: {
|
||||||
|
input_productSn: "请输入SN号",
|
||||||
|
input_mac: "请输入MAC地址",
|
||||||
|
input_repairStatus: "请选择维修状态",
|
||||||
|
input_repairDate: "请输入维修日期",
|
||||||
|
input_manufacturingDate: "请输入生产日期",
|
||||||
|
input_mark: "请输入备注",
|
||||||
|
input_repairMark: "请输入返修记录",
|
||||||
|
input_repair_mark: "请输入返修记录",
|
||||||
|
input_identifier: "SN号、MAC地址、序列号至少填写一个",
|
||||||
|
delete_message: "删除维修记录",
|
||||||
|
identifier_tip: "提示:SN号、MAC地址、序列号三者至少填写一个",
|
||||||
|
input_productSn_optional: "SN号(选填)",
|
||||||
|
input_mac_optional: "MAC地址(选填)",
|
||||||
|
input_serialNum_optional: "序列号(选填)",
|
||||||
|
input_softVersion_optional: "软件版本(选填)",
|
||||||
|
input_alVersion_optional: "算法版本(选填)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
systemset: {
|
systemset: {
|
||||||
vendor: {
|
vendor: {
|
||||||
@@ -915,6 +931,13 @@ export default {
|
|||||||
saleorder: {
|
saleorder: {
|
||||||
add: "添加销售订单",
|
add: "添加销售订单",
|
||||||
edit: "编辑销售订单",
|
edit: "编辑销售订单",
|
||||||
|
showItem: "销售明细",
|
||||||
|
baseTitle: "销售订单基本信息",
|
||||||
|
tableTitle: "销售明细",
|
||||||
|
},
|
||||||
|
repairrecord: {
|
||||||
|
add: "添加维修记录",
|
||||||
|
edit: "编辑维修记录",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
systemset: {
|
systemset: {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
tableEl: ref,
|
tableEl: ref,
|
||||||
statusLabelMapping: Function,
|
statusLabelMapping: Function,
|
||||||
|
tagTypeMapping: Function,
|
||||||
statusParamName: {
|
statusParamName: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "status",
|
default: "status",
|
||||||
@@ -37,14 +38,26 @@ const getLabel = (code: number | null) => {
|
|||||||
if (props.statusLabelMapping === undefined) return getCommonStatusLabel(code);
|
if (props.statusLabelMapping === undefined) return getCommonStatusLabel(code);
|
||||||
return props.statusLabelMapping(code);
|
return props.statusLabelMapping(code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTagType = (code: number | null): string => {
|
||||||
|
if (props.tagTypeMapping !== undefined) {
|
||||||
|
return props.tagTypeMapping(code);
|
||||||
|
}
|
||||||
|
// 默认逻辑:switchOnValue 为 success,其他为 info
|
||||||
|
return code === props.switchOnValue ? "success" : "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-table-column :label="$t('_prop.common.status')" :prop="statusParamName">
|
<el-table-column :label="$t('_prop.common.status')" :prop="statusParamName">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
<!-- 没有权限按钮时,显示带框标签 -->
|
||||||
<span v-if="buttonList.length === 0">
|
<span v-if="buttonList.length === 0">
|
||||||
{{ getLabel(scope.row[statusParamName]) }}
|
<el-tag :type="getTagType(scope.row[statusParamName])" size="small">
|
||||||
|
{{ getLabel(scope.row[statusParamName]) }}
|
||||||
|
</el-tag>
|
||||||
</span>
|
</span>
|
||||||
<template v-for="button in buttonList" :key="button.buttonName">
|
<!-- 有权限按钮时,显示开关或标签 -->
|
||||||
|
<template v-else v-for="button in buttonList" :key="button.buttonName">
|
||||||
<StatusSwitch
|
<StatusSwitch
|
||||||
v-model="scope.row[statusParamName]"
|
v-model="scope.row[statusParamName]"
|
||||||
@change="val => change(val, scope.row)"
|
@change="val => change(val, scope.row)"
|
||||||
@@ -54,6 +67,21 @@ const getLabel = (code: number | null) => {
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- 有权限但没有匹配到开关时,显示带框标签 -->
|
||||||
|
<el-tag
|
||||||
|
v-if="
|
||||||
|
buttonList.length > 0 &&
|
||||||
|
!buttonList.some(
|
||||||
|
button =>
|
||||||
|
(button.eventName === 'enable' && scope.row[statusParamName] === switchOffValue) ||
|
||||||
|
(button.eventName === 'disable' && scope.row[statusParamName] === switchOnValue)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:type="getTagType(scope.row[statusParamName])"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
{{ getLabel(scope.row[statusParamName]) }}
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const dynamicRoutes: RouterConfigRaw[] = [
|
|||||||
component: "/systemset/vendor/form",
|
component: "/systemset/vendor/form",
|
||||||
meta: {
|
meta: {
|
||||||
title: "总表",
|
title: "总表",
|
||||||
icon: Compass,
|
icon: "ep:Compass",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
||||||
import { $t } from "@/common/languages";
|
import { $t } from "@/common/languages";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const getPageUrl = "/sale/device/getDevicePage";
|
const tableRef = ref<InstanceType<typeof TreeSidePageableTable> | null>(null);
|
||||||
const treeSideUrl = "/sale/device/getKeyAccount";
|
const getPageUrl = "/sale/device/getDeviceSnPage";
|
||||||
|
const treeSideUrl = "/sys/keyaccount/getKeyAccountTree";
|
||||||
const searchers = [
|
const searchers = [
|
||||||
{
|
{
|
||||||
name: "searchCode",
|
name: "searchCode",
|
||||||
type: "text" as const,
|
type: "text" as const,
|
||||||
placeholder: $t("_prop.sale.device.searchCode"),
|
placeholder:
|
||||||
|
$t("_prop.sale.devicesn.productSn") +
|
||||||
|
"/" +
|
||||||
|
$t("_prop.sale.devicesn.mac") +
|
||||||
|
"/" +
|
||||||
|
$t("_prop.sale.devicesn.serialNum"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
@@ -22,21 +29,19 @@ const searchers = [
|
|||||||
:searchers="searchers"
|
:searchers="searchers"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:tree-side-url="treeSideUrl"
|
:tree-side-url="treeSideUrl"
|
||||||
tree-side-node-name="keyAccountId"
|
tree-side-node-name="id"
|
||||||
tree-side-param-name="keyAccountId"
|
tree-side-param-name="keyAccountId"
|
||||||
tree-side-title="所有客户"
|
:tree-side-title="$t('_message.common.all_customers')"
|
||||||
>
|
>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column :label="$t('_prop.sale.device.productType')" prop="productType" />
|
<el-table-column :label="$t('_prop.sale.devicesn.productType')" prop="productType" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.productSn')" prop="productSn" />
|
<el-table-column :label="$t('_prop.sale.devicesn.productSn')" prop="productSn" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.mac')" prop="mac" />
|
<el-table-column :label="$t('_prop.sale.devicesn.mac')" prop="mac" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.serialNum')" prop="serialNum" />
|
<el-table-column :label="$t('_prop.sale.devicesn.serialNum')" prop="serialNum" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.softVersion')" prop="softVersion" />
|
<el-table-column :label="$t('_prop.sale.devicesn.softVersion')" prop="softVersion" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.alVersion')" prop="alVersion" />
|
<el-table-column :label="$t('_prop.sale.devicesn.AlVersion')" prop="alVersion" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.alNum')" prop="alNum" />
|
<el-table-column :label="$t('_prop.sale.devicesn.outProductDate')" prop="outProductDate" />
|
||||||
<el-table-column :label="$t('_prop.sale.device.outStatus')" prop="outStatus" />
|
<el-table-column :label="$t('_prop.sale.devicesn.repairMark')" prop="repairRecords" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('_prop.sale.device.outProductDate')" prop="outProductDate" />
|
|
||||||
<el-table-column :label="$t('_prop.sale.device.repairMark')" prop="repairMark" />
|
|
||||||
</template>
|
</template>
|
||||||
</TreeSidePageableTable>
|
</TreeSidePageableTable>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,26 +6,64 @@ import BaseForm from "@/components/base/base-form/BaseForm.vue";
|
|||||||
import { $t } from "@/common/languages";
|
import { $t } from "@/common/languages";
|
||||||
import type { FormInstance, FormRules } from "element-plus";
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
||||||
|
import { get } from "@/common/http/request";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const getPageUrl = "/sale/repairrecord/getRepairRecordPage";
|
const getPageUrl = "/sale/repairrecord/getRepairReportPage";
|
||||||
const addUrl = "/sale/repairrecord/addRepairRecord";
|
const addUrl = "/sale/repairrecord/addRepairRecord";
|
||||||
const editUrl = "/sale/repairrecord/updateRepairRecord";
|
const editUrl = "/sale/repairrecord/updateRepairRecord";
|
||||||
const removeUrl = "/sale/repairrecord/deleteRepairRecord";
|
const removeUrl = "/sale/repairrecord/deleteRepairRecord";
|
||||||
const treeSideUrl = "/sale/repairrecord/getKeyAccount";
|
const treeSideUrl = "/sys/keyaccount/getKeyAccountTree";
|
||||||
|
const keyAccountSelectUrl = "/sys/keyaccount/getKeyAccountSelectList";
|
||||||
const searchers = [
|
const searchers = [
|
||||||
{ name: "searchCode", type: "text" as const, placeholder: $t("_prop.sale.repairrecord.searchCode") },
|
{
|
||||||
|
name: "searchCode",
|
||||||
|
type: "text" as const,
|
||||||
|
placeholder: $t("_prop.sale.repairrecord.productSn") + "/" + $t("_prop.sale.repairrecord.mac"),
|
||||||
|
clearable: true,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const rules = reactive<FormRules>({});
|
|
||||||
|
const validateIdentifier = (_rule: any, _value: any, callback: any) => {
|
||||||
|
const formData = form.value;
|
||||||
|
if (formData.productSn || formData.mac || formData.serialNum) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
callback(new Error($t("_message.sale.repairrecord.input_identifier")));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
repairMark: [{ required: true, message: $t("_message.sale.repairrecord.input_repair_mark"), trigger: "blur" }],
|
||||||
|
productSn: [{ validator: validateIdentifier, trigger: "blur" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const keyAccountOptions = ref<{ label: string; value: string }[]>([]);
|
||||||
|
|
||||||
|
const loadKeyAccountOptions = async () => {
|
||||||
|
const res = await get(keyAccountSelectUrl);
|
||||||
|
if (res.data) {
|
||||||
|
keyAccountOptions.value = res.data.map((item: { label: string; value: string }) => ({
|
||||||
|
label: item.label,
|
||||||
|
value: item.value,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadKeyAccountOptions();
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基本不变通用变量
|
* 基本不变通用变量
|
||||||
*/
|
*/
|
||||||
const tableRef = ref<InstanceType<typeof TreeSidePageableTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof TreeSidePageableTable> | null>(null);
|
||||||
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
||||||
const { title, visible, formType, form } = useGeneralPageRef();
|
const { title, visible, formType, form } = useGeneralPageRef();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可以自定义的变量
|
* 可以自定义的变量
|
||||||
*/
|
*/
|
||||||
@@ -36,25 +74,32 @@ const add = () => {
|
|||||||
visible.value = true;
|
visible.value = true;
|
||||||
formType.value = false;
|
formType.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const edit = (row: any) => {
|
const edit = (row: any) => {
|
||||||
title.value = "_title.sale.repairrecord.edit";
|
title.value = "_title.sale.repairrecord.edit";
|
||||||
form.value = { ...row };
|
form.value = { ...row };
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
formType.value = true;
|
formType.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const remove = (row: any) => {
|
const remove = (row: any) => {
|
||||||
useRemove(removeUrl, row.id, "_message.sale.repairrecord.delete_message");
|
useRemove(removeUrl, row.id, "_message.sale.repairrecord.delete_message");
|
||||||
};
|
};
|
||||||
const submit = (form: any, formRef: FormInstance | undefined) => {
|
|
||||||
|
const submit = (formData: any, formRef: FormInstance | undefined) => {
|
||||||
if (formRef !== undefined) {
|
if (formRef !== undefined) {
|
||||||
formRef.validate(valid => {
|
formRef.validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (formType.value) useEdit(editUrl, form, visible);
|
if (formType.value) {
|
||||||
else useAdd(addUrl, form, visible);
|
useEdit(editUrl, formData, visible);
|
||||||
|
} else {
|
||||||
|
useAdd(addUrl, formData, visible);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const topButtonClick = (eventName: string) => {
|
const topButtonClick = (eventName: string) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "add":
|
case "add":
|
||||||
@@ -62,6 +107,7 @@ const topButtonClick = (eventName: string) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const operateButtonClick = (eventName: string, row: any) => {
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "edit":
|
case "edit":
|
||||||
@@ -79,27 +125,98 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
:searchers="searchers"
|
:searchers="searchers"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:tree-side-url="treeSideUrl"
|
:tree-side-url="treeSideUrl"
|
||||||
tree-side-node-name="keyAccountId"
|
tree-side-node-name="id"
|
||||||
tree-side-param-name="keyAccountId"
|
tree-side-param-name="keyAccountIdSearch"
|
||||||
tree-side-title="所有客户"
|
:tree-side-title="$t('_message.common.all_customers')"
|
||||||
>
|
>
|
||||||
<template #tool-button>
|
<template #tool-button>
|
||||||
<DefaultToolButton @top-button-click="topButtonClick" />
|
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column prop="id" type="hidden" width="40" />
|
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.productType')" prop="productType" />
|
<el-table-column :label="$t('_prop.sale.repairrecord.productType')" prop="productType" />
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.productSn')" prop="productSn" />
|
<el-table-column :label="$t('_prop.sale.repairrecord.productSn')" prop="productSn" />
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.mac')" prop="mac" />
|
<el-table-column :label="$t('_prop.sale.repairrecord.mac')" prop="mac" />
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.outProductDate')" prop="outProductDate" />
|
<el-table-column :label="$t('_prop.sale.repairrecord.outProductDate')" prop="outProductDate" />
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.repairDate')" prop="repairDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" />
|
||||||
<el-table-column :label="$t('_prop.sale.repairrecord.repairMark')" prop="repairMark" />
|
<el-table-column :label="$t('_prop.sale.repairrecord.repairCount')" prop="repairCount" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.repairrecord.repairMark')" prop="repairRecords" show-overflow-tooltip />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
</TreeSidePageableTable>
|
</TreeSidePageableTable>
|
||||||
<BaseForm v-model:visible="visible" @submit="submit" v-model:form="form" :title="$t(title)" :rules="rules">
|
<BaseForm v-model:visible="visible" @submit="submit" v-model:form="form" :title="$t(title)" :rules="rules">
|
||||||
<template #form-items>
|
<template #form-items>
|
||||||
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
|
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
|
||||||
|
<el-alert
|
||||||
|
:title="$t('_message.sale.repairrecord.identifier_tip')"
|
||||||
|
type="info"
|
||||||
|
:closable="false"
|
||||||
|
style="margin-bottom: 15px"
|
||||||
|
/>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.repairrecord.productType')" prop="productType">
|
||||||
|
<el-input v-model="form.productType" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.repairrecord.productSn')" prop="productSn">
|
||||||
|
<el-input
|
||||||
|
v-model="form.productSn"
|
||||||
|
:placeholder="$t('_message.sale.repairrecord.input_productSn_optional')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.repairrecord.mac')" prop="mac">
|
||||||
|
<el-input v-model="form.mac" :placeholder="$t('_message.sale.repairrecord.input_mac_optional')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.devicesn.serialNum')" prop="serialNum">
|
||||||
|
<el-input
|
||||||
|
v-model="form.serialNum"
|
||||||
|
:placeholder="$t('_message.sale.repairrecord.input_serialNum_optional')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.devicesn.softVersion')" prop="softVersion">
|
||||||
|
<el-input
|
||||||
|
v-model="form.softVersion"
|
||||||
|
:placeholder="$t('_message.sale.repairrecord.input_softVersion_optional')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.devicesn.AlVersion')" prop="alVersion">
|
||||||
|
<el-input
|
||||||
|
v-model="form.alVersion"
|
||||||
|
:placeholder="$t('_message.sale.repairrecord.input_alVersion_optional')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('_prop.sale.repairrecord.keyAccountId')" prop="keyAccountId">
|
||||||
|
<el-select v-model="form.keyAccountId" clearable style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in keyAccountOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="Number(item.value)"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item :label="$t('_prop.sale.repairrecord.repairMark')" prop="repairMark">
|
||||||
|
<el-input v-model="form.repairMark" type="textarea" :rows="3" />
|
||||||
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</BaseForm>
|
</BaseForm>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import BasePageableTable from "@/components/base/base-pageable-table/BasePageableTable.vue";
|
|
||||||
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
import DefaultToolButton from "@/components/base/default-tool-button/DefaultToolButton.vue";
|
||||||
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
|
import DefaultOperateButtonColumn from "@/components/base/default-column/DefaultOperateButtonColumn.vue";
|
||||||
|
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
||||||
import { usePage } from "@/composables/use-page";
|
import { usePage } from "@/composables/use-page";
|
||||||
import BaseForm from "@/components/base/base-form/BaseForm.vue";
|
|
||||||
import { $t } from "@/common/languages";
|
import { $t } from "@/common/languages";
|
||||||
import type { FormInstance, FormRules } from "element-plus";
|
|
||||||
import { formatDate } from "@/common/utils/format-utils";
|
import { formatDate } from "@/common/utils/format-utils";
|
||||||
|
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
|
||||||
|
import BaseFormWithTable from "@/components/base/base-form-with-table/BaseFormWithTable.vue";
|
||||||
|
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";
|
||||||
|
import ExpandablePageableTable from "@/components/base/expandable-pageable-table/ExpandablePageableTable.vue";
|
||||||
|
import { get } from "@/common/http/request";
|
||||||
|
import { type FieldMappingConfig } from "@/components/base/base-form-with-table/type";
|
||||||
|
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
@@ -16,45 +21,152 @@ const getPageUrl = "/sale/saleorder/getSaleOrderPage";
|
|||||||
const addUrl = "/sale/saleorder/addSaleOrder";
|
const addUrl = "/sale/saleorder/addSaleOrder";
|
||||||
const editUrl = "/sale/saleorder/updateSaleOrder";
|
const editUrl = "/sale/saleorder/updateSaleOrder";
|
||||||
const removeUrl = "/sale/saleorder/deleteSaleOrder";
|
const removeUrl = "/sale/saleorder/deleteSaleOrder";
|
||||||
|
const approveUrl = "/sale/saleorder/approveSaleOrder";
|
||||||
|
const rejectUrl = "/sale/saleorder/unapproveSaleOrder";
|
||||||
|
const itemUrl = "/sale/saleorder/getSaleOrderItemList";
|
||||||
|
const keyAccountSelectUrl = "/sys/keyaccount/getKeyAccountSelectList";
|
||||||
|
|
||||||
const searchers = [
|
const searchers = [
|
||||||
{ name: "customerName", type: "text" as const, placeholder: $t("_prop.sale.saleorder.customerName") },
|
{
|
||||||
|
name: "customerName",
|
||||||
|
type: "text" as const,
|
||||||
|
placeholder: $t("_prop.sale.saleorder.customerName"),
|
||||||
|
clearable: true,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const rules = reactive<FormRules>({});
|
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
formCode: [{ required: true, message: $t("_message.sale.saleorder.input_formCode"), trigger: "blur" }],
|
||||||
|
formName: [{ required: true, message: $t("_message.sale.saleorder.input_formName"), trigger: "blur" }],
|
||||||
|
customerId: [{ required: true, message: $t("_message.sale.saleorder.select_customerId"), trigger: "change" }],
|
||||||
|
customerName: [{ required: true, message: $t("_message.sale.saleorder.select_customerId"), trigger: "change" }],
|
||||||
|
saleOrderItems: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value === undefined || value.length === 0) {
|
||||||
|
callback($t("_message.sale.saleorder.no_sale_order_items"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemArrayName = "saleOrderItems";
|
||||||
|
const getDetailUrl = "/sale/saleorder/getSaleOrderItemList";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基本不变通用变量
|
* 基本不变通用变量
|
||||||
*/
|
*/
|
||||||
const tableRef = ref<InstanceType<typeof BasePageableTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
||||||
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
const { useAdd, useEdit, useRemove, useGeneralPageRef, useApprove, useReject } = usePage(tableRef);
|
||||||
const { title, visible, formType, form } = useGeneralPageRef();
|
const { title, visible, formType, form, itemVisible, itemParentId } = useGeneralPageRef();
|
||||||
|
const { getFormStatusLabel } = useStatus();
|
||||||
|
const baseFormWithTableRef = ref<InstanceType<typeof BaseFormWithTable>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可以自定义的变量
|
* 可以自定义的变量
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const keyAccountOptions = ref<{ label: string; value: string }[]>([]);
|
||||||
|
|
||||||
|
const loadKeyAccountOptions = async () => {
|
||||||
|
const res = await get(keyAccountSelectUrl);
|
||||||
|
if (res.data) {
|
||||||
|
keyAccountOptions.value = res.data.map((item: { label: string; value: string }) => ({
|
||||||
|
label: item.label,
|
||||||
|
value: item.value,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadKeyAccountOptions();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 生成单据编号
|
||||||
|
const generateFormCode = () => {
|
||||||
|
const now = new Date();
|
||||||
|
const dateStr =
|
||||||
|
now.getFullYear().toString() +
|
||||||
|
String(now.getMonth() + 1).padStart(2, "0") +
|
||||||
|
String(now.getDate()).padStart(2, "0") +
|
||||||
|
String(now.getHours()).padStart(2, "0") +
|
||||||
|
String(now.getMinutes()).padStart(2, "0") +
|
||||||
|
String(now.getSeconds()).padStart(2, "0");
|
||||||
|
return "SO" + dateStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听客户选择变化,同步更新客户名称
|
||||||
|
const handleCustomerChange = (value: number) => {
|
||||||
|
const selected = keyAccountOptions.value.find(item => Number(item.value) === value);
|
||||||
|
if (selected) {
|
||||||
|
form.value.customerName = selected.label;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const add = () => {
|
const add = () => {
|
||||||
form.value = {};
|
form.value = {
|
||||||
|
formCode: generateFormCode(),
|
||||||
|
};
|
||||||
title.value = "_title.sale.saleorder.add";
|
title.value = "_title.sale.saleorder.add";
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
formType.value = false;
|
formType.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const edit = (row: any) => {
|
const edit = (row: any) => {
|
||||||
title.value = "_title.sale.saleorder.edit";
|
title.value = "_title.sale.saleorder.edit";
|
||||||
form.value = { ...row };
|
form.value = {
|
||||||
|
...row,
|
||||||
|
saleOrderItems: [],
|
||||||
|
};
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
formType.value = true;
|
formType.value = true;
|
||||||
|
|
||||||
|
// 加载明细数据
|
||||||
|
get(getDetailUrl, { saleOrderId: row.id })
|
||||||
|
.then(res => {
|
||||||
|
form.value.saleOrderItems = res.data || [];
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Failed to load sale order items:", err);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const remove = (row: any) => {
|
const remove = (row: any) => {
|
||||||
useRemove(removeUrl, row.id, "_message.sale.saleorder.delete_message");
|
useRemove(removeUrl, row.id, "_message.sale.saleorder.delete_message");
|
||||||
};
|
};
|
||||||
const submit = (form: any, formRef: FormInstance | undefined) => {
|
|
||||||
if (formRef !== undefined) {
|
const approve = (row: any) => {
|
||||||
formRef.validate(valid => {
|
useApprove(approveUrl, row.id);
|
||||||
if (valid) {
|
|
||||||
if (formType.value) useEdit(editUrl, form, visible);
|
|
||||||
else useAdd(addUrl, form, visible);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reject = (row: any) => {
|
||||||
|
useReject(rejectUrl, row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showItem = (row: any) => {
|
||||||
|
itemParentId.value = row.id;
|
||||||
|
itemVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = (formData: any, formRef: FormInstance | undefined) => {
|
||||||
|
const targetRef = formRef || (baseFormWithTableRef.value as any)?.baseFormRef;
|
||||||
|
if (!targetRef) return;
|
||||||
|
|
||||||
|
targetRef.validate((valid: any) => {
|
||||||
|
if (valid) {
|
||||||
|
if (formType.value) {
|
||||||
|
useEdit(editUrl, formData, visible);
|
||||||
|
} else {
|
||||||
|
useAdd(addUrl, formData, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const topButtonClick = (eventName: string) => {
|
const topButtonClick = (eventName: string) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "add":
|
case "add":
|
||||||
@@ -62,6 +174,7 @@ const topButtonClick = (eventName: string) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const operateButtonClick = (eventName: string, row: any) => {
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "edit":
|
case "edit":
|
||||||
@@ -70,29 +183,210 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
case "remove":
|
case "remove":
|
||||||
remove(row);
|
remove(row);
|
||||||
break;
|
break;
|
||||||
|
case "approve":
|
||||||
|
approve(row);
|
||||||
|
break;
|
||||||
|
case "reject":
|
||||||
|
reject(row);
|
||||||
|
break;
|
||||||
|
case "showItem":
|
||||||
|
showItem(row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||||
|
if (row.formStatus === 1 && button.eventName === "approve") return false;
|
||||||
|
if (row.formStatus === 0 && button.eventName === "reject") return false;
|
||||||
|
if (row.formStatus === 1 && button.eventName === "edit") return false;
|
||||||
|
if (row.formStatus === 1 && button.eventName === "remove") return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const mappingConfig: FieldMappingConfig = {
|
||||||
|
partNumber: {
|
||||||
|
sourceKey: "物料编号",
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
productSpecs: {
|
||||||
|
sourceKey: "物料型号",
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
saleCount: {
|
||||||
|
sourceKey: "数量",
|
||||||
|
defaultValue: 0,
|
||||||
|
transform: (val: any) => {
|
||||||
|
const num = Number(val);
|
||||||
|
return isNaN(num) ? 0 : num;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
sourceKey: "单价",
|
||||||
|
defaultValue: 0,
|
||||||
|
transform: (val: any) => {
|
||||||
|
const num = Number(val);
|
||||||
|
return isNaN(num) ? 0 : num;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
saleMark: {
|
||||||
|
sourceKey: "备注",
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算总价
|
||||||
|
const calculateTotalPrice = (row: any) => {
|
||||||
|
if (row.saleCount && row.price) {
|
||||||
|
row.totalPrice = Number((row.saleCount * row.price).toFixed(2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
<ExpandablePageableTable
|
||||||
|
:url="getPageUrl"
|
||||||
|
:searchers="searchers"
|
||||||
|
ref="tableRef"
|
||||||
|
:item-url="itemUrl"
|
||||||
|
item-id-key="id"
|
||||||
|
item-id-name="saleOrderId"
|
||||||
|
item-field-name="saleOrderItems"
|
||||||
|
>
|
||||||
<template #tool-button>
|
<template #tool-button>
|
||||||
<DefaultToolButton @top-button-click="topButtonClick" />
|
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column prop="id" type="hidden" width="40" />
|
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.formCode')" prop="formCode" />
|
<el-table-column :label="$t('_prop.sale.saleorder.formCode')" prop="formCode" />
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.customerName')" prop="customerName" />
|
<el-table-column :label="$t('_prop.sale.saleorder.customerName')" prop="customerName" />
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.totalValue')" prop="totalValue" />
|
<el-table-column :label="$t('_prop.sale.saleorder.totalValue')" prop="totalValue" />
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.formName')" prop="formName" />
|
<el-table-column :label="$t('_prop.sale.saleorder.formName')" prop="formName" />
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.sale.saleorder.formMark')" prop="formMark" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<el-table-column :label="$t('_prop.sale.saleorder.formStatus')" prop="formStatus" />
|
<DefaultStatusSwitchColumn
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:switch-on-value="1"
|
||||||
|
:switch-off-value="0"
|
||||||
|
/>
|
||||||
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
</BasePageableTable>
|
<template #item-content="{ itemData }">
|
||||||
<BaseForm v-model:visible="visible" @submit="submit" v-model:form="form" :title="$t(title)" :rules="rules">
|
<el-table :data="itemData" size="small" border stripe>
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.partNumber')" prop="partNumber" width="150" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.productSpecs')" prop="productSpecs" width="200" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.saleCount')" prop="saleCount" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.price')" prop="price" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.totalPrice')" prop="totalPrice" />
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
</ExpandablePageableTable>
|
||||||
|
<BaseFormWithTable
|
||||||
|
ref="baseFormWithTableRef"
|
||||||
|
v-model:visible="visible"
|
||||||
|
@submit="submit"
|
||||||
|
v-model:form="form"
|
||||||
|
:title="$t(title)"
|
||||||
|
:rules="rules"
|
||||||
|
:base-title="$t('_title.sale.saleorder.baseTitle')"
|
||||||
|
:table-title="$t('_title.sale.saleorder.tableTitle')"
|
||||||
|
item-array-name="saleOrderItems"
|
||||||
|
upload-desc="销售明细"
|
||||||
|
:mapping-config="mappingConfig"
|
||||||
|
>
|
||||||
<template #form-items>
|
<template #form-items>
|
||||||
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
|
<el-form-item prop="id" v-if="false"><el-input v-model="form.id" /></el-form-item>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('_prop.sale.saleorder.formCode')" prop="formCode">
|
||||||
|
<el-input v-model="form.formCode" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('_prop.sale.saleorder.customerId')" prop="customerId">
|
||||||
|
<el-select v-model="form.customerId" clearable style="width: 100%" @change="handleCustomerChange">
|
||||||
|
<el-option
|
||||||
|
v-for="item in keyAccountOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="Number(item.value)"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item :label="$t('_prop.sale.saleorder.formName')" prop="formName">
|
||||||
|
<el-input v-model="form.formName" :placeholder="$t('_message.sale.saleorder.input_formName')" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item :label="$t('_prop.sale.saleorder.formMark')" prop="formMark">
|
||||||
|
<el-input
|
||||||
|
v-model="form.formMark"
|
||||||
|
:placeholder="$t('_message.sale.saleorder.input_formMark')"
|
||||||
|
type="textarea"
|
||||||
|
:rows="2"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</BaseForm>
|
<template #form-table-columns>
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.partNumber')" width="150">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${itemArrayName}.${$index}.partNumber`" :rules="rules.partNumber">
|
||||||
|
<el-input v-model="row.partNumber" size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.saleCount')" width="120">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${itemArrayName}.${$index}.saleCount`">
|
||||||
|
<el-input-number v-model="row.saleCount" size="small" :min="1" @change="calculateTotalPrice(row)" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.price')" width="120">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${itemArrayName}.${$index}.price`">
|
||||||
|
<el-input-number
|
||||||
|
v-model="row.price"
|
||||||
|
size="small"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
@change="calculateTotalPrice(row)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.totalPrice')" width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span>{{ row.totalPrice?.toFixed(2) || "0.00" }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.saleMark')" width="150">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${itemArrayName}.${$index}.saleMark`">
|
||||||
|
<el-input v-model="row.saleMark" placeholder="请输入备注" size="small" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</template>
|
||||||
|
</BaseFormWithTable>
|
||||||
|
<BaseItemDialog
|
||||||
|
:title="$t('_title.sale.saleorder.showItem')"
|
||||||
|
v-model:visible="itemVisible"
|
||||||
|
:url="getDetailUrl"
|
||||||
|
parent-param-name="saleOrderId"
|
||||||
|
v-model:parent-param-value="itemParentId"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.partNumber')" prop="partNumber" width="150" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.productSpecs')" prop="productSpecs" width="200" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.saleCount')" prop="saleCount" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.price')" prop="price" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.totalPrice')" prop="totalPrice" />
|
||||||
|
<el-table-column :label="$t('_prop.sale.saleorder.saleMark')" prop="saleMark" />
|
||||||
|
</template>
|
||||||
|
</BaseItemDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user