This commit is contained in:
dzc committed 2025-05-14 16:46:46 +08:00
commit b714616205
11 files changed
+443 -548

No files matched your search

@@ -8,6 +8,14 @@ export function fetchList(query?: Object) {
})
}
export function fetchGetSelectTemplatePage(query?: Object) {
return request({
url: '/canteen/canteenProductionTemplate/getSelectTemplatePage',
method: 'get',
params: query
})
}
export function addObj(obj?: Object) {
return request({
url: '/canteen/canteenProductionTemplate',
+1 -1
View File
@@ -3,7 +3,7 @@ import request from "/@/utils/request"
// 获取食堂业务流水编号
export function getCanteenSequence(params?: { type: string | number }) {
return request({
url: "/canteen/common/getSequence",
url: "/canteen/canteen/common/getSequence",
method: "get",
params,
})
@@ -12,9 +12,6 @@
<el-form-item label="经办人" prop="handlerUserId">
<SelectHandlerUser v-model.trim="baseForm.handlerUserId" placeholder="请选择经办人" style="width: 200px" />
</el-form-item>
<el-form-item label="商户" prop="merchantId">
<select-mch v-model="baseForm.merchantId" :apiParams="{ types: '1' }" style="width: 200px" />
</el-form-item>
<el-form-item label="货商" prop="supplierId">
<SelectCanteenSupplier v-model="baseForm.supplierId" style="width: 200px" />
</el-form-item>
@@ -25,14 +22,8 @@
</el-form>
<el-row class="my-3">
<el-button type="primary" plain @click="clickSelectDialog" v-auth="'canteen_canteenInventoryRecordsItem_add'">商品选择</el-button>
<el-button
@click="removeSelectedRows"
:disabled="state.selectedRowIds.length <= 0"
v-auth="'canteen_canteenInventoryRecordsItem_del'"
>
删除选中
</el-button>
<el-button type="primary" plain @click="clickSelectDialog">食材选择</el-button>
<el-button @click="removeSelectedRows" :disabled="state.selectedRowIds.length <= 0">删除选中</el-button>
<el-button type="danger" plain @click="clearData">清空数据</el-button>
</el-row>
@@ -73,7 +64,7 @@
>
<vxe-column type="checkbox" width="40" fixed="left" />
<vxe-column type="seq" width="50" fixed="left" />
<vxe-column field="name" title="库存商品" />
<vxe-column field="name" title="库存食材" />
<vxe-column field="stock" title="库存" />
<vxe-column field="unit" title="单位" />
<vxe-column field="quantity" title="数量" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
@@ -94,6 +85,11 @@
<el-input v-model="row.realPrice" />
</template>
</vxe-column>
<vxe-column field="totalNumber" title="总数" :edit-render="{ autoFocus: 'input', placeholder: '请输入' }">
<template #edit="{ row }">
<el-input v-model="row.totalNumber" />
</template>
</vxe-column>
<vxe-column field="totalAmount" title="累计总金额">
<template #default="{ row }">
{{ (Number(row.quantity || 0) * Number(row.realPrice || 0)).toFixed(2) }}
@@ -116,16 +112,16 @@
<el-tooltip effect="dark" content="保存并返回列表页面" placement="top">
<el-button type="primary" plain @click="onSave">保存</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="打印清单" placement="top">
<!-- <el-tooltip effect="dark" content="打印清单" placement="top">
<el-button type="success" plain @click="">打印</el-button>
</el-tooltip>
</el-tooltip> -->
</el-row>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from "vue"
import { ref, reactive, onMounted } from "vue"
import { getObj, addObj, putObj } from "/@/api/canteen/canteenInventoryRecords"
import { getCanteenSequence } from "/@/api/canteen/common"
import { VxeTableEvents, VxeTablePropTypes, type VxeTableInstance } from "vxe-table"
@@ -155,11 +151,11 @@ const baseForm = reactive<any>({
inventoryCode: "",
inventoryDate: formatDate(new Date(), "YYYY-mm-dd"),
handlerUserId: "",
merchantId: "",
supplierId: "",
remark: "",
inventoryType: "1",
orderType: "1",
totalAmount: 0,
})
const state = reactive<any>({
selectDialogVisible: false, // 对话框选择开关
@@ -173,13 +169,13 @@ const dataRules = ref({
inventoryDate: [{ required: true, message: "出入库记录表单据日期不能为空", trigger: "blur" }],
handlerUserId: [{ required: true, message: "经办人不能为空", trigger: "blur" }],
supplierId: [{ required: true, message: "货商不能为空", trigger: "blur" }],
merchantId: [{ required: true, message: "商户不能为空", trigger: "blur" }],
})
// 可编辑表格校验规则
const validRules = ref<VxeTablePropTypes.EditRules<any>>({
quantity: [{ required: true, type: "number", min: 1, message: "必需大于等于0" }],
realPrice: [{ required: true, type: "number", min: 1, message: "必填" }],
totalNumber: [{ required: true, type: "number", min: 1, message: "必填" }],
})
// 初始化数据
@@ -187,14 +183,20 @@ const getInitData = async () => {
baseForm.id = undefined
const id = props.formId
if (id) {
// loading.value = true
// // 获取清单数据
// const [cgPlanData] = await Promise.allSettled([getObj(id)])
// .then((results) => results.map((result) => (result.status === "fulfilled" ? result.value : null)))
// .finally(() => (loading.value = false))
// if (cgPlanData && cgPlanData.code === 0) {
// Object.assign(baseForm, cgPlanData.data)
// }
loading.value = true
// 获取清单数据
const [res] = await Promise.allSettled([getObj(id)])
.then((results) => results.map((result) => (result.status === "fulfilled" ? result.value : null)))
.finally(() => (loading.value = false))
if (res && res.code == 0) {
Object.assign(baseForm, res.data, { items: "" })
state.itemTableForm = res.data.items.map((item: any) => ({
...item,
realPrice: displayPrice(item.realPrice, ""),
totalAmount: displayPrice(item.totalNumber, ""),
price: displayPrice(item.unitPrice, ""),
}))
}
} else {
loading.value = true
// 获取采购入库编号
@@ -205,19 +207,19 @@ const getInitData = async () => {
}
// loading.value = true
// 获取简要商品列表
// 获取简要食材列表
// const [erpSpuSimpleAll] = await Promise.allSettled([getErpSpuSimpleAll()])
// .then((results) => results.map((result) => (result.status === "fulfilled" ? result.value : null)))
// .finally(() => (loading.value = false))
// erpSpuSimpleAll && erpSpuSimpleAll.code === 0 && (state.erpSpuSimpleAll = erpSpuSimpleAll.data)
}
// 点击商品选择
// 点击食材选择
const clickSelectDialog = () => selectDialogRef.value.openDialog()
// 获取被选择的商品行
// 获取被选择的食材行
const getSelectedRows = (selectionRows: any) => {
console.log("被选择的商品行", selectionRows)
console.log("被选择的食材行", selectionRows)
// 筛选新勾选的项并处理
const addedItems = selectionRows
@@ -253,18 +255,21 @@ const removeSelectedRows = () => {
}
// 整理数据
const tableFormItems = state.itemTableForm.map((item: any) => {
return {
// id: item.isNew ? undefined : item.id,
erpMaterialId: item.erpMaterialId,
quantity: item.quantity,
unitPrice: item.price,
realPrice: item.realPrice ? storePrice(item.realPrice) : 0,
totalAmount: (Number(item.quantity || 0) * Number(item.realPrice || 0)).toFixed(2),
stock: item.stock,
remark: item.remark,
}
})
const tableFormItems = () => {
return state.itemTableForm.map((item: any) => {
return {
// id: item.isNew ? undefined : item.id,
erpMaterialId: item.erpMaterialId,
quantity: item.quantity,
unitPrice: storePrice(item.price),
realPrice: item.realPrice ? storePrice(item.realPrice) : 0,
totalAmount: storePrice((Number(item.quantity || 0) * Number(item.realPrice || 0)).toFixed(2)),
stock: item.stock,
remark: item.remark,
totalNumber: item.totalNumber,
}
})
}
// 点击继续添加
const onContinueAdd = async () => {
@@ -285,7 +290,7 @@ const baseFormValidate = async () => {
// 校验可编辑表格 成功返回 true 失败返回 false
const itemTableFormValidate = async () => {
if (state.itemTableForm.length <= 0) {
useMessage().warning("请选择商品")
useMessage().warning("请选择食材")
return false
}
@@ -305,16 +310,16 @@ const itemTableFormValidate = async () => {
// 提交数据 成功返回 true 失败返回 false
const submitData = async () => {
const canteenInventoryRecordsItemDTOS = tableFormItems()
const _pa = {
...baseForm,
totalAmount: canteenInventoryRecordsItemDTOS.reduce((acc: number, cur: any) => acc + Number(cur.totalAmount), 0),
canteenInventoryRecordsItemDTOS,
}
console.log("提交的数据:", _pa)
try {
loading.value = true
const _pa = {
...baseForm,
items: tableFormItems(),
}
console.log("提交的数据:", _pa)
const res = baseForm.id ? await putObj(_pa) : await addObj(_pa)
if (res.code == 0) {
useMessage().success(baseForm.id ? "修改成功" : "添加成功")
@@ -1,112 +0,0 @@
<template>
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
<el-col :span="12" class="mb20">
<el-form-item label="部门id" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入部门id" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="收款金额" prop="receiveAmount">
<el-input v-model="form.receiveAmount" placeholder="请输入收款金额" />
</el-form-item>
</el-col>
</el-form>
</el-dialog>
</template>
<script setup lang="ts" name="CanteenInventoryRecordsDialog">
import { useDict } from "/@/hooks/dict"
import { useMessage } from "/@/hooks/message"
const emit = defineEmits(["refresh"])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
// 定义字典
const { canteen_inventory_type } = useDict("canteen_inventory_type")
// 提交表单数据
const form = reactive({
id: "",
inventoryCode: "",
inventoryDate: "",
inventoryType: "",
linkCode: "",
handlerUserId: "",
checkStatus: "",
checkUserId: "",
checkTime: "",
merchantId: "",
deptId: "",
supplierId: "",
remark: "",
orderType: "",
totalAmount: "",
receiveAmount: "",
processInstanceId: "",
checkReason: "",
})
// 定义校验规则
const dataRules = ref({
inventoryCode: [{ required: true, message: "单据编号(规则生成,出入库编号)不能为空", trigger: "blur" }],
inventoryDate: [{ required: true, message: "单据日期不能为空", trigger: "blur" }],
inventoryType: [{ required: true, message: "单据类型(字典inventory_type)采购入库不能为空", trigger: "blur" }],
})
// 打开弹窗
const openDialog = (id: string) => {
visible.value = true
form.id = ""
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
})
// 获取canteenInventoryRecords信息
if (id) {
form.id = id
getcanteenInventoryRecordsData(id)
}
}
// 提交
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)
useMessage().success(form.id ? "修改成功" : "添加成功")
visible.value = false
emit("refresh")
} catch (err: any) {
useMessage().error(err.msg)
} finally {
loading.value = false
}
}
// 初始化表单数据
const getcanteenInventoryRecordsData = (id: string) => {
// 获取数据
loading.value = true
getObj(id)
.then((res: any) => {
Object.assign(form, res.data)
})
.finally(() => {
loading.value = false
})
}
// 暴露变量
defineExpose({
openDialog,
})
</script>
@@ -60,23 +60,16 @@
<el-table-column type="index" label="#" width="50" />
<el-table-column prop="inventoryCode" label="单据编号" show-overflow-tooltip />
<el-table-column prop="inventoryDate" label="单据日期" show-overflow-tooltip />
<el-table-column prop="inventoryType" label="单据类型(字典inventory_type)采购入库" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="canteen_inventory_type" :value="scope.row.inventoryType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="linkCode" label="来源ID(根据类型指向对应的表,如采购单ID、退货单ID等)" show-overflow-tooltip />
<el-table-column prop="handlerUserId" label="经办人id" show-overflow-tooltip />
<el-table-column prop="productName" label="商品" show-overflow-tooltip />
<el-table-column prop="handlerUserName" label="经办人" show-overflow-tooltip />
<!-- <el-table-column prop="checkStatus" label="审批状态" show-overflow-tooltip /> -->
<!-- <el-table-column prop="checkUserId" label="审批人id" show-overflow-tooltip /> -->
<!-- <el-table-column prop="checkTime" label="审核日期" show-overflow-tooltip /> -->
<el-table-column prop="merchantId" label="商户编号" show-overflow-tooltip />
<el-table-column prop="deptId" label="部门id" show-overflow-tooltip />
<el-table-column prop="supplierId" label="货商" show-overflow-tooltip />
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
<el-table-column prop="orderType" label="订单类型(1入库 2出库)" show-overflow-tooltip />
<el-table-column prop="totalAmount" label="入库总金额" show-overflow-tooltip />
<el-table-column prop="receiveAmount" label="收款金额" show-overflow-tooltip />
<el-table-column prop="totalAmount" label="入库总金额" show-overflow-tooltip>
<template #default="{ row }">{{ displayPrice(row.totalAmount) }}</template>
</el-table-column>
<!-- <el-table-column prop="checkReason" label="审核原因" show-overflow-tooltip /> -->
<el-table-column label="操作" width="150">
<template #default="scope">
@@ -106,10 +99,9 @@
import { BasicTableProps, useTable } from "/@/hooks/table"
import { fetchList, delObjs } from "/@/api/canteen/canteenInventoryRecords"
import { useMessage, useMessageBox } from "/@/hooks/message"
import { useDict } from "/@/hooks/dict"
import { displayPrice } from "/@/utils/formatMoney"
const CtForm = defineAsyncComponent(() => import("./form.vue"))
const { canteen_inventory_type } = useDict("canteen_inventory_type")
const queryRef = ref()
const showSearch = ref(true)
@@ -122,7 +114,7 @@ const formState = reactive<{ formId: string | undefined; showForm: boolean }>({
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
inventoryType: "3",
inventoryType: "1",
},
pageList: fetchList,
})
@@ -157,7 +149,8 @@ const create = () => {
// 点击编辑
const edit = (row: any) => {
row.id ? (formState.formId = row.id) : useMessage().warning("清单id不存在")
if (!row.id) return useMessage().warning("清单id不存在")
formState.formId = row.id
formState.showForm = true
}
@@ -182,6 +175,6 @@ const handleDelete = async (ids: string[]) => {
const formClose = () => {
formState.showForm = false
formState.formId = undefined
fetchList()
getDataList()
}
</script>
@@ -1,9 +1,9 @@
<template>
<el-dialog v-model="dialogVisible" title="选择商品" width="80%" :close-on-click-modal="false" draggable @close="dialogVisible = false">
<el-dialog v-model="dialogVisible" title="选择食材" width="80%" :close-on-click-modal="false" draggable @close="dialogVisible = false">
<el-row>
<el-form :model="queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataListAndSelect">
<el-form-item label="商品名称" prop="name">
<el-input placeholder="请输入商品名称" v-model="queryForm.name" />
<el-form-item label="食材名称" prop="name">
<el-input placeholder="请输入食材名称" v-model="queryForm.name" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataListAndSelect">查询</el-button>
@@ -12,8 +12,8 @@
</el-form>
</el-row>
<el-table
ref="spuMultipleTableRef"
:data="spuDataList"
ref="tableRef"
:data="dataList"
v-loading="loading"
:row-key="(row:any) => row.id"
:reserve-selection="true"
@@ -22,7 +22,7 @@
>
<el-table-column type="selection" width="40" fixed="left" align="center" />
<el-table-column type="index" label="#" width="50" fixed="left" align="center" />
<el-table-column prop="name" label="商品名称" min-width="150px" align="center" show-overflow-tooltip />
<el-table-column prop="name" label="食材名称" min-width="150px" align="center" show-overflow-tooltip />
<el-table-column prop="unit" label="单位" min-width="100px" align="center" show-overflow-tooltip />
<el-table-column prop="stock" label="库存" min-width="80px" align="center" show-overflow-tooltip />
</el-table>
@@ -57,13 +57,13 @@ const props = withDefaults(
)
const queryRef = ref()
const spuMultipleTableRef = ref() // 对话框多选表格ref
const tableRef = ref() // 对话框多选表格ref
const loading = ref(false) // 对话框多选表格loading
const queryForm = reactive<any>({
name: "",
})
const total = ref<number>(0)
const spuDataList = ref<any[]>([]) // 对话框多选表格数据
const dataList = ref<any[]>([]) // 对话框多选表格数据
// 打开弹窗
const openDialog = () => {
@@ -71,36 +71,30 @@ const openDialog = () => {
getDataListAndSelect()
}
// 获取商品数据并且勾选
// 获取食材数据并且勾选
const getDataListAndSelect = async () => {
loading.value = true
try {
const { code, data } = await fetchErpMaterialPageList(queryForm).finally(() => (loading.value = false))
if (code === 0) {
spuDataList.value = data.records.map((item: any) => ({ ...item, erpMaterialId: item.id }))
const { code, data } = await fetchErpMaterialPageList(queryForm)
if (code == 0) {
dataList.value = data.records.map((item: any) => ({ ...item, erpMaterialId: item.id }))
total.value = data.total
// 保存当前已选中的行
// const currentSelectedRows = spuMultipleTableRef.value?.getSelectionRows() || []
// 清空表格数据后重新设置
nextTick(() => {
// 合并当前页面数据中的已选行和之前保存的已选行
const rowsToSelect = [
// ...currentSelectedRows,
...props.selectedRows.filter((row) => spuDataList.value.some((item) => item.erpMaterialId === row.erpMaterialId)),
...props.selectedRows.filter((row) => dataList.value.some((item) => item.erpMaterialId === row.erpMaterialId)),
]
// 去重
const uniqueRowsToSelect = Array.from(new Map(rowsToSelect.map((row) => [row.erpMaterialId, row])).values())
// 为匹配的行设置选中状态
uniqueRowsToSelect.forEach((row) => {
const targetRow = spuDataList.value.find((item) => item.erpMaterialId === row.erpMaterialId)
targetRow && spuMultipleTableRef.value?.toggleRowSelection(targetRow, true)
const targetRow = dataList.value.find((item) => item.erpMaterialId === row.erpMaterialId)
targetRow && tableRef.value?.toggleRowSelection(targetRow, true)
})
})
}
} catch (error) {
spuDataList.value = []
loading.value = false
dataList.value = []
} finally {
loading.value = false
}
@@ -121,21 +115,21 @@ const resetQuery = () => {
getDataListAndSelect()
}
// 点击商品列表表格行
// 点击食材列表表格行
const rowClick = (row: any) => {
spuMultipleTableRef.value.toggleRowSelection(row)
tableRef.value.toggleRowSelection(row)
}
// 商品选择对话框确认
// 食材选择对话框确认
const dialogConfirm = () => {
const $table = spuMultipleTableRef.value
const $table = tableRef.value
if ($table) {
// 获取所有选中的行,包括其他页面的选择
const currentSelectedRows = $table.getSelectionRows()
// 合并当前选中的行和之前已选的行(排除当前页面的行)
const allSelectedRows = [
...currentSelectedRows,
...props.selectedRows.filter((row) => !spuDataList.value.some((item) => item.erpMaterialId === row.erpMaterialId)),
...props.selectedRows.filter((row) => !dataList.value.some((item) => item.erpMaterialId === row.erpMaterialId)),
]
// 去重
const uniqueSelectedRows = Array.from(new Map(allSelectedRows.map((row) => [row.erpMaterialId, row])).values())
@@ -1,209 +0,0 @@
<template>
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
:close-on-click-modal="false" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="单据类型(字典inventory_type)" prop="inventoryType">
<el-input v-model="form.inventoryType" placeholder="请输入单据类型(字典inventory_type)"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="原料id" prop="erpMaterialId">
<el-input v-model="form.erpMaterialId" placeholder="请输入原料id"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="商户编号" prop="merchantId">
<el-input v-model="form.merchantId" placeholder="请输入商户编号"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="部门id" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入部门id"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="出入库数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入出入库数量"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="单价" prop="unitPrice">
<el-input v-model="form.unitPrice" placeholder="请输入单价"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="总金额" prop="totalAmount">
<el-input v-model="form.totalAmount" placeholder="请输入总金额"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="税率%" prop="taxRate">
<el-input v-model="form.taxRate" placeholder="请输入税率%"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="税前金额" prop="taxAmount">
<el-input v-model="form.taxAmount" placeholder="请输入税前金额"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="货商" prop="supplierId">
<el-input v-model="form.supplierId" placeholder="请输入货商"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="订单类型(1入库 2出库)" prop="orderType">
<el-input v-model="form.orderType" placeholder="请输入订单类型(1入库 2出库)"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="出入库关联id" prop="inventoryId">
<el-input v-model="form.inventoryId" placeholder="请输入出入库关联id"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="总数" prop="totalNumber">
<el-input v-model="form.totalNumber" placeholder="请输入总数"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="账面数量" prop="accountNumber">
<el-input v-model="form.accountNumber" placeholder="请输入账面数量"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="实际数量" prop="realNumber">
<el-input v-model="form.realNumber" placeholder="请输入实际数量"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="实际单价" prop="realPrice">
<el-input v-model="form.realPrice" placeholder="请输入实际单价"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="CanteenInventoryRecordsItemDialog">
import { useDict } from '/@/hooks/dict';
import { useMessage } from "/@/hooks/message";
import { getObj, addObj, putObj } from '/@/api/canteen/canteenInventoryRecordsItem'
import { rule } from '/@/utils/validate';
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const visible = ref(false)
const loading = ref(false)
// 定义字典
// 提交表单数据
const form = reactive({
id:'',
inventoryType: '',
erpMaterialId: '',
merchantId: '',
deptId: '',
quantity: '',
unitPrice: '',
totalAmount: '',
taxRate: '',
taxAmount: '',
supplierId: '',
remark: '',
orderType: '',
inventoryId: '',
totalNumber: '',
accountNumber: '',
realNumber: '',
realPrice: '',
});
// 定义校验规则
const dataRules = ref({
})
// 打开弹窗
const openDialog = (id: string) => {
visible.value = true
form.id = ''
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields();
});
// 获取canteenInventoryRecordsItem信息
if (id) {
form.id = id
getcanteenInventoryRecordsItemData(id)
}
};
// 提交
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);
useMessage().success(form.id ? '修改成功' : '添加成功');
visible.value = false;
emit('refresh');
} catch (err: any) {
useMessage().error(err.msg);
} finally {
loading.value = false;
}
};
// 初始化表单数据
const getcanteenInventoryRecordsItemData = (id: string) => {
// 获取数据
loading.value = true
getObj(id).then((res: any) => {
Object.assign(form, res.data)
}).finally(() => {
loading.value = false
})
};
// 暴露变量
defineExpose({
openDialog
});
</script>
+335 -110
View File
@@ -1,134 +1,359 @@
<template>
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
:close-on-click-modal="false" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="加工日期" prop="productionTime">
<el-input v-model="form.productionTime" placeholder="请输入加工日期"/>
</el-form-item>
</el-col>
<el-dialog
:title="form.id ? '编辑生产记录' : '新增生产记录'"
v-model="visible"
width="1300px"
:close-on-click-modal="false"
draggable
>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="120px"
v-loading="loading"
>
<!-- 主表信息 -->
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="加工日期" prop="productionTime">
<el-date-picker
v-model="form.productionTime"
type="date"
placeholder="选择日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
:disabled-date="disabledDate"
class="w-full"
/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="加工人" prop="handlerUser">
<el-input v-model="form.handlerUser" placeholder="请输入加工人"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="加工批次" prop="recordCode">
<el-input v-model="form.recordCode" placeholder="请输入加工批次"/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="生产模板">
<div style="display: flex; align-items: center;">
<el-button @click="openTemplateDialog">选择生产模板</el-button>
<span v-if="selectedTemplates.length" style="margin-left: 12px;">
已选{{ selectedTemplates.length }}个模板
</span>
</div>
</el-form-item>
</el-col>
</el-row>
<el-col :span="12" class="mb20">
<el-form-item label="加工人" prop="handlerUser">
<el-input v-model="form.handlerUser" placeholder="请输入加工人"/>
<!-- 子表信息 -->
<el-form-item label="生产详情" style="margin-top: 16px;">
<el-table
:data="form.productionDetailList"
border
:span-method="spanMethod"
style="width: 100%"
>
<el-table-column prop="dishName" label="菜品名称" width="180" />
<el-table-column label="生成数量" width="120">
<template #default="{ row }">
<el-input-number
v-model="row.produceQuantity"
:min="1"
:precision="0"
@change="updateProduceQuantity(row)"
/>
</template>
</el-table-column>
<el-table-column prop="materialName" label="食材名称" width="180" />
<el-table-column prop="materialUnit" label="单位" width="80" />
<el-table-column prop="baseUsage" label="基准用量" width="120" />
<el-table-column prop="lossRate" label="损耗率" width="120">
<template #default="{ row }">{{ row.lossRate }}%</template>
</el-table-column>
<el-table-column label="实际用量" width="180">
<template #default="{ row }">
<el-input-number
v-model="row.actualUsage"
:min="0"
:precision="2"
@change="calculateActualOutput(row)"
/>
</template>
</el-table-column>
<el-table-column label="实际产出" width="180">
<template #default="{ row }">
<el-input-number
v-model="row.actualOutput"
:min="0"
:precision="2"
/>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-form>
<el-col :span="12" class="mb20">
<el-form-item label="主id" prop="recordId">
<el-input v-model="form.recordId" placeholder="请输入主id"/>
</el-form-item>
</el-col>
<template #footer>
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
</template>
<el-col :span="12" class="mb20">
<el-form-item label="加工批次号" prop="recordCode">
<el-input v-model="form.recordCode" placeholder="请输入加工批次号"/>
</el-form-item>
</el-col>
<!-- 生产模板选择弹窗 -->
<el-dialog
v-model="templateDialogVisible"
title="选择生产模板"
width="800px"
append-to-body
:close-on-click-modal="false"
>
<div class="h-[500px] flex flex-col">
<el-form :inline="true" class="mb-4">
<el-form-item>
<el-input
v-model="templateQuery.templateName"
placeholder="模板名称"
clearable
@keyup.enter="searchTemplate"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchTemplate">搜索</el-button>
</el-form-item>
</el-form>
<el-col :span="12" class="mb20">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注"/>
</el-form-item>
</el-col>
<div class="flex-1 overflow-auto">
<el-table
ref="templateTable"
:data="templateList"
border
@selection-change="handleSelectionChange"
height="100%"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="templateName" label="模板名称" />
<el-table-column prop="dishName" label="菜品名称" />
<el-table-column prop="baseOutput" label="基准产出量" />
</el-table>
</div>
<el-col :span="12" class="mb20">
<el-form-item label="部门id" prop="deptId">
<el-input v-model="form.deptId" placeholder="请输入部门id"/>
</el-form-item>
</el-col>
<div class="mt-4">
<pagination
v-model:current-page="templateQuery.current"
v-model:page-size="templateQuery.size"
:total="templateTotal"
@size-change="val => { templateQuery.size = val; templateQuery.current = 1; searchTemplate() }"
@current-change="val => { templateQuery.current = val; searchTemplate() }"
/>
</div>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
</span>
</template>
<div class="dialog-footer" style="margin-top: 20px;">
<el-button @click="templateDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmTemplateSelection">确定</el-button>
</div>
</div>
</el-dialog>
</el-dialog>
</template>
<script setup lang="ts" name="CanteenProductionRecordDialog">
import { useDict } from '/@/hooks/dict';
import { useMessage } from "/@/hooks/message";
import { getObj, addObj, putObj } from '/@/api/canteen/canteenProductionRecord'
import { rule } from '/@/utils/validate';
const emit = defineEmits(['refresh']);
<script setup lang="ts">
import { ref, reactive } from 'vue'
import type { FormInstance } from 'element-plus'
import { useMessage } from "/@/hooks/message"
import { fetchGetSelectTemplatePage } from "/@/api/canteen/canteenProductionTemplate"
import { addObj, putObj } from "/@/api/canteen/canteenProductionRecord"
import Pagination from '/@/components/Pagination/index.vue'
// 定义变量内容
const dataFormRef = ref();
const visible = ref(false)
const loading = ref(false)
// 定义字典
const formRef = ref<FormInstance>()
const selectedTemplates = ref<any[]>([])
// 提交表单数据
const form = reactive({
id:'',
productionTime: '',
handlerUser: '',
recordId: '',
recordCode: '',
remark: '',
deptId: '',
});
// 定义校验规则
const dataRules = ref({
productionTime: [{required: true, message: '加工日期不能为空', trigger: 'blur'}],
recordCode: [{required: true, message: '加工批次号不能为空', trigger: 'blur'}],
// 生产模板选择相关
const templateDialogVisible = ref(false)
const templateList = ref<any[]>([])
const templateTotal = ref(0)
const templateQuery = reactive({
current: 1,
size: 10,
templateName: ''
})
// 打开弹窗
const openDialog = (id: string) => {
visible.value = true
form.id = ''
const form = reactive({
id: undefined,
productionTime: new Date().toISOString().split('T')[0],
handlerUser: '',
recordCode: '',
productionDetailList: [] as any[]
})
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields();
});
const rules = {
productionTime: [{ required: true, message: '请选择加工日期', trigger: 'change' }],
handlerUser: [{ required: true, message: '请输入加工人', trigger: 'blur' }],
recordCode: [{ required: true, message: '请输入加工批次', trigger: 'blur' }]
}
// 获取canteenProductionRecord信息
if (id) {
form.id = id
getcanteenProductionRecordData(id)
}
};
// 行合并逻辑
const rowspanMap = ref<number[]>([])
const generateRowspanMap = () => {
const map: number[] = []
let currentDish = ''
let count = 0
let startIndex = 0
// 提交
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);
useMessage().success(form.id ? '修改成功' : '添加成功');
visible.value = false;
emit('refresh');
} catch (err: any) {
useMessage().error(err.msg);
} finally {
loading.value = false;
}
};
// 初始化表单数据
const getcanteenProductionRecordData = (id: string) => {
// 获取数据
loading.value = true
getObj(id).then((res: any) => {
Object.assign(form, res.data)
}).finally(() => {
loading.value = false
form.productionDetailList.forEach((item, index) => {
if (item.dishName !== currentDish) {
if (currentDish !== '') {
for (let i = startIndex; i < index; i++) {
map[i] = i === startIndex ? count : 0
}
}
currentDish = item.dishName
startIndex = index
count = 1
} else {
count++
}
})
};
// 暴露变量
// 处理最后一组
if (currentDish !== '') {
for (let i = startIndex; i < form.productionDetailList.length; i++) {
map[i] = i === startIndex ? count : 0
}
}
rowspanMap.value = map
}
// 单元格合并方法
const spanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
if (columnIndex === 0 || columnIndex === 1) { // 合并菜品名称和生成数量列
const span = rowspanMap.value[rowIndex]
return {
rowspan: span,
colspan: span > 0 ? 1 : 0
}
}
return { rowspan: 1, colspan: 1 }
}
const emit = defineEmits(['refresh'])
const disabledDate = (time: Date) => {
return time.getTime() > Date.now()
}
const searchTemplate = async () => {
try {
const res = await fetchGetSelectTemplatePage(templateQuery)
templateList.value = res.data.records
templateTotal.value = res.data.total
} catch (error) {
console.error('获取生产模板列表失败:', error)
}
}
const handleSelectionChange = (selection: any[]) => {
selectedTemplates.value = selection
}
const confirmTemplateSelection = () => {
if (selectedTemplates.value.length === 0) {
useMessage().warning('请至少选择一个模板')
return
}
form.productionDetailList = []
selectedTemplates.value.forEach(template => {
const details = template.canteenProductionTemplateDetailList.map((item: any) => ({
...item,
dishName: template.dishName,
materialUnit: item.unit, // 正确传递食材单位字段
produceQuantity: 1,
actualUsage: item.baseUsage * 1,
actualOutput: 0,
manualModified: false
}))
form.productionDetailList.push(...details)
})
generateRowspanMap()
templateDialogVisible.value = false
}
// 更新生成数量
const updateProduceQuantity = (changedRow: any) => {
const dishName = changedRow.dishName
form.productionDetailList.forEach(row => {
if (row.dishName === dishName) {
row.produceQuantity = changedRow.produceQuantity
if (!row.manualModified) {
row.actualUsage = Number((row.baseUsage * changedRow.produceQuantity).toFixed(2))
calculateActualOutput(row)
}
}
})
}
// 计算实际产出
const calculateActualOutput = (row: any) => {
row.manualModified = true
const lossAmount = row.actualUsage * (row.lossRate / 100)
row.actualOutput = Number((row.actualUsage - lossAmount).toFixed(2))
}
const openTemplateDialog = () => {
templateDialogVisible.value = true
selectedTemplates.value = []
searchTemplate()
}
const openDialog = (row?: any) => {
visible.value = true
if (row) {
Object.assign(form, row)
generateRowspanMap()
} else {
form.id = undefined
form.productionTime = new Date().toISOString().split('T')[0]
form.handlerUser = ''
form.recordCode = ''
form.productionDetailList = []
selectedTemplates.value = []
}
}
const submitForm = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid) => {
if (valid) {
loading.value = true
try {
const api = form.id ? putObj : addObj
const res = await api(form)
if (res.code === 0) {
useMessage().success(form.id ? '修改成功' : '新增成功')
emit('refresh')
visible.value = false
} else {
useMessage().error(res.msg || (form.id ? '修改失败' : '新增失败'))
}
} catch (error: any) {
useMessage().error(error.msg || (form.id ? '修改失败' : '新增失败'))
} finally {
loading.value = false
}
}
})
}
defineExpose({
openDialog
});
</script>
})
</script>`
@@ -29,14 +29,14 @@
<div class="mb-4">
<el-button type="primary" @click="openMaterialDialog">选择食材</el-button>
</div>
<el-table :data="form.canteenProductionTemplateDetailList" border>
<el-table-column label="食材名称" prop="materialName" />
<el-table-column label="基准用量" width="200">
<template #default="{ row }">
<el-input-number
v-model="row.baseUsage"
:min="0"
<el-input-number
v-model="row.baseUsage"
:min="0"
:precision="2"
style="width: 120px"
/>
@@ -45,9 +45,9 @@
<el-table-column label="损耗率" width="200">
<template #default="{ row }">
<div style="display: flex; align-items: center;">
<el-input-number
v-model="row.lossRate"
:min="0"
<el-input-number
v-model="row.lossRate"
:min="0"
:max="100"
:precision="2"
style="width: 120px"
@@ -371,7 +371,7 @@ const closeDialog = () => {
const submitForm = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid) => {
if (valid) {
loading.value = true
@@ -397,4 +397,4 @@ const submitForm = async () => {
defineExpose({
openDialog
})
</script>
</script>
@@ -36,8 +36,8 @@
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="40" />
<el-table-column prop="templateName" label="模版名称" show-overflow-tooltip/>
<el-table-column prop="dishId" label="菜品id" show-overflow-tooltip/>
<el-table-column prop="baseOutput" label="基准产出量(碗)" show-overflow-tooltip/>
<!-- <el-table-column prop="dishId" label="菜品id" show-overflow-tooltip/>-->
<el-table-column prop="baseOutput" label="基准产出量" show-overflow-tooltip/>
<el-table-column label="操作" width="150">
<template #default="scope">
<el-button icon="edit-pen" text type="primary" v-auth="'canteen_canteenProductionTemplate_edit'"
+2 -11
View File
@@ -32,27 +32,18 @@
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table :data="state.dataList" v-loading="state.loading" border
<el-table :data="state.dataList" v-loading="state.loading" border
:cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle"
@selection-change="selectionChangHandle"
@sort-change="sortChangeHandle">
<el-table-column type="selection" width="40" align="center" />
<el-table-column type="index" label="#" width="40" />
<el-table-column prop="supplierName" label="货商名称" show-overflow-tooltip/>
<el-table-column prop="address" label="货商地址" show-overflow-tooltip/>
<el-table-column prop="phone" label="电话号码" show-overflow-tooltip/>
<el-table-column prop="tax" label="税号" show-overflow-tooltip/>
<el-table-column prop="linkName" label="联系人" show-overflow-tooltip/>
<el-table-column prop="openAccount" label="开户行账号" show-overflow-tooltip/>
<el-table-column prop="email" label="邮箱地址" show-overflow-tooltip/>
<el-table-column prop="deptId" label="所属部门ID" show-overflow-tooltip/>
<el-table-column prop="supplierType" label="货商类别" show-overflow-tooltip/>
<el-table-column prop="supplierArea" label="货商地区" show-overflow-tooltip/>
<el-table-column prop="passwordModifyTime" label="修改时间" show-overflow-tooltip/>
<el-table-column prop="openName" label="开户行" show-overflow-tooltip/>
<el-table-column prop="contractNumber" label="合同号" show-overflow-tooltip/>
<el-table-column prop="status" label="状态 0使用 1禁用" show-overflow-tooltip/>
<el-table-column prop="pinyinCod" label="拼音简码" show-overflow-tooltip/>
<el-table-column label="操作" width="150">
<template #default="scope">
<el-button icon="edit-pen" text type="primary" v-auth="'canteen_canteenSupplier_edit'"
@@ -140,4 +131,4 @@ const handleDelete = async (ids: string[]) => {
useMessage().error(err.msg);
}
};
</script>
</script>