refactor(wms): 移除未使用的采购计划相关组件和代码

清理未使用的采购计划面板组件(RecommendPurchasePanel, clac, merger, CreatePurchasePanel, transfer, stockin)及相关代码
移除未使用的采购计划明细API导入
删除未使用的供应商、产品BOM和库存流水视图文件
This commit is contained in:
砂糖
2025-11-13 13:40:22 +08:00
parent 88b7e37712
commit 6f448faa45
15 changed files with 0 additions and 4381 deletions

View File

@@ -1,291 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="存储位置" prop="warehouseId">
<WarehouseSelect v-model="queryParams.warehouseId" placeholder="请选择仓库/库区/库位" clearable @change="getList" />
</el-form-item>
<MaterialSelect :itemType.sync="queryParams.itemType" :itemId.sync="queryParams.itemId" @change="getList" />
<el-form-item label="变动时间" prop="changeTime">
<el-date-picker
clearable
v-model="queryParams.changeTime"
type="daterange"
value-format="yyyy-MM-dd"
placeholder="请选择实际库存变动时间">
</el-date-picker>
</el-form-item>
<el-form-item label="批次号" prop="batchNo">
<el-input v-model="queryParams.batchNo" placeholder="请输入批次号" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="stockLogList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="存储位置" align="center" prop="warehouseName" />
<el-table-column label="物品ID" align="center" prop="itemId">
<template slot-scope="scope">
<RawMaterialInfo v-if="scope.row.itemType == 'raw_material'" :material-id="scope.row.itemId" />
<ProductInfo v-else-if="scope.row.itemType == 'product' || scope.row.itemType == 'semi'" :product-id="scope.row.itemId" />
</template>
</el-table-column>
<el-table-column label="物品类型" align="center" prop="itemType">
<template slot-scope="scope">
<dict-tag :options="dict.type.stock_item_type" :value="scope.row.itemType" />
</template>
</el-table-column>
<el-table-column label="变动数量" align="center" prop="changeQty" />
<el-table-column label="变动后的库存数量" align="center" prop="afterQty" />
<el-table-column label="变动类型" align="center" prop="changeType" />
<el-table-column label="库存数量变动时间" align="center" prop="changeTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.changeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="批次号" align="center" prop="batchNo" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改库存流水对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="存储位置" prop="warehouseId" disabled>
<el-input v-model="form.warehouseId" placeholder="请输入仓库/库区/库位ID" disabled />
</el-form-item>
<el-form-item label="物品信息" prop="itemId" disabled>
<RawMaterialInfo v-if="form.itemType == 'raw_material'" :material-id="form.itemId" />
<ProductInfo v-else-if="form.itemType == 'product' || form.itemType == 'semi'" :product-id="form.itemId" />
</el-form-item>
<el-form-item label="变动数量" prop="changeQty" disabled>
<el-input v-model="form.changeQty" placeholder="请输入变动数量" disabled />
</el-form-item>
<el-form-item label="库存数量" prop="afterQty" disabled>
<el-input v-model="form.afterQty" placeholder="请输入变动后的库存数量" disabled />
</el-form-item>
<el-form-item label="变动时间" prop="changeTime" disabled>
<el-date-picker clearable
v-model="form.changeTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择实际库存变动时间" disabled>
</el-date-picker>
</el-form-item>
<el-form-item label="批次号" prop="batchNo">
<el-input v-model="form.batchNo" placeholder="请输入批次号" disabled/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listStockLog, getStockLog, updateStockLog } from "@/api/wms/stockLog";
import WarehouseSelect from '@/components/KLPService/WarehouseSelect/index.vue';
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect/index.vue';
import ProductSelect from '@/components/KLPService/ProductSelect/index.vue';
import SemiSelect from '@/components/KLPService/SemiSelect/index.vue';
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo.vue';
import ProductInfo from '@/components/KLPService/Renderer/ProductInfo.vue';
import MaterialSelect from '@/components/KLPService/MaterialSelect/index.vue';
export default {
name: "StockLog",
components: {
WarehouseSelect,
RawMaterialSelect,
ProductSelect,
RawMaterialInfo,
ProductInfo,
SemiSelect,
MaterialSelect
},
dicts: ['stock_item_type'],
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 库存流水表格数据
stockLogList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
warehouseId: undefined,
itemId: undefined,
itemType: undefined,
changeQty: undefined,
afterQty: undefined,
changeType: undefined,
changeTime: undefined,
batchNo: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
}
};
},
created() {
const itemId = this.$route.query.itemId;
const itemType = this.$route.query.itemType;
if (itemId && itemType) {
this.queryParams.itemId = itemId;
this.queryParams.itemType = itemType;
}
this.getList();
},
methods: {
/** 查询库存流水列表 */
getList() {
this.loading = true;
const { changeTime, ...payload } = {
...this.queryParams,
startTime: this.queryParams.changeTime ? this.queryParams.changeTime[0] + ' 00:00:00' : undefined,
endTime: this.queryParams.changeTime ? this.queryParams.changeTime[1] + ' 23:59:59' : undefined
}
listStockLog(payload).then(response => {
this.stockLogList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: undefined,
warehouseId: undefined,
itemId: undefined,
itemType: undefined,
changeQty: undefined,
afterQty: undefined,
changeType: undefined,
changeTime: undefined,
remark: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined,
delFlag: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const id = row.id || this.ids
getStockLog(id).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改库存流水";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.id != null) {
updateStockLog(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 导出按钮操作 */
handleExport() {
this.download('klp/stockLog/export', {
...this.queryParams
}, `stockLog_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -40,7 +40,6 @@ import { listStockIoDetail } from '@/api/wms/stockIoDetail';
import { listOrder } from '@/api/wms/order';
import { listOrderDetail } from '@/api/wms/orderDetail';
import { listPurchasePlan } from '@/api/wms/purchasePlan';
import { listPurchasePlanDetail } from '@/api/wms/purchasePlanDetail';
import { mapState } from 'vuex';
import { ITEM_TYPE } from '../../../utils/enums';

View File

@@ -1,311 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="50px">
<el-form-item label="产品" prop="productId">
<ProductSelect v-model="queryParams.productId" placeholder="请选择产品" />
</el-form-item>
<el-form-item label="原材料" prop="rawMaterialId">
<RawMaterialSelect v-model="queryParams.rawMaterialId" placeholder="请选择原材料" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input
v-model="queryParams.unit"
placeholder="请输入单位"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="productBomList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="产品" align="center" prop="productName">
<template slot-scope="scope">
<ProductInfo :productId="scope.row.productId" />
</template>
</el-table-column>
<el-table-column label="原材料" align="center" prop="rawMaterialName">
<template slot-scope="scope">
<RawMaterialInfo :materialId="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="原材料数量" align="center" prop="quantity" />
<el-table-column label="单位" align="center" prop="unit" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改产品参数产品-原材料清单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="产品" prop="productId">
<ProductSelect v-model="form.productId" placeholder="请选择产品" />
</el-form-item>
<el-form-item label="原材料" prop="rawMaterialId">
<RawMaterialSelect v-model="form.rawMaterialId" placeholder="请选择原材料" />
</el-form-item>
<el-form-item label="原材料数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入每个产品所需原材料数量" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入单位" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listProductBom, getProductBom, delProductBom, addProductBom, updateProductBom } from "@/api/wms/productBom";
import ProductSelect from "@/components/KLPService/ProductSelect";
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
export default {
name: "ProductBom",
components: {
ProductSelect,
RawMaterialSelect,
ProductInfo,
RawMaterialInfo
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 产品参数(产品-原材料清单)表格数据
productBomList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
productId: undefined,
rawMaterialId: undefined,
quantity: undefined,
unit: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
productId: [
{ required: true, message: "产品ID不能为空", trigger: "blur" }
],
rawMaterialId: [
{ required: true, message: "原材料ID不能为空", trigger: "blur" }
],
quantity: [
{ required: true, message: "每个产品所需原材料数量不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "单位不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询产品参数(产品-原材料清单)列表 */
getList() {
this.loading = true;
listProductBom(this.queryParams).then(response => {
this.productBomList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
bomId: undefined,
productId: undefined,
rawMaterialId: undefined,
quantity: undefined,
unit: undefined,
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.bomId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加产品参数(产品-原材料清单)";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const bomId = row.bomId || this.ids
getProductBom(bomId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改产品参数(产品-原材料清单)";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.bomId != null) {
updateProductBom(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addProductBom(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const bomIds = row.bomId || this.ids;
this.$modal.confirm('是否确认删除产品参数(产品-原材料清单)编号为"' + bomIds + '"的数据项?').then(() => {
this.loading = true;
return delProductBom(bomIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/productBom/export', {
...this.queryParams
}, `productBom_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -1,544 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="120px">
<el-form-item label="采购计划编号" prop="planCode">
<el-input
v-model="queryParams.planCode"
placeholder="请输入采购计划编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="queryParams.owner" :multiple="false" placeholder="请选择负责人" clearable />
</el-form-item>
<el-form-item label="关联订单ID" prop="orderId">
<el-input
v-model="queryParams.orderId"
placeholder="请输入关联订单ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="purchasePlanList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="采购计划编号" align="center" prop="planCode" />
<el-table-column label="负责人" align="center" prop="owner" />
<!-- <el-table-column label="关联订单ID" align="center" prop="orderId" /> -->
<!-- <el-table-column label="状态" align="center" prop="status" /> -->
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-document"
@click="handleAccessory(scope.row)"
>附件</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleDetail(scope.row)"
>详情</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改采购计划主对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="采购计划编号" prop="planCode">
<el-input v-model="form.planCode" placeholder="请输入采购计划编号" />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="form.owner" :multiple="false" placeholder="请选择负责人" />
</el-form-item>
<el-form-item label="关联订单ID" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入关联订单ID" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 订单选择弹窗 -->
<el-dialog title="选择订单" :visible.sync="orderSelectOpen" width="800px" append-to-body>
<el-form :model="orderQueryParams" ref="orderQueryForm" size="small" :inline="true" label-width="80px">
<el-form-item label="订单编号" prop="orderCode">
<el-input
v-model="orderQueryParams.orderCode"
placeholder="请输入订单编号"
clearable
@keyup.enter.native="handleOrderQuery"
/>
</el-form-item>
<el-form-item label="客户名称" prop="customerName">
<el-input
v-model="orderQueryParams.customerName"
placeholder="请输入客户名称"
clearable
@keyup.enter.native="handleOrderQuery"
/>
</el-form-item>
<el-form-item label="销售经理" prop="salesManager">
<el-input v-model="orderQueryParams.salesManager" :multiple="false" placeholder="请选择销售经理" clearable />
</el-form-item>
<el-form-item label="订单状态" prop="orderStatus">
<el-select v-model="orderQueryParams.orderStatus" placeholder="请选择订单状态" clearable>
<el-option
v-for="dict in dict.type.order_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleOrderQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetOrderQuery">重置</el-button>
</el-form-item>
</el-form>
<KLPTable v-loading="orderLoading" :data="orderList" @row-click="handleOrderSelect" style="cursor: pointer;">
<el-table-column label="订单编号" align="center" prop="orderCode" />
<el-table-column label="客户名称" align="center" prop="customerName" />
<el-table-column label="销售经理" align="center" prop="salesManager" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
</KLPTable>
<pagination
v-show="orderTotal>0"
:total="orderTotal"
:page.sync="orderQueryParams.pageNum"
:limit.sync="orderQueryParams.pageSize"
@pagination="getOrderList"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="orderSelectOpen = false"> </el-button>
</div>
</el-dialog>
<!-- 推荐采购计划弹窗 -->
<el-dialog title="推荐采购计划" :visible.sync="recommendOpen" width="1200px" append-to-body>
<div v-if="selectedOrderId">
<p style="margin-bottom: 20px; color: #666;">
当前选择订单ID: <strong>{{ selectedOrderId }}</strong>
<el-button type="text" @click="handleReSelectOrder" style="margin-left: 10px;">重新选择订单</el-button>
</p>
<PurchasePlanClac
:orderId="selectedOrderId"
@confirm="handleRecommendConfirm"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="recommendOpen = false"> </el-button>
</div>
</el-dialog>
<!-- 采购计划详情弹窗 -->
<el-dialog title="采购计划详情" :visible.sync="detailOpen" width="1400px" append-to-body>
<div v-if="selectedPlanId">
<p style="margin-bottom: 20px; color: #666;">
当前采购计划ID: <strong>{{ selectedPlanId }}</strong>
</p>
<PurchasePlanDetail
ref="purchasePlanDetail"
:planId="selectedPlanId"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="detailOpen = false"> </el-button>
</div>
</el-dialog>
<!-- 新增采购计划底部抽屉 -->
<el-drawer
title="新增采购计划"
:visible.sync="addDrawerOpen"
direction="btt"
size="98%"
:with-header="true"
:wrapperClosable="false"
custom-class="purchase-drawer"
append-to-body
mask-closable="false"
>
<Transfer
:order-id="''"
:recommend-data="{}"
@confirm="onAddConfirm"
/>
</el-drawer>
<el-dialog title="附件查看" :visible.sync="accessoryOpen" width="800px" append-to-body>
<FileUpload v-model="accessory" @success="handleAccessorySuccess" />
</el-dialog>
</div>
</template>
<script>
import { listPurchasePlan, getPurchasePlan, delPurchasePlan, addPurchasePlan, updatePurchasePlan } from "@/api/wms/purchasePlan";
import { listOrder } from "@/api/wms/order";
import PurchasePlanClac from "./panels/clac.vue";
import PurchasePlanDetail from "./panels/detail.vue";
import { EOrderStatus } from "../../../utils/enums";
import UserSelect from '@/components/KLPService/UserSelect'
import Transfer from './panels/transfer.vue'
import FileUpload from '@/components/FileUpload'
export default {
name: "PurchasePlan",
components: {
PurchasePlanClac,
PurchasePlanDetail,
UserSelect,
Transfer,
FileUpload,
},
dicts: ['order_status'],
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 采购计划主表格数据
purchasePlanList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 订单选择弹窗
orderSelectOpen: false,
// 推荐采购计划弹窗
recommendOpen: false,
// 采购计划详情弹窗
detailOpen: false,
// 选中的订单ID
selectedOrderId: null,
// 选中的采购计划ID
selectedPlanId: null,
// 订单列表
orderList: [],
// 订单总数
orderTotal: 0,
// 订单加载状态
orderLoading: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
planCode: undefined,
owner: undefined,
orderId: undefined,
status: undefined,
},
// 订单查询参数
orderQueryParams: {
pageNum: 1,
pageSize: 20,
orderCode: undefined,
customerName: undefined,
salesManager: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
planCode: [
{ required: true, message: "采购计划编号不能为空", trigger: "blur" }
],
owner: [
{ required: true, message: "负责人不能为空", trigger: "blur" }
],
status: [
{ required: true, message: "状态不能为空", trigger: "change" }
],
},
addDrawerOpen: false,
accessory: '',
accessoryOpen: false,
};
},
mounted() {
this.getList();
},
methods: {
/** 查询采购计划主列表 */
getList() {
this.loading = true;
listPurchasePlan(this.queryParams).then(response => {
this.purchasePlanList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
planId: undefined,
planCode: undefined,
owner: undefined,
orderId: undefined,
status: undefined,
remark: undefined,
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.planId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.addDrawerOpen = true;
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const planId = row.planId || this.ids
getPurchasePlan(planId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改采购计划主";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.planId != null) {
updatePurchasePlan(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addPurchasePlan(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const planIds = row.planId || this.ids;
this.$modal.confirm('是否确认删除采购计划主编号为"' + planIds + '"的数据项?').then(() => {
this.loading = true;
return delPurchasePlan(planIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/purchasePlan/export', {
...this.queryParams
}, `purchasePlan_${new Date().getTime()}.xlsx`)
},
/** 推荐采购计划按钮操作 */
handleRecommend() {
this.orderSelectOpen = true;
this.getOrderList();
},
/** 获取订单列表 */
getOrderList() {
this.orderLoading = true;
listOrder({...this.orderQueryParams, orderStatus: EOrderStatus.NEW}).then(response => {
this.orderList = response.rows;
this.orderTotal = response.total;
this.orderLoading = false;
});
},
/** 订单查询 */
handleOrderQuery() {
this.orderQueryParams.pageNum = 1;
this.getOrderList();
},
/** 重置订单查询 */
resetOrderQuery() {
this.orderQueryParams = {
pageNum: 1,
pageSize: 20,
orderCode: undefined,
customerName: undefined,
salesManager: undefined,
orderStatus: undefined,
};
this.handleOrderQuery();
},
/** 选择订单 */
handleOrderSelect(row) {
this.selectedOrderId = row.orderId;
this.orderSelectOpen = false;
this.recommendOpen = true;
},
/** 重新选择订单 */
handleReSelectOrder() {
this.recommendOpen = false;
this.orderSelectOpen = true;
},
/** 推荐采购计划确认 */
handleRecommendConfirm(data) {
console.log('推荐采购计划数据:', data);
this.$modal.msgSuccess("推荐采购计划已生成");
this.recommendOpen = false;
this.getList(); // 刷新列表
},
/** 详情按钮操作 */
handleDetail(row) {
this.selectedPlanId = row.planId;
this.detailOpen = true;
},
onAddConfirm() {
this.addDrawerOpen = false;
this.getList();
},
handleAccessory(row) {
this.accessoryOpen = true;
this.form = row;
this.accessory = row.attachmentInfo;
},
handleAccessorySuccess(fileList) {
updatePurchasePlan({
planId: this.form.planId,
attachmentInfo: fileList.map(item => item.ossId).join(',')
}).then(response => {
this.$modal.msgSuccess("附件上传成功");
this.getList();
});
}
}
};
</script>
<style>
.purchase-drawer .el-drawer__body {
padding: 24px;
background: #f9f9f9;
overflow-y: auto;
}
</style>

View File

@@ -1,439 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="60px">
<el-form-item label="原材料" prop="rawMaterialId">
<RawMaterialSelect v-model="queryParams.rawMaterialId" placeholder="请选择原材料" can-add />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="queryParams.owner" placeholder="请输入负责人" />
</el-form-item>
<!-- 远程搜索供应商 -->
<!-- <el-form-item label="供应商" prop="supplierId">
<VendorSelect v-model="queryParams.supplierId" />
</el-form-item> -->
<el-form-item label="关联订单" prop="orderId">
<el-input v-model="queryParams.orderId" placeholder="请输入关联订单ID" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
@click="handleUpdate">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
@click="handleDelete">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button type="info" plain icon="el-icon-plus" size="mini" :disabled="!hasArrivalItems"
@click="handleCreateStockIn">创建入库单</el-button>
</el-col> -->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="purchasePlanDetailList" @selection-change="handleSelectionChange"
ref="purchasePlanDetailTable">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="明细ID" align="center" prop="detailId" v-if="true"/>
<el-table-column label="采购计划ID" align="center" prop="planId" /> -->
<el-table-column label="计划编号" align="center" prop="detailCode" />
<el-table-column label="原材料" align="center">
<template slot-scope="scope">
<RawMaterialInfo :material-id="scope.row.rawMaterialId">
<template #default="{ material }">
{{ material.rawMaterialName }}<span v-if="material.rawMaterialCode">({{ material.rawMaterialCode
}})</span>
</template>
</RawMaterialInfo>
</template>
</el-table-column>
<el-table-column label="参数" align="center">
<template slot-scope="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="负责人" align="center" prop="owner" />
<el-table-column label="供应商" align="center" prop="supplierName" />
<el-table-column label="合同编号" align="center" prop="contractNo" />
<el-table-column label="计划采购数量" align="center" prop="quantity" />
<el-table-column label="单位" align="center" prop="unit" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<el-select v-model="scope.row.status"
size="large"
@change="handleStatusChange(scope.row, scope.row.status, scope.row.status)">
<el-option v-for="item in dict.type.pruchase_detail_status" :key="item.value" :label="item.label"
:value="parseInt(item.value)">
<dict-tag :options="dict.type.pruchase_detail_status" :value="item.value" />
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
<!-- 状态修改按钮 -->
<el-button v-if="scope.row.status === EPurchaseDetailStatus.NEW" size="mini" type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.ONWAY, '在途')">设为在途</el-button>
<el-button v-if="scope.row.status === EPurchaseDetailStatus.ONWAY" size="mini" type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.ARRIVAL, '到货')">设为到货</el-button>
<el-button v-if="scope.row.status === EPurchaseDetailStatus.ARRIVAL" size="mini" type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.REVIEW, '待审核')">设为待审核</el-button>
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.REVIEW || scope.row.status === EPurchaseDetailStatus.FINISH"
size="mini" type="text" icon="el-icon-document"
@click="handleUploadQualityCertificate(scope.row)">质保单</el-button>
<el-button v-if="scope.row.status === EPurchaseDetailStatus.REVIEW" size="mini" type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.FINISH, '采购完成')">设为完成</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 添加或修改采购计划明细对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="计划编号" prop="detailCode">
<el-input v-model="form.detailCode" placeholder="请输入计划编号" />
</el-form-item>
<el-form-item label="原材料" prop="rawMaterialId">
<RawMaterialSelect v-model="form.rawMaterialId" placeholder="请选择原材料" @change="onRawMaterialChange" can-add />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="form.owner" placeholder="请输入负责人" />
</el-form-item>
<!-- 远程搜索供应商 -->
<el-form-item label="供应商" prop="supplierId">
<VendorSelect v-model="form.supplierId" />
</el-form-item>
<!-- 远程搜索合同 -->
<el-form-item label="合同" prop="contractId">
<el-select remote filterable v-model="form.contractId" placeholder="请选择合同"
:remote-method="remoteSearchContract" :loading="contractLoading">
<el-option v-for="item in contractList" :key="item.contractId" :label="item.contractNo"
:value="item.contractId" />
</el-select>
</el-form-item>
<el-form-item label="采购数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入计划采购数量" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入单位" :disabled="true" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 入库单创建对话框 -->
<stock-in-dialog :visible.sync="stockInVisible" :selected-items="selectedArrivalItems"
@success="handleStockInSuccess" />
<el-dialog title="上传质保单" :visible.sync="uploadQualityCertificateOpen" width="800px" append-to-body>
<quality-certicate :info="uploadQualityCertificateInfo" @confirm="handleUploadQualityCertificateConfirm" />
</el-dialog>
</div>
</template>
<script>
import { listPurchasePlanDetail, getPurchasePlanDetail, delPurchasePlanDetail, addPurchasePlanDetail, updatePurchasePlanDetail } from "@/api/wms/purchasePlanDetail";
import { listContract } from "@/api/wms/contract";
import { EPurchaseDetailStatus } from "@/utils/enums";
import StockInDialog from "./panels/stockin.vue";
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect';
import UserSelect from '@/components/KLPService/UserSelect'
import { RawMaterialInfo } from '@/components/KLPService';
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
import QualityCerticate from './panels/qualityCerticate.vue'
import VendorSelect from '@/components/KLPService/VendorSelect/index.vue';
export default {
name: "PurchasePlanDetail",
components: {
StockInDialog,
RawMaterialSelect,
UserSelect,
RawMaterialInfo,
BomInfoMini,
QualityCerticate,
VendorSelect
},
dicts: ['pruchase_detail_status'],
data() {
return {
EPurchaseDetailStatus,
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 采购计划明细表格数据
purchasePlanDetailList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
rawMaterialId: undefined,
owner: undefined,
quantity: undefined,
unit: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
detailCode: [
{ required: true, message: "计划编号不能为空", trigger: "blur" }
],
rawMaterialId: [
{ required: true, message: "原材料ID不能为空", trigger: "blur" }
],
owner: [
{ required: true, message: "负责人不能为空", trigger: "blur" }
],
quantity: [
{ required: true, message: "计划采购数量不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "单位不能为空", trigger: "blur" }
],
},
// 入库单相关
stockInVisible: false,
selectedArrivalItems: [],
uploadQualityCertificateOpen: false,
uploadQualityCertificateInfo: undefined,
vendorList: [],
vendorLoading: false,
contractList: [],
contractLoading: false
};
},
computed: {
/** 是否有到货状态的明细 */
hasArrivalItems() {
return this.purchasePlanDetailList.some(item => item.status === EPurchaseDetailStatus.ARRIVAL);
}
},
created() {
this.getList();
this.remoteSearchContract('');
},
methods: {
remoteSearchContract(query) {
this.contractLoading = true;
listContract({ contractNo: query, pageNum: 1, pageSize: 10 }).then(response => {
this.contractList = response.rows;
}).finally(() => {
this.contractLoading = false;
});
},
/** 查询采购计划明细列表 */
getList() {
this.loading = true;
listPurchasePlanDetail(this.queryParams).then(response => {
this.purchasePlanDetailList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
detailCode: undefined,
detailId: undefined,
rawMaterialId: undefined,
owner: undefined,
quantity: undefined,
unit: undefined,
remark: undefined,
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.detailId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加采购计划明细";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const detailId = row.detailId || this.ids
getPurchasePlanDetail(detailId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改采购计划明细";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.detailId != null) {
updatePurchasePlanDetail(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addPurchasePlanDetail(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const detailIds = row.detailId || this.ids;
this.$modal.confirm('是否确认删除采购计划明细编号为"' + detailIds + '"的数据项?').then(() => {
this.loading = true;
return delPurchasePlanDetail(detailIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/purchasePlanDetail/export', {
...this.queryParams
}, `purchasePlanDetail_${new Date().getTime()}.xlsx`)
},
/** 状态修改按钮操作 */
handleStatusChange(row, status, label) {
// this.$modal.confirm('是否确认将采购计划明细编号为"' + row.detailId + '"的状态改为"' + label + '"').then(() => {
this.loading = true;
updatePurchasePlanDetail({ detailId: row.detailId, status: status }).then(response => {
this.$modal.msgSuccess("状态修改成功");
this.getList();
}).catch(error => {
console.error(error);
this.$modal.msgError("状态修改失败");
}).finally(() => {
this.loading = false;
});
// });
},
handleUploadQualityCertificateConfirm() {
this.uploadQualityCertificateOpen = false;
this.handleStatusChange(this.uploadQualityCertificateInfo, EPurchaseDetailStatus.FINISH, '采购完成');
},
/** 创建入库单按钮操作 */
handleCreateStockIn() {
// 获取用户选中的明细
const selectedItems = this.$refs.purchasePlanDetailTable.selection;
if (selectedItems.length === 0) {
this.$modal.msgWarning("请先选择要入库的明细");
return;
}
// 检查选中的明细是否都是到货状态
const nonArrivalItems = selectedItems.filter(item => item.status !== EPurchaseDetailStatus.ARRIVAL);
if (nonArrivalItems.length > 0) {
this.$modal.msgWarning("只能选择到货状态的明细进行入库操作");
return;
}
this.selectedArrivalItems = selectedItems;
this.stockInVisible = true;
},
/** 入库单创建成功后的回调 */
handleStockInSuccess() {
this.$modal.msgSuccess("入库单创建成功,相关明细状态已更新为采购完成");
this.getList();
this.stockInVisible = false;
this.selectedArrivalItems = []; // 清空选中的明细
},
onRawMaterialChange(rawMaterial) {
if (rawMaterial && rawMaterial.unit) {
this.form.unit = rawMaterial.unit;
}
},
handleUploadQualityCertificate(row) {
this.uploadQualityCertificateOpen = true;
this.uploadQualityCertificateInfo = row;
}
}
};
</script>

View File

@@ -1,255 +0,0 @@
<template>
<div class="purchase-plan-transfer">
<!-- 采购单信息区 -->
<el-card class="section-card" shadow="never">
<div slot="header" class="section-title">采购单信息</div>
<el-form :model="mainForm" :rules="mainFormRules" ref="mainFormRef" :inline="true" label-width="120px" style="margin-bottom: 0;" v-loading="formLoading" element-loading-text="正在加载主数据...">
<el-form-item label="计划编号" prop="planCode">
<el-input v-model="mainForm.planCode" placeholder="请输入计划编号" style="width: 200px;" />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="mainForm.owner" :multiple="false" placeholder="请填写负责人" style="width: 200px;" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="mainForm.remark" placeholder="请输入备注" style="width: 300px;" />
</el-form-item>
</el-form>
</el-card>
<div>
<!-- 采购单明细区 -->
<el-card shadow="never">
<div slot="header" class="section-title">采购单明细</div>
<KLPTable
:data="purchaseList"
@selection-change="handleRightSelectionChange"
style="width: 100%"
ref="rightTable"
border
>
<el-table-column type="selection" width="55" />
<el-table-column prop="rawMaterialId" label="原材料">
<template #default="scope">
<RawMaterialSelect v-model="scope.row.rawMaterialId" placeholder="请选择原材料" />
</template>
</el-table-column>
<el-table-column label="参数" align="center">
<template #default="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column prop="unit" label="单位" />
<el-table-column prop="onTheWay" label="在途" />
<el-table-column prop="inventory" label="在库" />
<el-table-column prop="demand" label="所需" />
<el-table-column prop="quantity" label="计划采购数">
<template #default="scope">
<el-input-number :controls=false controls-position="right" v-model="scope.row.quantity" :min="0" size="small" />
</template>
</el-table-column>
<el-table-column prop="owner" label="负责人">
<template #default="scope">
<el-input v-model="scope.row.owner" :multiple="false" placeholder="请填写负责人" size="small" />
</template>
</el-table-column>
<el-table-column prop="remark" label="备注">
<template #default="scope">
<el-input v-model="scope.row.remark" size="small" />
</template>
</el-table-column>
</KLPTable>
</el-card>
</div>
<div style="margin-top: 20px; text-align: right;" v-loading="submitLoading" element-loading-text="正在提交数据...">
<el-button type="primary" @click="confirm" :loading="submitLoading">{{ submitLoading ? '提交中...' : '确认' }}</el-button>
</div>
</div>
</template>
<script>
import { createPurchasePlan } from '@/api/wms/purchasePlan'
import { listRawMaterial } from '@/api/wms/rawMaterial'
import UserSelect from '@/components/KLPService/UserSelect'
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect'
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
export default {
name: 'CreatePurchasePanel',
components: { UserSelect, RawMaterialSelect, BomInfoMini },
props: {
orderId: {
type: [String, Number],
required: true
},
recommendData: {
type: Object,
default: () => ({})
}
},
data() {
return {
// 原材料表格相关
rawMaterialList: [],
total: 0,
pageNum: 1,
pageSize: 20,
rawMaterialLoading: false,
leftSelected: [],
rightSelected: [],
rawMaterialNameFilter: '',
// 采购列表
purchaseList: [],
// 细化的loading状态
formLoading: false,
submitLoading: false,
mainForm: {
planCode: '',
owner: '',
remark: ''
},
mainFormRules: {
planCode: [
{ required: true, message: '请输入计划编号', trigger: 'blur' }
],
owner: [
{ required: true, message: '请输入负责人', trigger: 'blur' }
]
}
}
},
watch: {
recommendData: {
immediate: true,
handler(newVal) {
if (newVal && newVal.detailList) {
this.purchaseList = newVal.detailList
this.mainForm = {
planCode: newVal.planCode || '',
owner: newVal.owner || '',
remark: newVal.remark || ''
}
}
}
}
},
mounted() {
this.fetchRawMaterials();
},
methods: {
// 原材料分页查询
fetchRawMaterials() {
this.rawMaterialLoading = true;
listRawMaterial({ pageNum: this.pageNum, pageSize: this.pageSize, rawMaterialName: this.rawMaterialNameFilter }).then(res => {
// 过滤掉已在采购列表中的原材料
const purchaseIds = this.purchaseList.map(item => item.rawMaterialId);
this.rawMaterialList = (res.rows || []).filter(item => !purchaseIds.includes(item.rawMaterialId));
this.total = res.total || 0;
this.rawMaterialLoading = false;
}).catch(() => {
this.rawMaterialLoading = false;
});
},
handlePageChange(page) {
this.pageNum = page;
this.fetchRawMaterials();
},
handleSelectionChange(selection) {
this.leftSelected = selection;
},
handleRightSelectionChange(selection) {
this.rightSelected = selection;
},
handleRawMaterialFilter() {
this.pageNum = 1;
this.fetchRawMaterials();
},
addToPurchase() {
// 去重添加
const ids = this.purchaseList.map(item => item.rawMaterialId);
const newItems = this.leftSelected.filter(item => !ids.includes(item.rawMaterialId)).map(item => ({
...item,
quantity: 0,
owner: '',
remark: ''
}));
this.purchaseList = this.purchaseList.concat(newItems);
this.$refs.leftTable.clearSelection();
this.fetchRawMaterials();
},
removeFromPurchase() {
const removeIds = this.rightSelected.map(item => item.rawMaterialId);
this.purchaseList = this.purchaseList.filter(item => !removeIds.includes(item.rawMaterialId));
this.$refs.rightTable.clearSelection();
this.fetchRawMaterials();
},
confirm() {
this.submitLoading = true;
this.$refs.mainFormRef.validate(async(valid) => {
if (!valid) {
this.$message.error('请完整填写主数据信息');
this.submitLoading = false;
return;
}
// 校验采购列表数据除remark外都不能为空
const filtered = this.purchaseList.filter(row => row.rawMaterialId && row.rawMaterialId !== '');
const invalid = filtered.some(row => {
return !row.rawMaterialId || !row.owner || !row.unit || row.quantity === '' || row.quantity === null || row.quantity === undefined;
});
if (invalid) {
this.$message.error('请完整填写所有必填项');
this.submitLoading = false;
return;
}
// 合并主数据和明细数据
const submitData = {
...this.mainForm,
orderId: this.orderId,
detailList: filtered
};
await createPurchasePlan(submitData);
this.$emit('confirm', submitData);
this.submitLoading = false;
});
}
}
}
</script>
<style scoped>
.purchase-plan-transfer {
display: flex;
flex-direction: column;
}
.section-card {
margin-bottom: 20px;
}
.section-title {
font-weight: bold;
font-size: 16px;
color: #333;
}
.transfer-content {
display: flex;
align-items: flex-start;
}
.left-table {
width: 30%;
}
.right-table {
width: 60%;
}
.transfer-actions {
width: 10%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.transfer-actions .el-button {
margin: 10px 0;
}
.filter-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
}
</style>

View File

@@ -1,57 +0,0 @@
<template>
<div>
<el-button v-if="showButton" type="primary" @click="handleRecommend" :loading="loading">推荐采购计划</el-button>
</div>
</template>
<script>
import { recommendPurchasePlan } from '@/api/wms/purchasePlan'
export default {
name: 'RecommendPurchasePanel',
props: {
orderId: {
type: [String, Number],
required: true
},
showButton: {
type: Boolean,
default: true
}
},
data() {
return {
loading: false
}
},
watch: {
orderId: {
handler(newVal) {
this.handleRecommend()
}
}
},
mounted() {
if (!this.showButton) {
this.handleRecommend();
}
},
methods: {
async handleRecommend() {
if (!this.orderId) {
this.$message.error('缺少订单ID');
return;
}
this.loading = true;
try {
const res = await recommendPurchasePlan(this.orderId);
this.$emit('recommend', res.data);
} catch (e) {
this.$message.error('推荐失败');
} finally {
this.loading = false;
}
}
}
}
</script>

View File

@@ -1,115 +0,0 @@
<template>
<div class="purchase-plan-transfer">
<!-- 推荐采购计划自动推荐无按钮 -->
<recommend-purchase-panel :order-id="orderId" :show-button="false" @recommend="onRecommend" />
<!-- 创建采购计划表单及明细 -->
<create-purchase-panel
:order-id="orderId"
:recommend-data="recommendData"
@confirm="onConfirm"
/>
</div>
</template>
<script>
import RecommendPurchasePanel from './RecommendPurchasePanel.vue'
import CreatePurchasePanel from './CreatePurchasePanel.vue'
import { updateOrder } from '@/api/wms/order'
import { EOrderStatus } from '@/utils/enums'
export default {
name: 'PurchasePlanClac',
components: {
RecommendPurchasePanel,
CreatePurchasePanel
},
props: {
orderId: {
type: [String, Number],
required: true
}
},
data() {
return {
recommendData: {},
EOrderStatus: EOrderStatus
}
},
methods: {
onRecommend(data) {
console.log('获取推荐数据', data)
this.recommendData = data
},
onConfirm(submitData) {
console.log('calc层', submitData)
updateOrder({
orderId: this.orderId,
orderStatus: this.EOrderStatus.PRODUCTIONING,
}).then(response => {
this.$emit('confirm', submitData)
})
}
}
}
</script>
<style scoped>
.purchase-plan-transfer {
display: flex;
flex-direction: column;
}
.section-card {
margin-bottom: 20px;
}
.section-title {
font-weight: bold;
font-size: 16px;
color: #333;
}
.transfer-content {
display: flex;
align-items: flex-start;
}
.left-table {
width: 30%;
}
.right-table {
width: 60%;
}
.transfer-actions {
width: 10%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.transfer-actions .el-button {
margin: 10px 0;
}
.global-loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.9);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 2000;
border-radius: 4px;
}
.global-loading-overlay p {
margin-top: 10px;
color: #409EFF;
font-size: 14px;
}
.filter-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
}
</style>

View File

@@ -1,496 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-plus"
size="mini"
:disabled="!hasArrivalItems"
@click="handleCreateStockIn"
>创建入库单</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="purchasePlanDetailList" @selection-change="handleSelectionChange" ref="purchasePlanDetailTable">
<el-table-column type="selection" width="55" align="center" />
<!-- <el-table-column label="明细ID" align="center" prop="detailId" v-if="true"/>
<el-table-column label="采购计划ID" align="center" prop="planId" /> -->
<el-table-column label="原材料" align="center">
<template slot-scope="scope">
<RawMaterialInfo :material-id="scope.row.rawMaterialId">
<template #default="{ material }">
{{ material.rawMaterialName }}<span v-if="material.rawMaterialCode">({{ material.rawMaterialCode }})</span>
</template>
</RawMaterialInfo>
</template>
</el-table-column>
<el-table-column label="参数" align="center">
<template slot-scope="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="负责人" align="center" prop="owner" />
<el-table-column label="供应商" align="center" prop="supplierName" />
<el-table-column label="合同编号" align="center" prop="contractNo" />
<el-table-column label="计划采购数量" align="center" prop="quantity" />
<el-table-column label="单位" align="center" prop="unit" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<el-select v-model="scope.row.status" @change="handleStatusChange(scope.row, scope.row.status, scope.row.status)">
<el-option v-for="item in dict.type.pruchase_detail_status" :key="item.value" :label="item.label" :value="parseInt(item.value)">
<dict-tag :options="dict.type.pruchase_detail_status" :value="item.value" />
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<!-- 状态修改按钮 -->
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.NEW"
size="mini"
type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.ONWAY, '在途')"
>设为在途</el-button>
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.ONWAY"
size="mini"
type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.ARRIVAL, '到货')"
>设为到货</el-button>
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.ARRIVAL"
size="mini"
type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.REVIEW, '待审核')"
>设为待审核</el-button>
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.REVIEW || scope.row.status === EPurchaseDetailStatus.FINISH"
size="mini"
type="text"
icon="el-icon-document"
@click="handleUploadQualityCertificate(scope.row)"
>质保单</el-button>
<el-button
v-if="scope.row.status === EPurchaseDetailStatus.REVIEW"
size="mini"
type="text"
icon="el-icon-refresh"
@click="handleStatusChange(scope.row, EPurchaseDetailStatus.FINISH, '采购完成')"
>设为完成</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改采购计划明细对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="原材料" prop="rawMaterialId">
<RawMaterialSelect v-model="form.rawMaterialId" placeholder="请选择原材料" @change="onRawMaterialChange" can-add />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="form.owner" placeholder="请输入负责人" />
</el-form-item>
<!-- 远程搜索供应商 -->
<el-form-item label="供应商" prop="supplierId">
<VendorSelect v-model="form.supplierId" />
</el-form-item>
<!-- 远程搜索合同 -->
<el-form-item label="合同" prop="contractId">
<el-select remote filterable v-model="form.contractId" placeholder="请选择合同" :remote-method="remoteSearchContract" :loading="contractLoading">
<el-option v-for="item in contractList" :key="item.contractId" :label="item.contractNo" :value="item.contractId" />
</el-select>
</el-form-item>
<el-form-item label="采购数量" prop="quantity">
<el-input v-model="form.quantity" placeholder="请输入计划采购数量" />
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入单位" :disabled="true" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 入库单创建对话框 -->
<stock-in-dialog
:visible.sync="stockInVisible"
:selected-items="selectedArrivalItems"
@success="handleStockInSuccess"
/>
<el-dialog title="上传质保单" :visible.sync="uploadQualityCertificateOpen" width="800px" append-to-body>
<quality-certicate :info="uploadQualityCertificateInfo" @confirm="handleUploadQualityCertificateConfirm" />
</el-dialog>
</div>
</template>
<script>
import { listPurchasePlanDetail, getPurchasePlanDetail, delPurchasePlanDetail, addPurchasePlanDetail, updatePurchasePlanDetail } from "@/api/wms/purchasePlanDetail";
import { listSupplier } from "@/api/wms/supplier";
import { listContract } from "@/api/wms/contract";
import { EPurchaseDetailStatus } from "@/utils/enums";
import StockInDialog from "./stockin.vue";
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect';
import UserSelect from '@/components/KLPService/UserSelect'
import { RawMaterialInfo } from '@/components/KLPService';
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
import QualityCerticate from './qualityCerticate.vue'
import VendorSelect from '@/components/KLPService/VendorSelect/index.vue';
export default {
name: "PurchasePlanDetail",
components: {
StockInDialog,
RawMaterialSelect,
UserSelect,
RawMaterialInfo,
BomInfoMini,
QualityCerticate,
VendorSelect
},
props: {
planId: {
type: [String, Number],
default: null
}
},
dicts: ['pruchase_detail_status'],
data() {
return {
EPurchaseDetailStatus,
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 采购计划明细表格数据
purchasePlanDetailList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
planId: undefined,
rawMaterialId: undefined,
owner: undefined,
quantity: undefined,
unit: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
planId: [
{ required: true, message: "采购计划ID不能为空", trigger: "blur" }
],
rawMaterialId: [
{ required: true, message: "原材料ID不能为空", trigger: "blur" }
],
owner: [
{ required: true, message: "负责人不能为空", trigger: "blur" }
],
quantity: [
{ required: true, message: "计划采购数量不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "单位不能为空", trigger: "blur" }
],
},
// 入库单相关
stockInVisible: false,
selectedArrivalItems: [],
uploadQualityCertificateOpen: false,
uploadQualityCertificateInfo: undefined,
vendorList: [],
vendorLoading: false,
contractList: [],
contractLoading: false
};
},
computed: {
/** 是否有到货状态的明细 */
hasArrivalItems() {
return this.purchasePlanDetailList.some(item => item.status === EPurchaseDetailStatus.ARRIVAL);
}
},
created() {
this.getList();
this.remoteSearchContract('');
},
watch: {
planId: {
handler(newVal) {
if (newVal) {
this.queryParams.planId = newVal;
this.getList();
}
},
immediate: true
}
},
methods: {
remoteSearchContract(query) {
this.contractLoading = true;
listContract({ contractNo: query, pageNum: 1, pageSize: 10 }).then(response => {
this.contractList = response.rows;
}).finally(() => {
this.contractLoading = false;
});
},
/** 查询采购计划明细列表 */
getList() {
this.loading = true;
listPurchasePlanDetail(this.queryParams).then(response => {
this.purchasePlanDetailList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
detailId: undefined,
planId: undefined,
rawMaterialId: undefined,
owner: undefined,
quantity: undefined,
unit: undefined,
remark: undefined,
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.detailId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
if (this.planId) {
this.form.planId = this.planId;
}
this.open = true;
this.title = "添加采购计划明细";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const detailId = row.detailId || this.ids
getPurchasePlanDetail(detailId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改采购计划明细";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.detailId != null) {
updatePurchasePlanDetail(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addPurchasePlanDetail(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const detailIds = row.detailId || this.ids;
this.$modal.confirm('是否确认删除采购计划明细编号为"' + detailIds + '"的数据项?').then(() => {
this.loading = true;
return delPurchasePlanDetail(detailIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/purchasePlanDetail/export', {
...this.queryParams
}, `purchasePlanDetail_${new Date().getTime()}.xlsx`)
},
/** 状态修改按钮操作 */
handleStatusChange(row, status, label) {
// this.$modal.confirm('是否确认将采购计划明细编号为"' + row.detailId + '"的状态改为"' + label + '"').then(() => {
this.loading = true;
updatePurchasePlanDetail({ detailId: row.detailId, status: status }).then(response => {
this.$modal.msgSuccess("状态修改成功");
this.getList();
}).catch(error => {
console.error(error);
this.$modal.msgError("状态修改失败");
}).finally(() => {
this.loading = false;
});
// });
},
handleUploadQualityCertificateConfirm() {
this.uploadQualityCertificateOpen = false;
this.handleStatusChange(this.uploadQualityCertificateInfo, EPurchaseDetailStatus.FINISH, '采购完成');
},
/** 创建入库单按钮操作 */
handleCreateStockIn() {
// 获取用户选中的明细
const selectedItems = this.$refs.purchasePlanDetailTable.selection;
if (selectedItems.length === 0) {
this.$modal.msgWarning("请先选择要入库的明细");
return;
}
// 检查选中的明细是否都是到货状态
const nonArrivalItems = selectedItems.filter(item => item.status !== EPurchaseDetailStatus.ARRIVAL);
if (nonArrivalItems.length > 0) {
this.$modal.msgWarning("只能选择到货状态的明细进行入库操作");
return;
}
this.selectedArrivalItems = selectedItems;
this.stockInVisible = true;
},
/** 入库单创建成功后的回调 */
handleStockInSuccess() {
this.$modal.msgSuccess("入库单创建成功,相关明细状态已更新为采购完成");
this.getList();
this.stockInVisible = false;
this.selectedArrivalItems = []; // 清空选中的明细
},
onRawMaterialChange(rawMaterial) {
if (rawMaterial && rawMaterial.unit) {
this.form.unit = rawMaterial.unit;
}
},
handleUploadQualityCertificate(row) {
this.uploadQualityCertificateOpen = true;
this.uploadQualityCertificateInfo = row;
}
}
};
</script>

View File

@@ -1,165 +0,0 @@
<!-- 当新旧质保单不一致时, 需要用户选择处理方式, 在这个组件内处理通过confirm回调来通知父组件完成 -->
<template>
<div>
<el-row>
<el-alert title="质保单处理结果与历史质保单不一致,请选择处理方式" type="warning" />
</el-row>
<el-row :gutter="20" style="margin-top: 20px;">
<el-col :span="12">
<KLPTable :data="oldResult" style="width: 100%">
<el-table-column prop="attrKey" label="属性名称" />
<el-table-column prop="attrValue" label="属性值" />
</KLPTable>
</el-col>
<el-col :span="12">
<!-- 默认全部选中 -->
<KLPTable :data="newResult" style="width: 100%" @selection-change="handleSelectionChange" :default-sort="{ prop: 'attrKey', order: 'ascending' }">
<el-table-column type="selection" width="55" />
<el-table-column prop="attrKey" label="属性名称">
<template slot-scope="scope">
<el-input v-model="scope.row.attrKey" />
</template>
</el-table-column>
<el-table-column prop="attrValue" label="属性值">
<template slot-scope="scope">
<el-input v-model="scope.row.attrValue" />
</template>
</el-table-column>
</KLPTable>
</el-col>
</el-row>
<el-row style="margin-top: 20px;">
<el-col>
<el-radio-group v-model="uploadQualityCertificateForm.qualityCertificateType">
<el-radio v-for="item in options" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-col>
</el-row>
<el-button type="primary" @click="handleConfirm">确认</el-button>
</div>
</template>
<script>
import { addBomItem } from '@/api/wms/bomItem'
import { addBom } from '@/api/wms/bom'
import { updateRawMaterial, addRawMaterial, getRawMaterial } from '@/api/wms/rawMaterial'
import { updatePurchasePlanDetail } from '@/api/wms/purchasePlanDetail'
export default {
name: 'Merger',
props: {
oldResult: {
type: Array,
required: true
},
newResult: {
type: Array,
required: true
},
info: {
type: Object,
required: true
}
},
data() {
return {
options: [
{
label: '使用旧的质保单',
value: 1
},
{
label: '使用新的质保单',
value: 2
},
{
label: '创建新物料',
value: 3
}
],
uploadQualityCertificateForm: {
qualityCertificateType: 1
},
selection: []
}
},
methods: {
handleSelectionChange(selection) {
this.selection = selection;
},
async handleConfirm() {
if (!this.uploadQualityCertificateForm.qualityCertificateType) {
this.$modal.msgError('请选择处理方式');
return;
}
this.$emit('confirm', {
status: 'start',
})
try {
if (this.uploadQualityCertificateForm.qualityCertificateType === 1) {
// 什么都不需要做,直接完成就可以
console.log('使用旧的质保单');
}
else if (this.uploadQualityCertificateForm.qualityCertificateType === 2) {
// 创建一个新的参数
const bom = await addBom({
bomName: 'N' + new Date().getTime(),
bomCode: 'N' + new Date().getTime(),
})
// 将参数ID赋值给对应的materialId
await updateRawMaterial({
rawMaterialId: this.info.rawMaterialId,
bomId: bom.data.bomId,
})
// 逐项创建参数Item, 只创建选中的
for (let i = 0; i < this.selection.length; i++) {
await addBomItem({
bomId: bom.data.bomId,
attrKey: this.selection[i].attrKey,
attrValue: this.selection[i].attrValue,
})
}
this.$store.dispatch('category/getBomMap');
this.$store.dispatch('category/getRawMaterialMap');
} else if (this.uploadQualityCertificateForm.qualityCertificateType === 3) {
// 创建一个新的参数
const bom = await addBom({
bomName: 'N' + new Date().getTime(),
bomCode: 'N' + new Date().getTime(),
})
// 逐项创建参数Item
for (let i = 0; i < this.selection.length; i++) {
await addBomItem({
bomId: bom.data.bomId,
attrKey: this.selection[i].attrKey,
attrValue: this.selection[i].attrValue,
})
}
// 创建一个新的物料,使用原有物料的信息, code使用时间戳
const { rawMaterialId, rawMaterialCode, ...rawMaterial } = (await getRawMaterial(this.info.rawMaterialId)).data
const newMaterial = await addRawMaterial({
...rawMaterial,
bomId: bom.data.bomId,
rawMaterialCode: 'N' + new Date().getTime(),
})
// 修改采购单据赋值为新的物料
await updatePurchasePlanDetail({
detailId: this.info.detailId,
rawMaterialId: newMaterial.data.rawMaterialId,
})
this.$store.dispatch('category/getBomMap');
this.$store.dispatch('category/getRawMaterialMap');
}
this.$emit('confirm', {
status: 'success',
})
} catch {
this.$emit('confirm', {
status: 'error',
})
}
}
}
}
</script>

View File

@@ -1,411 +0,0 @@
<template>
<div v-loading="loading" :element-loading-text="loadingText">
<el-steps :active="1" align-center simple>
<el-step style="cursor: pointer;" @click.native="active = 0" title="上传质保单" icon="el-icon-upload" />
<el-step style="cursor: pointer;" @click.native="active = 1" title="质保单处理" icon="el-icon-edit" />
<el-step style="cursor: pointer;" @click.native="active = 2" title="质保单审核" icon="el-icon-check" />
</el-steps>
<div v-if="active === 0" style="padding: 30px;">
<file-upload v-model="uploadQualityCertificateForm.qualityCertificate" />
</div>
<div v-if="active === 1">
<el-row>
<el-alert title="质保单处理" type="info" />
</el-row>
<!-- 提取质保单信息,选择使用ocr还是使用大模型 -->
<el-row :gutter="20">
<el-col :span="12">
<div
style="border: 1px solid #ccc; border-radius: 10px; padding: 20px; cursor: pointer; text-align: center; position: relative;">
<!-- 齿轮图标绝对定位在左上角 -->
<i class="el-icon-setting"
style="position: absolute; left: 10px; top: 10px; font-size: 20px; color: #606266; cursor: pointer; z-index: 2;"
@click.stop="openKeyListDialog"></i>
<div style="margin-bottom: 10px; display: flex; align-items: center; justify-content: center;">
<span style="font-weight: bold; font-size: 16px;">OCR识别</span>
<el-tooltip content="通过OCR自动识别质保单内容, 仅支持pdf格式" placement="top">
<i class="el-icon-question" style="margin-left: 6px; color: #409EFF; cursor: pointer;"></i>
</el-tooltip>
</div>
<img @click="handleOcr" :src="ocrImage" alt="ocr" style="width: 120px; height: 120px; object-fit: contain;"
append-to-body />
</div>
</el-col>
<el-col :span="12">
<div style="border: 1px solid #ccc; border-radius: 10px; padding: 20px; cursor: pointer; text-align: center;">
<div style="margin-bottom: 10px; display: flex; align-items: center; justify-content: center;">
<span style="font-weight: bold; font-size: 16px;">大模型识别</span>
<el-tooltip content="通过AI大模型识别质保单内容, 仅支持图片格式" placement="top">
<i class="el-icon-question" style="margin-left: 6px; color: #409EFF; cursor: pointer;"></i>
</el-tooltip>
</div>
<img @click="handleModel" :src="modelImage" alt="model"
style="width: 120px; height: 120px; object-fit: contain;" />
</div>
</el-col>
</el-row>
</div>
<div v-if="active === 2">
<div v-if="resultDiff">
<merger :info="info" :old-result="oldResult" :new-result="newResult" @confirm="handleMergerConfirm" />
</div>
<div v-else>
<el-row>
<el-alert title="请核对识别结果是否正确" type="success" />
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<KLPTable :data="newResult" style="width: 100%">
<el-table-column prop="attrKey" label="属性名称" />
<el-table-column prop="attrValue" label="属性值" />
</KLPTable>
</el-col>
<el-col :span="12">
<div>
<img style="width: 100%; height: 100%;" :src="file.url" alt="">
</div>
</el-col>
</el-row>
<el-button type="primary" @click="handleConfirm">确认</el-button>
</div>
</div>
<!-- keyList配置弹窗 -->
<el-dialog title="配置OCR识别字段" :visible.sync="showKeyListDialog" width="400px" append-to-body>
<div>
<el-tag type="info" style="margin-bottom: 8px;">每行一个字段名顺序影响识别</el-tag>
<el-input type="textarea" :rows="8" v-model="keyListInput" placeholder="如:订货单位\n合同号\n产品名称..." />
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="showKeyListDialog = false">取消</el-button>
<el-button type="primary" @click="saveKeyList">保存</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import FileUpload from '@/components/FileUpload'
import { listByIds } from '@/api/system/oss'
import { updatePurchasePlanDetail } from '@/api/wms/purchasePlanDetail'
import { recognizeText, recognizeBomByModel, recognizePdfText, testNet } from '@/api/system/ocr'
import { listBomItem } from '@/api/wms/bomItem'
import { getRawMaterial } from '@/api/wms/rawMaterial'
import Merger from './merger.vue'
import modelImage from '@/assets/images/model.png'
import ocrImage from '@/assets/images/ocr.png'
const so = {
annex: {
loading: '正在保存质保单',
handler: async (vm, newVal) => {
return await updatePurchasePlanDetail({
...vm.info,
annex: newVal
})
}
},
ocr: {
loading: '等待ocr识别结果',
handler: async (vm) => {
function extractData(text) {
// 优先读取localStorage配置的keyList
let keyList = [];
try {
const local = localStorage.getItem('ocrKeyList');
if (local) {
keyList = local.split('\n').map(k => k.trim()).filter(k => k);
}
} catch { }
// 默认keyList
if (!keyList.length) {
keyList = [
"订货单位", "合同号", "产品名称", "执行标准",
"卷号", "原料坯号", "规格", "材质",
"表面状态", "调制度", "切边要求", "包装种类",
"毛重", "净重", "参考长度"
];
}
// 预处理:将复合键合并(如"合同号"、"卷号"等)
let normalizedText = text
.replace(/卷\s*号/g, "卷号")
.replace(/原料\s*坯号/g, "原料坯号")
.replace(/切边\s*要求/g, "切边要求")
.replace(/包装\s*种类/g, "包装种类");
const lines = normalizedText.split(/\r?\n/).filter(line => line.trim());
const result = [];
// 核心数据行处理(跳过首行公司名)
for (let i = 1; i < lines.length; i++) {
let currentLine = lines[i];
let remaining = currentLine;
// 处理单行中的多组键值对
while (remaining) {
let found = false;
// 检查剩余文本是否以已知键开头
for (const key of keyList) {
if (remaining.startsWith(key)) {
found = true;
// 移动到键之后的位置
let afterKey = remaining.substring(key.length).trim();
// 查找下一个键的起始位置
let nextKeyIndex = afterKey.length;
for (const k of keyList) {
const idx = afterKey.indexOf(k);
if (idx > -1 && idx < nextKeyIndex) {
nextKeyIndex = idx;
}
}
// 提取当前键的值
const value = afterKey.substring(0, nextKeyIndex).trim();
result.push({
attrKey: key,
attrValue: key === "毛重" || key === "净重"
? value.replace(/\D/g, "") // 提取数字部分
: value
});
// 更新剩余文本
remaining = afterKey.substring(nextKeyIndex).trim();
break;
}
}
// 如果没有找到更多键,结束循环
if (!found) break;
}
}
return result;
}
const { text } = (await recognizePdfText({ pdfUrl: vm.file.url })).data
console.log(text)
const result = extractData(text)
console.log(result)
vm.newResult = result;
return result;
}
},
model: {
loading: '等待大模型识别结果',
handler: async (vm) => {
// 外网连通测试,如果失败给出提示请打开外网
const flag = await testNet()
if (!flag) {
vm.$modal.msgError('请打开外网连接以使用大模型');
return;
}
const res = await recognizeBomByModel({ imageUrl: vm.file.url })
vm.newResult = res.data.attributes;
vm.$modal.msgSuccess("识别成功");
return res;
}
},
bom: {
loading: '正在处理参数'
},
oss: {
loading: '正在获取质保单',
handler: async (vm, newVal) => {
const res = await listByIds(newVal)
vm.file = res.data[0];
vm.active = 1;
return res.data[0];
}
},
old: {
loading: '正在获取历史质保单',
handler: async (vm, newVal) => {
// 查询对应的bomId
const res = await getRawMaterial(vm.info.rawMaterialId)
const bomId = res.data.bomId;
const bomItemRes = await listBomItem({
bomId,
})
vm.oldResult = bomItemRes.rows;
return bomItemRes.rows;
}
},
compare: {
loading: '正在比较新旧质保单',
handler: async (vm) => {
// 先检查新旧result是否一致
if (vm.oldResult.length !== vm.newResult.length) {
vm.resultDiff = true;
return;
}
// 比较新旧result是否一致
for (let i = 0; i < vm.oldResult.length; i++) {
if (vm.oldResult[i].attrKey !== vm.newResult[i].attrKey || vm.oldResult[i].attrValue !== vm.newResult[i].attrValue) {
vm.resultDiff = true;
return;
}
}
vm.resultDiff = false;
return false;
}
}
}
// 原子操作, 用于细化的进度展示, 無論其同步還是異步一律視作異步函數執行, 並返回一個Promise
const atoms = {
}
export default {
name: 'QualityCerticate',
components: {
FileUpload,
Merger
},
props: {
info: {
type: Object,
default: () => ({})
}
},
watch: {
info: {
handler(newVal) {
this.active = 0;
if (newVal.annex) {
this.uploadQualityCertificateForm.qualityCertificate = newVal.annex;
} else {
this.uploadQualityCertificateForm.qualityCertificate = undefined;
}
},
deep: true,
immediate: true
},
'uploadQualityCertificateForm.qualityCertificate': {
handler(newVal) {
if (newVal) {
this.loadingMethod('oss')
}
this.loadingMethod('annex')
},
immediate: true
}
},
data() {
return {
uploadQualityCertificateForm: {
qualityCertificate: undefined,
qualityCertificateType: undefined,
},
active: 0,
file: undefined,
loading: false,
loadingText: '加载中...',
resultDiff: true,
oldResult: [],
newResult: [],
modelImage,
ocrImage,
showKeyListDialog: false,
keyListInput: '',
}
},
methods: {
handleOcr() {
// 识别file是不是pdf, 只有pdf可以使用ocr
if (!this.file.url.endsWith('.pdf')) {
this.$modal.msgError('质保单不是pdf格式');
return;
}
this.loadingMethod('ocr', async (res) => {
await this.loadingMethod('old')
await this.loadingMethod('compare')
this.active = 2;
})
},
handleModel() {
this.loadingMethod('model', async (res) => {
await this.loadingMethod('old')
await this.loadingMethod('compare')
this.active = 2;
})
},
async handleConfirm() {
// 变更状态
this.active = 3;
this.$emit('confirm')
},
handleMergerConfirm(res) {
if (res.status === 'start') {
this.loading = true;
this.loadingText = '正在处理产品参数';
} else if (res.status === 'success') {
this.loading = false;
this.active = 3;
this.$emit('confirm')
} else if (res.status === 'error') {
this.loading = false;
this.$modal.msgError('质保单处理失败');
}
},
async loadingMethod(key, fn) {
this.loading = true;
this.loadingText = so[key].loading;
try {
const res = await so[key].handler(this, this.uploadQualityCertificateForm.qualityCertificate)
fn && await fn(res)
return res;
} catch {
this.$modal.msgError('操作失败');
} finally {
this.loading = false;
}
},
// 比较新旧result是否一致
handleCompareResult() {
// 先检查新旧result是否一致
if (this.oldResult.length !== this.newResult.length) {
this.resultDiff = true;
return;
}
// 比较新旧result是否一致
for (let i = 0; i < this.oldResult.length; i++) {
if (this.oldResult[i].attrKey !== this.newResult[i].attrKey || this.oldResult[i].attrValue !== this.newResult[i].attrValue) {
this.resultDiff = true;
return;
}
}
this.resultDiff = false;
},
// 保存keyList到localStorage
saveKeyList() {
localStorage.setItem('ocrKeyList', this.keyListInput)
this.showKeyListDialog = false
this.$message.success('已保存OCR字段配置')
},
// 打开弹窗时初始化内容
openKeyListDialog() {
let local = ''
try {
local = localStorage.getItem('ocrKeyList') || ''
} catch { }
if (local) {
this.keyListInput = local
} else {
this.keyListInput = [
"订货单位", "合同号", "产品名称", "执行标准",
"卷号", "原料坯号", "规格", "材质",
"表面状态", "调制度", "切边要求", "包装种类",
"毛重", "净重", "参考长度"
].join('\n')
}
this.showKeyListDialog = true
},
}
}
</script>
<style scoped>
.el-row {
margin-bottom: 20px;
margin-top: 20px;
}
</style>

View File

@@ -1,335 +0,0 @@
<template>
<div class="stockin-container">
<el-dialog
:title="title"
:visible.sync="visible"
width="80%"
:before-close="handleClose"
append-to-body
>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<!-- 入库单基本信息 -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="入库单号" prop="stockIoCode">
<el-input v-model="form.stockIoCode" placeholder="系统自动生成" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入库类型" prop="ioType">
<el-select v-model="form.ioType" placeholder="请选择入库类型" :disabled="true">
<el-option label="入库" value="in" />
<el-option label="出库" value="out" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="业务类型" prop="bizType">
<el-select v-model="form.bizType" placeholder="请选择业务类型" :disabled="true">
<el-option label="采购入库" value="purchase" />
<el-option label="销售退货" value="return" />
<el-option label="调拨入库" value="transfer" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单据状态" prop="status">
<el-select v-model="form.status" placeholder="请选择单据状态" :disabled="true">
<el-option label="草稿" :value="0" />
<el-option label="已提交" :value="1" />
<el-option label="已审核" :value="2" />
<el-option label="已完成" :value="3" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
:rows="3"
placeholder="请输入备注信息"
/>
</el-form-item>
<!-- 入库明细表格 -->
<el-form-item label="入库明细">
<KLPTable
:data="form.details"
border
style="width: 100%"
>
<el-table-column label="原材料" align="center" prop="rawMaterialName" />
<el-table-column label="参数" align="center">
<template slot-scope="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="计划数量" align="center" prop="planQuantity" />
<el-table-column label="入库数量" align="center" prop="quantity">
<template slot-scope="scope">
<el-input
v-model.number="scope.row.quantity"
size="mini"
@change="handleQuantityChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="unit" />
<el-table-column label="仓库" align="center" prop="warehouseId">
<template slot-scope="scope">
<warehouse-select
v-model="scope.row.warehouseId"
placeholder="请选择仓库"
size="mini"
style="width: 100%"
/>
</template>
</el-table-column>
<el-table-column label="批次号" align="center" prop="batchNo">
<template slot-scope="scope">
<el-input
v-model="scope.row.batchNo"
size="mini"
placeholder="请输入批次号"
/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark">
<template slot-scope="scope">
<el-input
v-model="scope.row.remark"
size="mini"
placeholder="请输入备注"
/>
</template>
</el-table-column>
</KLPTable>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose"> </el-button>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addStockIoWithDetail } from "@/api/wms/stockIo";
import { updatePurchasePlanDetail } from "@/api/wms/purchasePlanDetail";
import { getRawMaterial } from "@/api/wms/rawMaterial";
import { EPurchaseDetailStatus } from "@/utils/enums";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
export default {
name: "StockInDialog",
components: {
WarehouseSelect,
BomInfoMini
},
props: {
visible: {
type: Boolean,
default: false
},
selectedItems: {
type: Array,
default: () => []
}
},
data() {
return {
title: "创建入库单",
submitLoading: false,
form: {
stockIoCode: "",
ioType: "in",
bizType: "purchase",
status: 0,
remark: "",
details: []
},
rules: {
remark: [
{ max: 500, message: "备注长度不能超过500个字符", trigger: "blur" }
]
}
};
},
watch: {
visible(newVal) {
if (newVal) {
this.initForm();
}
},
// selectedItems: {
// handler(newVal) {
// if (newVal && newVal.length > 0 && this.visible) {
// this.initDetails();
// }
// },
// immediate: false
// }
},
methods: {
/** 初始化表单 */
initForm() {
this.form = {
stockIoCode: `IN-${new Date().getTime()}`,
ioType: "in",
bizType: "purchase",
status: 0,
remark: `采购计划入库单 - ${new Date().toLocaleDateString()}`,
details: []
};
// 如果已经有选中的明细,则初始化明细
if (this.selectedItems && this.selectedItems.length > 0) {
this.initDetails();
}
},
/** 初始化明细数据 */
async initDetails() {
if (this.selectedItems && this.selectedItems.length > 0) {
this.form.details = [];
// 逐个获取原材料信息
for (const item of this.selectedItems) {
try {
const rawMaterialInfo = await getRawMaterial(item.rawMaterialId);
this.form.details.push({
detailId: item.detailId,
rawMaterialId: item.rawMaterialId,
rawMaterialName: rawMaterialInfo.data.rawMaterialName || `原材料${item.rawMaterialId}`,
planQuantity: item.quantity,
quantity: item.quantity, // 默认入库数量等于计划数量
unit: item.unit,
warehouseId: null, // 默认仓库ID
batchNo: `BATCH-${new Date().getTime()}-${item.rawMaterialId}`,
remark: "",
itemType: "raw_material"
});
} catch (error) {
console.error(`获取原材料信息失败: ${item.rawMaterialId}`, error);
// 如果获取失败,使用默认名称
this.form.details.push({
detailId: item.detailId,
rawMaterialId: item.rawMaterialId,
rawMaterialName: `原材料${item.rawMaterialId}`,
planQuantity: item.quantity,
quantity: item.quantity,
unit: item.unit,
warehouseId: null,
batchNo: `BATCH-${new Date().getTime()}-${item.rawMaterialId}`,
remark: "",
itemType: "raw_material"
});
}
}
}
},
/** 处理数量变化 */
handleQuantityChange(row) {
// 验证入库数量不能超过计划数量
if (row.quantity > row.planQuantity) {
this.$message.warning(`入库数量不能超过计划数量 ${row.planQuantity}`);
row.quantity = row.planQuantity;
}
if (row.quantity < 0) {
this.$message.warning("入库数量不能为负数");
row.quantity = 0;
}
},
/** 关闭对话框 */
handleClose() {
this.$confirm("确认关闭?未保存的数据将丢失", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$emit("update:visible", false);
}).catch(() => {});
},
/** 提交表单 */
handleSubmit() {
this.$refs.form.validate(valid => {
if (valid) {
// 验证是否有明细
if (this.form.details.length === 0) {
this.$message.warning("没有可入库的明细");
return;
}
// 验证必填字段
const invalidDetails = this.form.details.filter(detail =>
!detail.warehouseId || !detail.batchNo || detail.quantity <= 0
);
if (invalidDetails.length > 0) {
this.$message.warning("请完善明细的仓库、批次号和入库数量信息");
return;
}
this.submitLoading = true;
// 构建入库单数据
const stockInData = {
...this.form,
details: this.form.details.map(detail => ({
warehouseId: detail.warehouseId,
itemType: detail.itemType,
itemId: detail.rawMaterialId,
quantity: detail.quantity,
unit: detail.unit,
batchNo: detail.batchNo,
remark: detail.remark
}))
};
// 调用创建入库单API
addStockIoWithDetail(stockInData).then(response => {
// 创建入库单成功后,更新采购明细状态
const updatePromises = this.form.details.map(detail =>
updatePurchasePlanDetail({
detailId: detail.detailId,
status: EPurchaseDetailStatus.FINISH
})
);
Promise.all(updatePromises).then(() => {
this.$modal.msgSuccess("入库单创建成功,相关明细状态已更新为采购完成");
this.$emit("success");
this.$emit("update:visible", false);
}).catch(error => {
console.error(error);
this.$modal.msgError("状态更新失败");
});
}).catch(error => {
console.error(error);
this.$modal.msgError("入库单创建失败");
}).finally(() => {
this.submitLoading = false;
});
}
});
}
}
};
</script>
<style scoped>
.stockin-container {
padding: 20px;
}
.dialog-footer {
text-align: right;
}
</style>

View File

@@ -1,295 +0,0 @@
<template>
<div class="purchase-plan-transfer">
<!-- 采购单信息区 -->
<el-card class="section-card" shadow="never">
<div slot="header" class="section-title">采购单信息</div>
<el-form :model="mainForm" :rules="mainFormRules" ref="mainFormRef" :inline="true" label-width="120px" style="margin-bottom: 0;" v-loading="formLoading" element-loading-text="正在加载主数据...">
<el-form-item label="计划编号" prop="planCode">
<el-input v-model="mainForm.planCode" placeholder="请输入计划编号" style="width: 200px;" />
</el-form-item>
<el-form-item label="负责人" prop="owner">
<el-input v-model="mainForm.owner" :multiple="false" placeholder="请填写负责人" style="width: 200px;" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="mainForm.remark" placeholder="请输入备注" style="width: 300px;" />
</el-form-item>
</el-form>
</el-card>
<div>
<el-row style="height: 60vh;">
<el-col :span="8">
<!-- 原材料表格 -->
<KLPTable v-loading="rawMaterialLoading" ref="leftTable" :data="rawMaterialList" style="width: 100%" height="600" class="message-table" stripe @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="rawMaterialId" label="原材料" align="center">
<template #default="scope">
<RawMaterialInfo :materialId="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="参数" align="center">
<template #default="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column prop="unit" label="单位" align="center" />
<el-table-column prop="onTheWay" label="在途" align="center" />
<el-table-column prop="inventory" label="在库" align="center" />
<el-table-column prop="demand" label="所需" align="center" />
</KLPTable>
<el-pagination
style="margin-top: 10px;"
background
layout="prev, pager, next"
:total="total"
:page-size="pageSize"
:current-page="pageNum"
@current-change="handlePageChange"
/>
</el-col>
<!-- 穿梭操作 -->
<el-col :span="2">
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%;">
<el-button type="primary" @click="addToPurchase">添加</el-button>
<el-button type="danger" @click="removeFromPurchase" style="margin-top: 10px;">删除</el-button>
</div>
</el-col>
<el-col :span="14">
<div slot="header" class="section-title">采购单明细</div>
<KLPTable
:data="purchaseList"
@selection-change="handleRightSelectionChange"
style="width: 100%"
height="600"
ref="rightTable"
border
>
<el-table-column type="selection" width="55" />
<el-table-column prop="rawMaterialId" label="原材料">
<template #default="scope">
<RawMaterialInfo :materialId="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column label="参数" align="center">
<template #default="scope">
<BomInfoMini item-type="raw_material" :item-id="scope.row.rawMaterialId" />
</template>
</el-table-column>
<el-table-column prop="unit" label="单位" />
<el-table-column prop="onTheWay" label="在途" />
<el-table-column prop="inventory" label="在库" />
<el-table-column prop="demand" label="所需" />
<el-table-column prop="quantity" label="计划采购数">
<template #default="scope">
<el-input-number :controls=false controls-position="right" v-model="scope.row.quantity" :min="0" size="small" />
</template>
</el-table-column>
<el-table-column prop="owner" label="负责人">
<template #default="scope">
<el-input v-model="scope.row.owner" :multiple="false" placeholder="请填写负责人" size="small" />
</template>
</el-table-column>
<el-table-column prop="remark" label="备注">
<template #default="scope">
<el-input v-model="scope.row.remark" size="small" />
</template>
</el-table-column>
</KLPTable>
</el-col>
</el-row>
</div>
<div style="margin-top: 20px; text-align: right;" v-loading="submitLoading" element-loading-text="正在提交数据...">
<el-button type="primary" @click="confirm" :loading="submitLoading">{{ submitLoading ? '提交中...' : '确认' }}</el-button>
</div>
</div>
</template>
<script>
import { createPurchasePlan } from '@/api/wms/purchasePlan'
import { listRawMaterial, listRawMaterialWithDemand } from '@/api/wms/rawMaterial'
import UserSelect from '@/components/KLPService/UserSelect'
import RawMaterialSelect from '@/components/KLPService/RawMaterialSelect'
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo.vue'
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
export default {
name: 'CreatePurchasePanel',
components: { UserSelect, RawMaterialSelect, RawMaterialInfo, BomInfoMini },
props: {
orderId: {
type: [String, Number],
required: true
},
recommendData: {
type: Object,
default: () => ({})
}
},
data() {
return {
// 原材料表格相关
rawMaterialList: [],
total: 0,
pageNum: 1,
pageSize: 20,
rawMaterialLoading: false,
leftSelected: [],
rightSelected: [],
rawMaterialNameFilter: '',
// 采购列表
purchaseList: [],
// 细化的loading状态
formLoading: false,
submitLoading: false,
mainForm: {
planCode: '',
owner: '',
remark: ''
},
mainFormRules: {
planCode: [
{ required: true, message: '请输入计划编号', trigger: 'blur' }
],
owner: [
{ required: true, message: '请输入负责人', trigger: 'blur' }
]
}
}
},
watch: {
recommendData: {
immediate: true,
handler(newVal) {
if (newVal && newVal.detailList) {
this.purchaseList = newVal.detailList
this.mainForm = {
planCode: newVal.planCode || '',
owner: newVal.owner || '',
remark: newVal.remark || ''
}
}
}
}
},
mounted() {
this.fetchRawMaterials();
},
methods: {
// 原材料分页查询
fetchRawMaterials() {
this.rawMaterialLoading = true;
listRawMaterialWithDemand({ pageNum: this.pageNum, pageSize: this.pageSize, rawMaterialName: this.rawMaterialNameFilter }).then(res => {
// 过滤掉已在采购列表中的原材料
const purchaseIds = this.purchaseList.map(item => item.rawMaterialId);
this.rawMaterialList = (res.rows || []).filter(item => !purchaseIds.includes(item.rawMaterialId));
this.total = res.total || 0;
this.rawMaterialLoading = false;
}).catch(() => {
this.rawMaterialLoading = false;
});
},
handlePageChange(page) {
this.pageNum = page;
this.fetchRawMaterials();
},
handleSelectionChange(selection) {
this.leftSelected = selection;
},
handleRightSelectionChange(selection) {
this.rightSelected = selection;
},
handleRawMaterialFilter() {
this.pageNum = 1;
this.fetchRawMaterials();
},
addToPurchase() {
// 去重添加
const ids = this.purchaseList.map(item => item.rawMaterialId);
const newItems = this.leftSelected.filter(item => !ids.includes(item.rawMaterialId)).map(item => ({
...item,
quantity: 0,
owner: '',
remark: ''
}));
this.purchaseList = this.purchaseList.concat(newItems);
this.$refs.leftTable.clearSelection();
this.fetchRawMaterials();
},
removeFromPurchase() {
const removeIds = this.rightSelected.map(item => item.rawMaterialId);
this.purchaseList = this.purchaseList.filter(item => !removeIds.includes(item.rawMaterialId));
this.$refs.rightTable.clearSelection();
this.fetchRawMaterials();
},
confirm() {
this.submitLoading = true;
this.$refs.mainFormRef.validate(async(valid) => {
if (!valid) {
this.$message.error('请完整填写主数据信息');
this.submitLoading = false;
return;
}
// 校验采购列表数据除remark外都不能为空
const filtered = this.purchaseList.filter(row => row.rawMaterialId && row.rawMaterialId !== '');
const invalid = filtered.some(row => {
return !row.rawMaterialId || !row.owner || !row.unit || row.quantity === '' || row.quantity === null || row.quantity === undefined;
});
if (invalid) {
this.$message.error('请完整填写所有必填项');
this.submitLoading = false;
return;
}
// 合并主数据和明细数据
const submitData = {
...this.mainForm,
orderId: this.orderId,
detailList: filtered
};
await createPurchasePlan(submitData);
this.$emit('confirm', submitData);
this.submitLoading = false;
});
}
}
}
</script>
<style scoped>
.purchase-plan-transfer {
display: flex;
flex-direction: column;
}
.section-card {
margin-bottom: 20px;
}
.section-title {
font-weight: bold;
font-size: 16px;
color: #333;
}
.transfer-content {
display: flex;
align-items: flex-start;
}
.left-table {
width: 30%;
}
.right-table {
width: 60%;
}
.transfer-actions {
width: 10%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.transfer-actions .el-button {
margin: 10px 0;
}
.filter-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
}
</style>

View File

@@ -1,361 +0,0 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-close"
size="mini"
@click="handleClose"
>关闭</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="字典编码" align="center" prop="dictCode" />
<el-table-column label="字典标签" align="center" prop="dictLabel">
<template slot-scope="scope">
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span>
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag>
</template>
</el-table-column>
<el-table-column label="字典键值" align="center" prop="dictValue" />
<el-table-column label="字典排序" align="center" prop="dictSort" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改参数配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="字典类型">
<el-input v-model="form.dictType" :disabled="true" />
</el-form-item>
<el-form-item label="数据标签" prop="dictLabel">
<el-input v-model="form.dictLabel" placeholder="请输入数据标签" />
</el-form-item>
<el-form-item label="数据键值" prop="dictValue">
<el-input v-model="form.dictValue" placeholder="请输入数据键值" />
</el-form-item>
<el-form-item label="样式属性" prop="cssClass">
<el-input v-model="form.cssClass" placeholder="请输入样式属性" />
</el-form-item>
<el-form-item label="显示排序" prop="dictSort">
<el-input-number :controls=false controls-position="right" v-model="form.dictSort" :min="0" />
</el-form-item>
<el-form-item label="回显样式" prop="listClass">
<el-select v-model="form.listClass">
<el-option
v-for="item in listClassOptions"
:key="item.value"
:label="item.label + '(' + item.value + ')'"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data";
import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type";
export default {
name: "Data",
dicts: ['sys_normal_disable'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 字典表格数据
dataList: [],
// 默认字典类型
defaultDictType: "",
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 数据标签回显样式
listClassOptions: [
{
value: "default",
label: "默认"
},
{
value: "primary",
label: "主要"
},
{
value: "success",
label: "成功"
},
{
value: "info",
label: "信息"
},
{
value: "warning",
label: "警告"
},
{
value: "danger",
label: "危险"
}
],
// 类型数据字典
typeOptions: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
dictName: undefined,
dictType: undefined,
status: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
dictLabel: [
{ required: true, message: "数据标签不能为空", trigger: "blur" }
],
dictValue: [
{ required: true, message: "数据键值不能为空", trigger: "blur" }
],
dictSort: [
{ required: true, message: "数据顺序不能为空", trigger: "blur" }
]
}
};
},
created() {
const dictId = '1946447341556719617';
this.getType(dictId);
this.getTypeList();
},
methods: {
/** 查询字典类型详细 */
getType(dictId) {
getType(dictId).then(response => {
this.queryParams.dictType = response.data.dictType;
this.defaultDictType = response.data.dictType;
this.getList();
});
},
/** 查询字典类型列表 */
getTypeList() {
getDictOptionselect().then(response => {
this.typeOptions = response.data;
});
},
/** 查询字典数据列表 */
getList() {
this.loading = true;
listData(this.queryParams).then(response => {
this.dataList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
dictCode: undefined,
dictLabel: undefined,
dictValue: undefined,
cssClass: undefined,
listClass: 'default',
dictSort: 0,
status: "0",
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 返回按钮操作 */
handleClose() {
const obj = { path: "/system/dict" };
this.$tab.closeOpenPage(obj);
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.queryParams.dictType = this.defaultDictType;
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加字典数据";
this.form.dictType = this.queryParams.dictType;
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.dictCode)
this.single = selection.length!=1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const dictCode = row.dictCode || this.ids
getData(dictCode).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改字典数据";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.dictCode != undefined) {
updateData(this.form).then(response => {
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addData(this.form).then(response => {
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const dictCodes = row.dictCode || this.ids;
this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() {
return delData(dictCodes);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
this.$store.dispatch('dict/removeDict', this.queryParams.dictType);
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/dict/data/export', {
...this.queryParams
}, `data_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -1,305 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="供应商名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入供应商名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系人" prop="contactPerson">
<el-input
v-model="queryParams.contactPerson"
placeholder="请输入联系人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input
v-model="queryParams.phone"
placeholder="请输入联系电话"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input
v-model="queryParams.address"
placeholder="请输入地址"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<KLPTable v-loading="loading" :data="supplierList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="供应商ID" align="center" prop="supplierId" v-if="false"/>
<el-table-column label="供应商名称" align="center" prop="name" />
<el-table-column label="联系人" align="center" prop="contactPerson" />
<el-table-column label="联系电话" align="center" prop="phone" />
<el-table-column label="地址" align="center" prop="address" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改供应商信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="供应商名称" prop="name">
<el-input v-model="form.name" placeholder="请输入供应商名称" />
</el-form-item>
<el-form-item label="联系人" prop="contactPerson">
<el-input v-model="form.contactPerson" placeholder="请输入联系人" />
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="form.address" placeholder="请输入地址" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listSupplier, getSupplier, delSupplier, addSupplier, updateSupplier } from "@/api/wms/supplier";
export default {
name: "Supplier",
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 供应商信息表格数据
supplierList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
name: undefined,
contactPerson: undefined,
phone: undefined,
address: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
}
};
},
created() {
this.getList();
},
methods: {
/** 查询供应商信息列表 */
getList() {
this.loading = true;
listSupplier(this.queryParams).then(response => {
this.supplierList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
supplierId: undefined,
name: undefined,
contactPerson: undefined,
phone: undefined,
address: undefined,
remark: undefined,
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.supplierId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加供应商信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const supplierId = row.supplierId || this.ids
getSupplier(supplierId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改供应商信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.supplierId != null) {
updateSupplier(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addSupplier(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const supplierIds = row.supplierId || this.ids;
this.$modal.confirm('是否确认删除供应商信息编号为"' + supplierIds + '"的数据项?').then(() => {
this.loading = true;
return delSupplier(supplierIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/supplier/export', {
...this.queryParams
}, `supplier_${new Date().getTime()}.xlsx`)
}
}
};
</script>