采购计划

This commit is contained in:
weiwei committed 2025-02-17 08:51:12 +08:00
1 parent a5958a451a
commit 43c5fdbb25
2 files changed
+219 -124

No files matched your search

+7 -7
View File
@@ -1,8 +1,8 @@
{
"tabWidth": 2,
"useTabs": true,
"trailingComma": "all",
"semi": false,
"singleQuote": false,
"printWidth": 120
}
"tabWidth": 2,
"useTabs": true,
"trailingComma": "all",
"semi": false,
"singleQuote": false,
"printWidth": 140
}
@@ -1,20 +1,20 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view" style="overflow: scroll">
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="140px" v-loading="loading">
<div v-loading="loading" class="layout-padding-auto layout-padding-view" style="overflow: scroll">
<el-form ref="baseDataFormRef" :model="baseDataForm" :rules="dataRules" formDialogRef label-width="140px">
<div class="flex flex-wrap">
<el-form-item label="采购计划编号" prop="planCode">
<el-input v-model="form.planCode" placeholder="请输入采购计划编号" disabled style="width: 200px" />
<el-input v-model.trim="baseDataForm.planCode" placeholder="请输入采购计划编号" disabled style="width: 200px" />
</el-form-item>
<el-form-item label="订单编号" prop="orderNumber">
<el-input v-model="form.orderNumber" placeholder="请输入订单编号" style="width: 200px" />
<el-input v-model.trim="baseDataForm.orderNumber" placeholder="请输入订单编号" maxlength="50" style="width: 200px" />
</el-form-item>
<el-form-item label="采购计划单据日期" prop="planDate">
<el-date-picker
style="width: 200px"
v-model="form.planDate"
v-model.trim="baseDataForm.planDate"
type="date"
placeholder="请选择采购计划单据日期"
format="YYYY-MM-DD"
@@ -23,21 +23,21 @@
</el-form-item>
<el-form-item label="货商" prop="supplierId">
<el-select v-model="form.supplierId" placeholder="请选择货商" style="width: 200px">
<el-option v-for="item in supplierDict" :key="item?.id" :label="item?.typeName" :value="item?.id" />
<el-select v-model.trim="baseDataForm.supplierId" placeholder="请选择货商" style="width: 200px">
<el-option v-for="item in supplierTypeDict" :key="item?.id" :label="item?.typeName" :value="item?.id" />
</el-select>
</el-form-item>
<!-- <el-form-item label="仓库" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入仓库id" />
<el-input v-model.trim="baseDataForm.warehouseId" placeholder="请输入仓库id" />
</el-form-item> -->
<el-form-item label="经办人" prop="handlerUserId">
<el-input v-model="form.handlerUserId" placeholder="请输入经办人" style="width: 200px" />
<el-input v-model.trim="baseDataForm.handlerUserId" placeholder="请输入经办人" maxlength="20" style="width: 200px" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" style="width: 200px" />
<el-input v-model.trim="baseDataForm.remark" placeholder="请输入备注" maxlength="50" style="width: 200px" />
</el-form-item>
</div>
</el-form>
@@ -49,9 +49,9 @@
在第
<el-input-number
@click.stop
v-model="state.insertRowNumber"
v-model="state.insertedRowNumber"
:min="0"
:max="state.tableData.length"
:max="state.editableTableData.length"
:precision="0"
size="small"
controls-position="right"
@@ -59,14 +59,13 @@
/>
行新增
</el-button>
<el-button @click="removeSelectRowEvent" :disabled="state.selectedRowsErpSpuIds.length <= 0">
删除选中
</el-button>
<el-button @click="removeSelectRowEvent" :disabled="state.selectedRowsErpSpuIds.length <= 0">删除选中</el-button>
<el-button @click="handleClickSpuSelect">商品选择</el-button>
<el-button @click="clearData">重置数据</el-button>
</el-row>
<vxe-table
ref="tableRef"
ref="editableTableRef"
border
:loading="loading"
show-overflow
@@ -75,7 +74,7 @@
trigger: 'click',
mode: 'cell',
beforeEditMethod({ row, column }:any) {
// name 为 'x' 开头的列禁止编辑
// 禁止编辑
if (column.property === '') {
return false
}
@@ -85,33 +84,39 @@
:column-config="{ resizable: true }"
:row-config="{ isHover: true }"
:resizable-config="{ dragMode: 'fixed' }"
:data="state.tableData"
:data="state.editableTableData"
:edit-rules="validRules"
@checkbox-all="selectChangeEvent"
@checkbox-change="selectChangeEvent"
size="mini"
align="center"
>
<vxe-column type="checkbox" width="40" fixed="left"></vxe-column>
<vxe-column type="checkbox" width="40" fixed="left" />
<vxe-column type="seq" width="50" fixed="left"></vxe-column>
<vxe-column type="seq" width="50" fixed="left" />
<!-- <vxe-column field="planId" title="采购" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">-->
<!-- <template #edit="{ row }">-->
<!-- <el-input v-model="row.planId" />-->
<!-- </template>-->
<!-- </vxe-column>-->
<!-- <vxe-column field="planId" title="采购" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
<template #edit="{ row }">
<el-input v-model="row.planId" />
</template>
</vxe-column> -->
<vxe-column field="productName" title="库存商品" />
<vxe-column field="unitId" title="包装单位" :edit-render="{}">
<template #edit="{ row }">
<el-select v-model="row.unitId" placeholder="请选择包装单位">
<el-option v-for="item in row.erpUnitVos" :key="item.id" :label="item.unit" :value="item.id" />
<el-option
v-if="row.erpUnitVos?.length > 0"
v-for="item in row.erpUnitVos"
:key="item.id"
:label="item.unit"
:value="item.id"
/>
</el-select>
</template>
<template #default="{ row }">
<span v-if="row.unitId">{{ row.erpUnitVos.find((item: any) => item.id == row.unitId)?.unit }}</span>
<span v-if="row.unitId">{{ row.erpUnitVos?.find((item: any) => item.id == row.unitId)?.unit }}</span>
<span v-else style="color: #c0c4cf">请选择</span>
</template>
</vxe-column>
@@ -124,7 +129,7 @@
<vxe-column field="unitPrice" title="进价">
<template #default="{ row }">
{{ row.erpUnitVos.find((item: any) => item.id == row.unitId)?.purchasePrice }}
{{ row.erpUnitVos?.find((item: any) => item.id == row.unitId)?.purchasePrice }}
</template>
</vxe-column>
@@ -132,7 +137,7 @@
<template #default="{ row }">
{{
row.unitId && row.quantity
? Number(row.erpUnitVos.find((item: any) => item.id == row.unitId)?.purchasePrice) * row.quantity
? Number(row.erpUnitVos?.find((item: any) => item.id == row.unitId)?.purchasePrice) * row.quantity
: ""
}}
</template>
@@ -158,16 +163,22 @@
</vxe-table>
<el-row class="my-3">
<el-button type="primary" plain @click="onSubmit">取消</el-button>
<el-button type="primary" plain @click="onSubmit">继续添加</el-button>
<el-button type="primary" plain @click="onSubmit">保存</el-button>
<el-tooltip effect="dark" content="返回列表页面" placement="top">
<el-button type="primary" plain @click="router.back()">取消</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="保存并清空数据" placement="top">
<el-button type="primary" plain @click="onContinueAdd">继续添加</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="保存并返回列表页面" placement="top">
<el-button type="primary" plain @click="onSave">保存</el-button>
</el-tooltip>
</el-row>
<!-- 商品选择对话框 -->
<el-dialog
v-model="state.spuSelectDialogVisible"
title="选择商品"
width="60%"
width="70%"
:close-on-click-modal="false"
draggable
@close="state.selectedSpuObjs = []"
@@ -227,7 +238,7 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="state.spuSelectDialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSelectDialogConfirm" :disabled="loading">确认</el-button>
<el-button type="primary" @click="handleSelectDialogConfirm" :disabled="spuListLoading">确认</el-button>
</div>
</template>
</el-dialog>
@@ -236,12 +247,27 @@
</template>
<script setup lang="ts" name="SmErpCgPlanDialog">
import { ref, reactive, computed, onMounted } from "vue"
import { useRouter } from "vue-router"
import { useDict } from "/@/hooks/dict"
import { useMessage } from "/@/hooks/message"
import { getObj, addObj, putObj, getPlanCode, getCgPlanSpuPage } from "/@/api/supermarketerp/smErpCgPlan"
import { VxeTableEvents, VxeTablePropTypes, VxeUI, type VxeTableInstance } from "vxe-table"
import { VxeTableEvents, VxeTablePropTypes, type VxeTableInstance } from "vxe-table"
import { getSupplierTypeOptions } from "/@/api/supermarketerp/smErpSupplier"
import { storePrice } from "/@/utils/formatMoney"
// 基本表单数据类型
interface FormVO {
planCode: string
orderNumber: string
planDate: string
supplierId: string
handlerUserId: string
remark: string
[key: string]: string
}
// 可编辑表格行数据类型
interface RowVO {
id?: string
erpSpuId: string
@@ -252,16 +278,16 @@ interface RowVO {
unitId: string
}
// 定义变量内容
const loading = ref(false)
const spuListLoading = ref(false)
const dataFormRef = ref()
const tableRef = ref<VxeTableInstance<RowVO>>()
const spuMultipleTableRef = ref()
const supplierDict = ref<any[]>([]) // 货商下拉选项
const router = useRouter()
const loading = ref(false) // 采购计划加载
const spuListLoading = ref(false) // 对话框商品列表加载
const baseDataFormRef = ref() // 基本数据表单ref
const editableTableRef = ref<VxeTableInstance<RowVO>>() // 可编辑表格ref
const spuMultipleTableRef = ref() // 对话框多选表格ref
const supplierTypeDict = ref<any[]>([]) // 货商下拉选项
// 提交表单数据
const form = reactive({
// 基本信息表单数据
const baseDataForm = reactive<FormVO>({
planCode: "",
orderNumber: "",
planDate: "",
@@ -270,23 +296,23 @@ const form = reactive({
remark: "",
})
const state = reactive<{
tableData: RowVO[]
editableTableData: RowVO[]
selectedRowsErpSpuIds: string[]
insertRowNumber: number
insertedRowNumber: number
spuSelectDialogVisible: boolean
spuDataList: any[]
selectedSpuObjs: any[]
}>({
tableData: [],
selectedRowsErpSpuIds: [],
insertRowNumber: 0,
editableTableData: [], // 可编辑表格数据
selectedRowsErpSpuIds: [], // 可编辑表格已选行的ErpSpuId
insertedRowNumber: 0, // 可编辑表格插入行的行号
spuSelectDialogVisible: false,
spuDataList: [],
selectedSpuObjs: [],
spuSelectDialogVisible: false, // 商品选择对话框开关
spuDataList: [], // 商品列表
selectedSpuObjs: [], // 已选中的商品列表项
})
// 表单校验规则
// 基本信息表单校验规则
const dataRules = ref({
planCode: [{ required: true, message: "采购计划编号不能为空", trigger: "blur" }],
planDate: [{ required: true, message: "采购计划单据日期不能为空", trigger: "blur" }],
@@ -299,33 +325,18 @@ const validRules = ref<VxeTablePropTypes.EditRules<RowVO>>({
quantity: [{ required: true, type: "number", min: 1, max: 99, message: "数值范围1~99" }],
})
// 获取货商选项
const getSupplierDict = async () => {
try {
const { code, data } = await getSupplierTypeOptions()
if (code === 0) {
supplierDict.value = data
}
} catch (error) {
supplierDict.value = []
}
}
// 获取采购计划编号
const getSequencePlanCode = async () => {
try {
const { code, data } = await getPlanCode()
if (code === 0) {
form.planCode = data
}
} catch (error) {
form.planCode = ""
}
const getInitData = async () => {
// 获取货商选项 & 获取采购计划编号
const [supplierTypeOptions, planCode] = await Promise.allSettled([getSupplierTypeOptions(), getPlanCode()]).then((results) =>
results.map((result) => (result.status === "fulfilled" ? result.value : null)),
)
supplierTypeOptions && supplierTypeOptions.code === 0 && (supplierTypeDict.value = supplierTypeOptions.data)
planCode && planCode.code === 0 && (baseDataForm.planCode = planCode.data)
}
// 可编辑表格行勾选
const selectChangeEvent: VxeTableEvents.CheckboxChange<RowVO> = ({ checked }) => {
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
const records = $table.getCheckboxRecords()
console.log(checked ? "勾选事件" : "取消事件", records)
@@ -336,6 +347,7 @@ const selectChangeEvent: VxeTableEvents.CheckboxChange<RowVO> = ({ checked }) =>
// 顶部表格行新增
const addEvent = () => {
const newRow: RowVO = {
id: "",
erpSpuId: "",
quantity: null,
unitPrice: null,
@@ -343,9 +355,9 @@ const addEvent = () => {
remark: "",
unitId: "",
}
state.tableData.unshift(newRow)
state.editableTableData.unshift(newRow)
nextTick(() => {
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
$table.setEditRow(newRow)
}
@@ -362,9 +374,9 @@ const pushEvent = () => {
remark: "",
unitId: "",
}
state.tableData.push(newRow)
state.editableTableData.push(newRow)
nextTick(() => {
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
$table.setEditRow(newRow)
}
@@ -381,9 +393,9 @@ const insertEvent = () => {
remark: "",
unitId: "",
}
state.tableData.splice(state.insertRowNumber, 0, newRow)
state.editableTableData.splice(state.insertedRowNumber, 0, newRow)
nextTick(() => {
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
$table.setEditRow(newRow)
}
@@ -392,18 +404,18 @@ const insertEvent = () => {
// 删除选中的行
const removeSelectRowEvent = () => {
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
const selectRecords = $table.getCheckboxRecords()
if (selectRecords.length > 0) {
state.tableData = state.tableData.filter((item) => !selectRecords.some((row) => row.erpSpuId === item.erpSpuId))
state.editableTableData = state.editableTableData.filter((item) => !selectRecords.some((row) => row.id === item.id))
}
}
}
// 点击商品选择
const handleClickSpuSelect = async () => {
state.selectedSpuObjs = [...state.tableData]
state.selectedSpuObjs = [...state.editableTableData]
state.spuSelectDialogVisible = true
spuListLoading.value = true
@@ -413,9 +425,7 @@ const handleClickSpuSelect = async () => {
state.spuDataList = data.records
// 勾选已经选择的商品
const target = state.spuDataList.filter((row: any) =>
state.selectedSpuObjs.some((item: any) => row.id === item.id),
)
const target = state.spuDataList.filter((row: any) => state.selectedSpuObjs.some((item: any) => row.id === item.id))
target.forEach((row: any) => nextTick(() => spuMultipleTableRef.value!.toggleRowSelection(row)))
}
} catch (error) {
@@ -439,7 +449,7 @@ const rowClick = (row: any) => {
}
// 选中商品列表表格行
function handleSelect(selectedRows: any[], row: any) {
const handleSelect = (selectedRows: any[], row: any) => {
state.selectedSpuObjs.findIndex((item: any) => item.id === row.id) === -1
? // state.selectedSpuObjs.indexOf(row) === -1
state.selectedSpuObjs.push(row)
@@ -452,7 +462,7 @@ function handleSelect(selectedRows: any[], row: any) {
}
// 全选和反全选商品列表表格行
function handleSelectAll(selectedRows: any[]) {
const handleSelectAll = (selectedRows: any[]) => {
if (selectedRows.length > 0) {
selectedRows.forEach((row: any) => {
if (state.selectedSpuObjs.findIndex((item: any) => item.id === row.id) === -1) {
@@ -460,8 +470,6 @@ function handleSelectAll(selectedRows: any[]) {
}
})
} else {
console.log("xxx", selectedRows)
state.spuDataList.forEach((row: any) => {
const index = state.selectedSpuObjs.findIndex((item: any) => item.id === row.id)
if (index !== -1) {
@@ -473,68 +481,155 @@ function handleSelectAll(selectedRows: any[]) {
}
// 商品表格多选
const selectionChangeHandle = (objs: any) => {
// console.log("onChange-selects", objs)
const selectionChangeHandle = (rows: any) => {
// console.log("onChange-selects", rows)
}
// 商品选择对话框确认
const handleSelectDialogConfirm = () => {
console.log(state.tableData, state.selectedSpuObjs)
// 对比可编辑表格数据和已勾选的数据判断新勾选的项和取消勾选的项
console.log(state.editableTableData, state.selectedSpuObjs)
// 筛选新勾选的项
const addItems = state.selectedSpuObjs
const addedItems = state.selectedSpuObjs
.map((item: any) => ({ ...item, erpSpuId: item.id }))
.filter((item: any) => !state.tableData.some((tableItem: RowVO) => tableItem.id === item.id))
.filter((item: any) => !state.editableTableData.some((editableTableItem: RowVO) => editableTableItem.id === item.id))
// 仅添加新勾选的项
state.tableData.push(...addItems)
// state.editableTableData.push(...addedItems)
state.editableTableData = [...state.editableTableData, ...addedItems]
// 筛选取消勾选的项
const removeItems = state.tableData.filter(
const removedItems = state.editableTableData.filter(
(item: any) => !state.selectedSpuObjs.some((selectedItem: any) => selectedItem.id === item.id),
)
// 仅移除取消勾选的项
state.tableData = state.tableData.filter(
(item: any) => !removeItems.some((removeItem: any) => removeItem.id === item.id),
state.editableTableData = state.editableTableData.filter(
(item: any) => !removedItems.some((removeItem: any) => removeItem.id === item.id),
)
// state.tableData.push(item)
// state.editableTableData.push(item)
// nextTick(() => {
// const $table = tableRef.value
// const $table = editableTableRef.value
// if ($table) {
// $table.setRow(item)
// }
// })
state.spuSelectDialogVisible = false
console.log("state.tableData", state.tableData)
console.log("state.editableTableData", state.editableTableData)
}
// 提交
const onSubmit = async () => {
console.log(form)
console.log(state.tableData)
// 整理数据
const cgPlanSpuItems = computed(() => {
const a = state.editableTableData
return a.map((item: any) => {
console.log("xxxx")
const unit = item.erpUnitVos.find((unitItem: any) => unitItem.id == item.unitId)
return {
id: "",
erpSpuId: item.erpSpuId,
quantity: item.quantity,
unitPrice: unit.purchasePrice ? storePrice(unit?.purchasePrice) : 0,
totalAmount: Number(unit?.purchasePrice || 0) * item.quantity,
remark: item.remark,
unitId: item.unitId,
}
})
})
// 点击继续添加
const onContinueAdd = async () => {
console.log("baseDataForm", baseDataForm)
console.log("state.editableTableData", state.editableTableData)
;(await baseDataFormValidate()) && checkSelectSpu() && (await editableTableValidate()) && (await submitData()) && clearData()
}
// 点击保存
const onSave = async () => {
console.log("baseDataForm", baseDataForm)
console.log("state.editableTableData", state.editableTableData)
;(await baseDataFormValidate()) &&
checkSelectSpu() &&
(await editableTableValidate()) &&
(await submitData()) &&
clearData() &&
router.back()
}
// 校验基本数据表单 成功返回 true 失败返回 undefined
const baseDataFormValidate = async () => {
const valid = await baseDataFormRef.value.validate().catch(() => {})
return valid
}
// 校验是否选择了商品 成功返回 true 失败返回 false
const checkSelectSpu = () => {
if (state.editableTableData.length <= 0) {
useMessage().warning("请选择商品")
return false
} else {
return true
}
}
// 校验可编辑表格 成功返回 true 失败返回 false
const editableTableValidate = async () => {
// 全量校验
const $table = tableRef.value
const $table = editableTableRef.value
if ($table) {
const errMap = await $table.validate(true)
if (errMap) {
console.log("全量校验失败!")
return
return false
} else {
console.log("全量校验成功!")
return
return true
}
}
}
// 提交数据 成功返回 true 失败返回 false
const submitData = async () => {
try {
loading.value = true
console.log("提交的数据:", {
...baseDataForm,
items: cgPlanSpuItems.value,
})
const res = await addObj({
...baseDataForm,
items: cgPlanSpuItems.value,
}).finally(() => (loading.value = false))
if (res.code === 0) {
useMessage().success("添加成功")
return true
} else {
useMessage().error(res.msg)
return false
}
} catch (err: any) {
useMessage().error(err.msg)
loading.value = false
return false
}
}
// 清空填写的数据
const clearData = () => {
for (const key in baseDataForm) {
if (key === "planCode") continue
baseDataForm[key] = ""
}
state.insertedRowNumber = 0
state.editableTableData = []
state.selectedRowsErpSpuIds = []
state.selectedSpuObjs = []
}
onMounted(() => {
getSupplierDict()
getSequencePlanCode()
getInitData()
})
// const onSubmit = async () => {
// const valid = await dataFormRef.value.validate().catch(() => {})
// if (!valid) return false
// try {
// loading.value = true
// form.id ? await putObj(form) : await addObj(form)