Pre Merge pull request !744 from 新的开始/gwj
commit
9c1f5354db
2
.env
2
.env
|
|
@ -1,5 +1,5 @@
|
||||||
# 标题
|
# 标题
|
||||||
VITE_APP_TITLE=芋道管理系统
|
VITE_APP_TITLE=CINO综合系统3.0
|
||||||
|
|
||||||
# 项目本地运行端口号
|
# 项目本地运行端口号
|
||||||
VITE_PORT=80
|
VITE_PORT=80
|
||||||
|
|
|
||||||
2
.env.dev
2
.env.dev
|
|
@ -4,7 +4,7 @@ NODE_ENV=production
|
||||||
VITE_DEV=true
|
VITE_DEV=true
|
||||||
|
|
||||||
# 请求路径
|
# 请求路径
|
||||||
VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
|
VITE_BASE_URL='http://121.5.163.108:48080'
|
||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="keywords"
|
name="keywords"
|
||||||
content="芋道管理系统 基于 vue3 + CompositionAPI + typescript + vite3 + element plus 的后台开源免费管理系统!"
|
content="CINO综合系统3.0 基于 vue3 + CompositionAPI + typescript + vite3 + element plus 的后台开源免费管理系统!"
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="芋道管理系统 基于 vue3 + CompositionAPI + typescript + vite3 + element plus 的后台开源免费管理系统!"
|
content="CINO综合系统3.0 基于 vue3 + CompositionAPI + typescript + vite3 + element plus 的后台开源免费管理系统!"
|
||||||
/>
|
/>
|
||||||
<title>%VITE_APP_TITLE%</title>
|
<title>%VITE_APP_TITLE%</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -62,7 +62,7 @@
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"pinia-plugin-persistedstate": "^3.2.1",
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.4",
|
||||||
"qs": "^6.12.0",
|
"qs": "^6.12.0",
|
||||||
"sortablejs": "^1.15.3",
|
"sortablejs": "^1.15.3",
|
||||||
"steady-xml": "^0.1.0",
|
"steady-xml": "^0.1.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// erp商务预报价 VO
|
||||||
|
export interface BdOrderPreQuoteVO {
|
||||||
|
orderId: string // 报价单ID
|
||||||
|
sypplierId: number // 供应商id
|
||||||
|
orderStatusId: number // 工单状态
|
||||||
|
fpTime: Date // 分配时间
|
||||||
|
pickOrderTime: Date // 接单时间
|
||||||
|
startPriceTime: Date // 开始报价时间
|
||||||
|
needEndTime: Date // 最晚报价时间
|
||||||
|
endPriceTime: Date // 结束报价时间
|
||||||
|
closeOrderTime: Date // 关单时间
|
||||||
|
cancelRemark: string // 取消工单原因
|
||||||
|
priceUserRemark: string // 报价者备注
|
||||||
|
dispUserId: number // 派单者id
|
||||||
|
pickUserId: number // 接单者id
|
||||||
|
priceUserId: number // 报价者id
|
||||||
|
address: string // 地址
|
||||||
|
expedited: number // 加急
|
||||||
|
}
|
||||||
|
|
||||||
|
// erp商务预报价 API
|
||||||
|
export const BdOrderPreQuoteApi = {
|
||||||
|
// 查询erp商务预报价分页
|
||||||
|
getBdOrderPreQuotePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/bd-order-pre-quote/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询erp商务预报价详情
|
||||||
|
getBdOrderPreQuote: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/bd-order-pre-quote/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增erp商务预报价
|
||||||
|
createBdOrderPreQuote: async (data: BdOrderPreQuoteVO) => {
|
||||||
|
return await request.post({ url: `/erp/bd-order-pre-quote/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改erp商务预报价
|
||||||
|
updateBdOrderPreQuote: async (data: BdOrderPreQuoteVO) => {
|
||||||
|
return await request.put({ url: `/erp/bd-order-pre-quote/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除erp商务预报价
|
||||||
|
deleteBdOrderPreQuote: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/bd-order-pre-quote/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出erp商务预报价 Excel
|
||||||
|
exportBdOrderPreQuote: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/bd-order-pre-quote/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 子表(Erp单据文件) ====================
|
||||||
|
|
||||||
|
// 获得Erp单据文件列表
|
||||||
|
getOrderFileListByOrderId: async (orderId) => {
|
||||||
|
return await request.get({ url: `/erp/bd-order-pre-quote/order-file/list-by-order-id?orderId=` + orderId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品分类故障 VO
|
||||||
|
export interface ProductCategoryFaultVO {
|
||||||
|
id: number // 类别故障编号
|
||||||
|
productCategoryId: number // 类别id
|
||||||
|
productFaultPart: string // 故障部位
|
||||||
|
productFault: string // 具体故障
|
||||||
|
ifAffectSale: boolean // 影响销售
|
||||||
|
affectSalePercentage: string // 影响销售%
|
||||||
|
affectSaleMoney: number // 影响销售金额
|
||||||
|
ifAffectRecycle: boolean // 影响回收
|
||||||
|
affectRecyclePercentage: string // 影响回收%
|
||||||
|
affectRecycleMoney: number // 影响回收金额
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品分类故障 API
|
||||||
|
export const ProductCategoryFaultApi = {
|
||||||
|
// 查询ERP 产品分类故障分页
|
||||||
|
getProductCategoryFaultPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-fault/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品分类故障详情
|
||||||
|
getProductCategoryFault: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-fault/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品分类故障
|
||||||
|
createProductCategoryFault: async (data: ProductCategoryFaultVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-category-fault/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品分类故障
|
||||||
|
updateProductCategoryFault: async (data: ProductCategoryFaultVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-category-fault/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品分类故障
|
||||||
|
deleteProductCategoryFault: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-category-fault/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品分类故障 Excel
|
||||||
|
exportProductCategoryFault: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-category-fault/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,8 +13,8 @@ export interface ProductCategoryVO {
|
||||||
// ERP 产品分类 API
|
// ERP 产品分类 API
|
||||||
export const ProductCategoryApi = {
|
export const ProductCategoryApi = {
|
||||||
// 查询产品分类列表
|
// 查询产品分类列表
|
||||||
getProductCategoryList: async () => {
|
getProductCategoryList: async (params: any) => {
|
||||||
return await request.get({ url: `/erp/product-category/list` })
|
return await request.get({ url: `/erp/product-category/list`, params })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询产品分类精简列表
|
// 查询产品分类精简列表
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品分类部位 VO
|
||||||
|
export interface ProductCategoryPartVO {
|
||||||
|
id: number // 编号
|
||||||
|
productCategoryId: number // 类别
|
||||||
|
productFaultPart: string // 部位
|
||||||
|
productFaultPartStr: string|undefined // 部位
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品分类部位 API
|
||||||
|
export const ProductCategoryPartApi = {
|
||||||
|
// 查询ERP 产品分类部位分页
|
||||||
|
getProductCategoryPartPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-part/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品分类部位详情
|
||||||
|
getProductCategoryPart: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-part/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品分类部位
|
||||||
|
createProductCategoryPart: async (data: ProductCategoryPartVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-category-part/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品分类部位
|
||||||
|
updateProductCategoryPart: async (data: ProductCategoryPartVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-category-part/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品分类部位
|
||||||
|
deleteProductCategoryPart: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-category-part/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品分类部位 Excel
|
||||||
|
exportProductCategoryPart: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-category-part/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品分类属性 VO
|
||||||
|
export interface ProductCategoryPropertiesVO {
|
||||||
|
id: number // 类别属性编号
|
||||||
|
productCategoryId: number // 类别属性id
|
||||||
|
ifSingleProperty: boolean // 是否单数属性
|
||||||
|
productPropertiesEn: string // 设备属性英文
|
||||||
|
productPropertiesCn: string // 设备属性中文
|
||||||
|
productPropertiesCategory: string // 设备属性分类
|
||||||
|
ifRequired: boolean // 是否必填
|
||||||
|
ifSn: boolean // 是否允许记录sn
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品分类属性 API
|
||||||
|
export const ProductCategoryPropertiesApi = {
|
||||||
|
// 查询ERP 产品分类属性分页
|
||||||
|
getProductCategoryPropertiesPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品分类属性详情
|
||||||
|
getProductCategoryProperties: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品分类属性
|
||||||
|
createProductCategoryProperties: async (data: ProductCategoryPropertiesVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-category-properties/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品分类属性
|
||||||
|
updateProductCategoryProperties: async (data: ProductCategoryPropertiesVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-category-properties/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品分类属性
|
||||||
|
deleteProductCategoryProperties: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-category-properties/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品分类属性 Excel
|
||||||
|
exportProductCategoryProperties: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-category-properties/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品分类属性值 VO
|
||||||
|
export interface ProductCategoryPropertiesValueVO {
|
||||||
|
id: number // 编号
|
||||||
|
productCategoryPropertiesId: number // 产品分类属性
|
||||||
|
productCategoryPropertiesValue: string // 产品分类属性值
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品分类属性值 API
|
||||||
|
export const ProductCategoryPropertiesValueApi = {
|
||||||
|
// 查询ERP 产品分类属性值分页
|
||||||
|
getProductCategoryPropertiesValuePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties-value/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品分类属性值详情
|
||||||
|
getProductCategoryPropertiesValue: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties-value/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品分类属性值
|
||||||
|
createProductCategoryPropertiesValue: async (data: ProductCategoryPropertiesValueVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-category-properties-value/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品分类属性值
|
||||||
|
updateProductCategoryPropertiesValue: async (data: ProductCategoryPropertiesValueVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-category-properties-value/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品分类属性值
|
||||||
|
deleteProductCategoryPropertiesValue: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-category-properties-value/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品分类属性值 Excel
|
||||||
|
exportProductCategoryPropertiesValue: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-category-properties-value/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品分类属性绑定 VO
|
||||||
|
export interface ProductCategoryPropertiesCategoryMapVO {
|
||||||
|
id: number // 编号
|
||||||
|
productCategoryPropertiesId: number // 类别属性
|
||||||
|
productCategoryId: number // 产品分类
|
||||||
|
productCategoryPropertiesValue: string // 类别属性值
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品分类属性绑定 API
|
||||||
|
export const ProductCategoryPropertiesCategoryMapApi = {
|
||||||
|
// 查询ERP 产品分类属性绑定分页
|
||||||
|
getProductCategoryPropertiesCategoryMapPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties-category-map/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品分类属性绑定详情
|
||||||
|
getProductCategoryPropertiesCategoryMap: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-category-properties-category-map/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品分类属性绑定
|
||||||
|
createProductCategoryPropertiesCategoryMap: async (data: ProductCategoryPropertiesCategoryMapVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-category-properties-category-map/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品分类属性绑定
|
||||||
|
updateProductCategoryPropertiesCategoryMap: async (data: ProductCategoryPropertiesCategoryMapVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-category-properties-category-map/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品分类属性绑定
|
||||||
|
deleteProductCategoryPropertiesCategoryMap: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-category-properties-category-map/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品分类属性绑定 Excel
|
||||||
|
exportProductCategoryPropertiesCategoryMap: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-category-properties-category-map/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -53,5 +53,11 @@ export const ProductApi = {
|
||||||
// 导出产品 Excel
|
// 导出产品 Excel
|
||||||
exportProduct: async (params) => {
|
exportProduct: async (params) => {
|
||||||
return await request.download({ url: `/erp/product/export-excel`, params })
|
return await request.download({ url: `/erp/product/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
//通过产品分类id查询产品list
|
||||||
|
getProductListByCategoryIds: async (productCategoryIds: number[]) => {
|
||||||
|
return await request.get({ url: `/erp/product/simple-list-by-category-ids`, params: { productCategoryIds } })
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品属性映射 VO
|
||||||
|
export interface ProductPropertiesMapVO {
|
||||||
|
id: number // 编号
|
||||||
|
productId: number // 产品id
|
||||||
|
productCategoryPropertiesId: number // 产品类别属性id
|
||||||
|
productPropertiesProductId: number // 产品属性产品id
|
||||||
|
productCategoryPropertiesValue: string // 产品类别属性值
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品属性映射 API
|
||||||
|
export const ProductPropertiesMapApi = {
|
||||||
|
// 查询ERP 产品属性映射分页
|
||||||
|
getProductPropertiesMapPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/product-properties-map/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品属性映射详情
|
||||||
|
getProductPropertiesMap: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/product-properties-map/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品属性映射
|
||||||
|
createProductPropertiesMap: async (data: ProductPropertiesMapVO) => {
|
||||||
|
return await request.post({ url: `/erp/product-properties-map/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品属性映射
|
||||||
|
updateProductPropertiesMap: async (data: ProductPropertiesMapVO) => {
|
||||||
|
return await request.put({ url: `/erp/product-properties-map/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品属性映射
|
||||||
|
deleteProductPropertiesMap: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/product-properties-map/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品属性映射 Excel
|
||||||
|
exportProductPropertiesMap: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/product-properties-map/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 销售退货项二维码 VO
|
||||||
|
export interface PurchaseReturnItemsQrVO {
|
||||||
|
id: number // 主键
|
||||||
|
qr: string // 二维码
|
||||||
|
returnId: number // 采购退货编号
|
||||||
|
orderItemId: number // 采购订单项编号
|
||||||
|
orderReturnItemId: number // 采购退货单项编号
|
||||||
|
warehouseId: number // 仓库编号
|
||||||
|
productId: number // 产品编号
|
||||||
|
productUnitId: number // 产品单位id
|
||||||
|
productPrice: number // 产品单价
|
||||||
|
taxPercent: number // 税率,百分比
|
||||||
|
taxPrice: number // 税额,单位:元
|
||||||
|
remark: string // 备注
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 销售退货项二维码 API
|
||||||
|
export const PurchaseReturnItemsQrApi = {
|
||||||
|
// 查询ERP 销售退货项二维码分页
|
||||||
|
getPurchaseReturnItemsQrPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/purchase-return-items-qr/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 销售退货项二维码详情
|
||||||
|
getPurchaseReturnItemsQr: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/purchase-return-items-qr/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 销售退货项二维码
|
||||||
|
createPurchaseReturnItemsQr: async (data: PurchaseReturnItemsQrVO) => {
|
||||||
|
return await request.post({ url: `/erp/purchase-return-items-qr/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 销售退货项二维码
|
||||||
|
updatePurchaseReturnItemsQr: async (data: PurchaseReturnItemsQrVO) => {
|
||||||
|
return await request.put({ url: `/erp/purchase-return-items-qr/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 销售退货项二维码
|
||||||
|
deletePurchaseReturnItemsQr: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/purchase-return-items-qr/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 销售退货项二维码 Excel
|
||||||
|
exportPurchaseReturnItemsQr: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/purchase-return-items-qr/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 销售出库项二维码 VO
|
||||||
|
export interface SaleOutItemsQrVO {
|
||||||
|
id: number // 编号
|
||||||
|
outId: number // 销售出库编号
|
||||||
|
orderItemId: number // 销售订单项编号
|
||||||
|
outItemId: number // 销售出库单项编号
|
||||||
|
warehouseId: number // 仓库编号
|
||||||
|
productId: number // 产品编号
|
||||||
|
productUnitId: number // 产品单位单位
|
||||||
|
productPrice: number // 产品单价
|
||||||
|
count: number // 数量
|
||||||
|
totalPrice: number // 总价
|
||||||
|
taxPercent: number // 税率,百分比
|
||||||
|
taxPrice: number // 税额,单位:元
|
||||||
|
remark: string // 备注
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 销售出库项二维码 API
|
||||||
|
export const SaleOutItemsQrApi = {
|
||||||
|
// 查询ERP 销售出库项二维码分页
|
||||||
|
getSaleOutItemsQrPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/sale-out-items-qr/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 销售出库项二维码详情
|
||||||
|
getSaleOutItemsQr: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/sale-out-items-qr/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 销售出库项二维码
|
||||||
|
createSaleOutItemsQr: async (data: SaleOutItemsQrVO) => {
|
||||||
|
return await request.post({ url: `/erp/sale-out-items-qr/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 销售出库项二维码
|
||||||
|
updateSaleOutItemsQr: async (data: SaleOutItemsQrVO) => {
|
||||||
|
return await request.put({ url: `/erp/sale-out-items-qr/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 销售出库项二维码
|
||||||
|
deleteSaleOutItemsQr: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/sale-out-items-qr/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 销售出库项二维码 Excel
|
||||||
|
exportSaleOutItemsQr: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/sale-out-items-qr/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品库存明细二维码 VO
|
||||||
|
export interface StockRecordQrVO {
|
||||||
|
id: number // 编号
|
||||||
|
recordId: number // 明细编号
|
||||||
|
productId: number // 产品编号
|
||||||
|
warehouseId: number // 仓库编号
|
||||||
|
warehouseLocationId: number // 货位编号
|
||||||
|
bizType: number // 业务类型
|
||||||
|
bizId: number // 业务编号
|
||||||
|
bizItemId: number // 业务项编号
|
||||||
|
bizNo: string // 业务单号
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品库存明细二维码 API
|
||||||
|
export const StockRecordQrApi = {
|
||||||
|
// 查询ERP 产品库存明细二维码分页
|
||||||
|
getStockRecordQrPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/stock-record-qr/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品库存明细二维码详情
|
||||||
|
getStockRecordQr: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/stock-record-qr/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品库存明细二维码
|
||||||
|
createStockRecordQr: async (data: StockRecordQrVO) => {
|
||||||
|
return await request.post({ url: `/erp/stock-record-qr/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品库存明细二维码
|
||||||
|
updateStockRecordQr: async (data: StockRecordQrVO) => {
|
||||||
|
return await request.put({ url: `/erp/stock-record-qr/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品库存明细二维码
|
||||||
|
deleteStockRecordQr: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/stock-record-qr/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品库存明细二维码 Excel
|
||||||
|
exportStockRecordQr: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/stock-record-qr/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 产品库存二维码 VO
|
||||||
|
export interface StockQrVO {
|
||||||
|
id: number // 编号
|
||||||
|
qr: string // 二维码
|
||||||
|
productId: number // 产品编号
|
||||||
|
warehouseId: number // 仓库编号
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 产品库存二维码 API
|
||||||
|
export const StockQrApi = {
|
||||||
|
// 查询ERP 产品库存二维码分页
|
||||||
|
getStockQrPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/stock-qr/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 产品库存二维码详情
|
||||||
|
getStockQr: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/stock-qr/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 产品库存二维码
|
||||||
|
createStockQr: async (data: StockQrVO) => {
|
||||||
|
return await request.post({ url: `/erp/stock-qr/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 产品库存二维码
|
||||||
|
updateStockQr: async (data: StockQrVO) => {
|
||||||
|
return await request.put({ url: `/erp/stock-qr/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 产品库存二维码
|
||||||
|
deleteStockQr: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/stock-qr/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 产品库存二维码 Excel
|
||||||
|
exportStockQr: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/stock-qr/export-excel`, params })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// ERP 仓库 VO
|
||||||
|
export interface WarehouseVO {
|
||||||
|
id: number // 仓库编号
|
||||||
|
name: string // 仓库名称
|
||||||
|
address: string // 仓库地址
|
||||||
|
sort: number // 排序
|
||||||
|
remark: string // 备注
|
||||||
|
principal: string // 负责人
|
||||||
|
warehousePrice: number // 仓储费,单位:元
|
||||||
|
truckagePrice: number // 搬运费,单位:元
|
||||||
|
status: number // 开启状态
|
||||||
|
defaultStatus: boolean // 是否默认
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WarehouseLocationVO {
|
||||||
|
id: number // 仓库编号
|
||||||
|
name: string // 仓库名称
|
||||||
|
sort: number // 排序
|
||||||
|
warehouseId: number //仓库编号
|
||||||
|
remark: string // 备注
|
||||||
|
principal: string // 负责人
|
||||||
|
warehousePrice: number // 仓储费,单位:元
|
||||||
|
truckagePrice: number // 搬运费,单位:元
|
||||||
|
status: number // 开启状态
|
||||||
|
defaultStatus: boolean // 是否默认
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERP 仓库 API
|
||||||
|
export const WarehouseApi = {
|
||||||
|
// 查询ERP 仓库分页
|
||||||
|
getWarehousePage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询ERP 仓库详情
|
||||||
|
getWarehouse: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增ERP 仓库
|
||||||
|
createWarehouse: async (data: WarehouseVO) => {
|
||||||
|
return await request.post({ url: `/erp/warehouse/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 仓库
|
||||||
|
updateWarehouse: async (data: WarehouseVO) => {
|
||||||
|
return await request.put({ url: `/erp/warehouse/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改仓库默认状态
|
||||||
|
updateWarehouseDefaultStatus: async (id: number, defaultStatus: boolean) => {
|
||||||
|
return await request.put({
|
||||||
|
url: `/erp/warehouse/update-default-status`,
|
||||||
|
params: {
|
||||||
|
id,
|
||||||
|
defaultStatus
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 仓库
|
||||||
|
deleteWarehouse: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/warehouse/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出ERP 仓库 Excel
|
||||||
|
exportWarehouse: async (params) => {
|
||||||
|
return await request.download({ url: `/erp/warehouse/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==================== 子表(ERP 仓库货位) ====================
|
||||||
|
|
||||||
|
// 获得ERP 仓库货位分页
|
||||||
|
getWarehouseLocationPage: async (params) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse/warehouse-location/page`, params })
|
||||||
|
},
|
||||||
|
// 新增ERP 仓库货位
|
||||||
|
createWarehouseLocation: async (data) => {
|
||||||
|
return await request.post({ url: `/erp/warehouse/warehouse-location/create`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改ERP 仓库货位
|
||||||
|
updateWarehouseLocation: async (data) => {
|
||||||
|
return await request.put({ url: `/erp/warehouse/warehouse-location/update`, data })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除ERP 仓库货位
|
||||||
|
deleteWarehouseLocation: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/erp/warehouse/warehouse-location/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获得ERP 仓库货位
|
||||||
|
getWarehouseLocation: async (id: number) => {
|
||||||
|
return await request.get({ url: `/erp/warehouse/warehouse-location/get?id=` + id })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -216,6 +216,17 @@ export enum DICT_TYPE {
|
||||||
// ========== ERP - 企业资源计划模块 ==========
|
// ========== ERP - 企业资源计划模块 ==========
|
||||||
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
|
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
|
||||||
ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type', // 库存明细的业务类型
|
ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type', // 库存明细的业务类型
|
||||||
|
ERP_PRODUCT_FAULT_PART = 'erp_product_fault_part', // 产品的故障部位
|
||||||
|
ERP_FILE_ORDER_TYPE = 'erp_file_order_type', // 文件单据类型
|
||||||
|
ERP_ORDER_PRE_STATUS = 'erp_order_pre_status', // 订单预报价单状态
|
||||||
|
ERP_PRODUCT_PROPERTIES_CATEGORY = 'erp_product_properties_category', // 产品属性的分类
|
||||||
|
ERP_PRODUCT_PROPERTIES = 'erp_product_properties', // 产品配件属性
|
||||||
|
ERP_PRODUCT_COMMON_PROPERTIES = 'erp_product_common_properties', // 产品普通属性
|
||||||
|
ERP_PRODUCT_INPUT_PROPERTIES = 'erp_product_input_properties', // 产品输入属性
|
||||||
|
ERP_PRODUCT_BRAND = 'erp_product_brand', // 产品品牌
|
||||||
|
ERP_PRODUCT_QR_MATCH='erp_product_qr_match', // 产品二维码匹配方式
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ========== AI - 人工智能模块 ==========
|
// ========== AI - 人工智能模块 ==========
|
||||||
AI_PLATFORM = 'ai_platform', // AI 平台
|
AI_PLATFORM = 'ai_platform', // AI 平台
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,43 @@
|
||||||
import { toNumber } from 'lodash-es'
|
import { toNumber } from 'lodash-es'
|
||||||
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从字典获取规则
|
||||||
|
*/
|
||||||
|
export const matchRulesFromDictOptions = (s : string) => {
|
||||||
|
// 从字典获取规则
|
||||||
|
const dictOptions = getStrDictOptions(DICT_TYPE.ERP_PRODUCT_QR_MATCH)
|
||||||
|
//获取长度相关
|
||||||
|
const longMatch = dictOptions.filter((item) => {
|
||||||
|
return item.value === 'long'
|
||||||
|
})
|
||||||
|
const longMatchValue = longMatch[0].label
|
||||||
|
//将长度拼接字符串转换为数组
|
||||||
|
const longMatchArr = longMatchValue.split(',')
|
||||||
|
//判断数组中元素是否包含传入的字符串长度
|
||||||
|
const longMatchResult = longMatchArr.some((item) => {
|
||||||
|
return item === s.length.toString()
|
||||||
|
})
|
||||||
|
if (!longMatchResult) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
//获取头部正则相关
|
||||||
|
const headMatch = dictOptions.filter((item) => {
|
||||||
|
return item.value === 'head'
|
||||||
|
})
|
||||||
|
const headMatchValue = headMatch[0].label
|
||||||
|
//将头部正则拼接字符串转换为数组
|
||||||
|
const headMatchArr = headMatchValue.split(',')
|
||||||
|
//判断数组中元素是否包含传入的字符串头部
|
||||||
|
const headMatchResult = headMatchArr.some((item) => {
|
||||||
|
return s.startsWith(item)
|
||||||
|
})
|
||||||
|
if (!headMatchResult) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,219 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="供应商id" prop="sypplierId">
|
||||||
|
<el-input v-model="formData.sypplierId" placeholder="请输入供应商id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="工单状态" prop="orderStatusId">
|
||||||
|
<el-select v-model="formData.orderStatusId" placeholder="请选择工单状态">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_ORDER_PRE_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分配时间" prop="fpTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.fpTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择分配时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="接单时间" prop="pickOrderTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.pickOrderTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择接单时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开始报价时间" prop="startPriceTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.startPriceTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择开始报价时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="最晚报价时间" prop="needEndTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.needEndTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择最晚报价时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="结束报价时间" prop="endPriceTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.endPriceTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择结束报价时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关单时间" prop="closeOrderTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.closeOrderTime"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择关单时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="取消工单原因" prop="cancelRemark">
|
||||||
|
<el-input v-model="formData.cancelRemark" type="textarea" placeholder="请输入取消工单原因" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="报价者备注" prop="priceUserRemark">
|
||||||
|
<el-input v-model="formData.priceUserRemark" type="textarea" placeholder="请输入报价者备注" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="派单者id" prop="dispUserId">
|
||||||
|
<el-input v-model="formData.dispUserId" placeholder="请输入派单者id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="接单者id" prop="pickUserId">
|
||||||
|
<el-input v-model="formData.pickUserId" placeholder="请输入接单者id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="报价者id" prop="priceUserId">
|
||||||
|
<el-input v-model="formData.priceUserId" placeholder="请输入报价者id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="address">
|
||||||
|
<el-input v-model="formData.address" placeholder="请输入地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="加急" prop="expedited">
|
||||||
|
<el-input v-model="formData.expedited" placeholder="请输入加急" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<el-tabs v-model="subTabsName">
|
||||||
|
<el-tab-pane label="Erp单据文件" name="orderFile">
|
||||||
|
<OrderFileForm ref="orderFileFormRef" :order-id="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { BdOrderPreQuoteApi, BdOrderPreQuoteVO } from '@/api/erp/bdorderprequote'
|
||||||
|
import OrderFileForm from './components/OrderFileForm.vue'
|
||||||
|
|
||||||
|
/** erp商务预报价 表单 */
|
||||||
|
defineOptions({ name: 'BdOrderPreQuoteForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
orderId: undefined,
|
||||||
|
sypplierId: undefined,
|
||||||
|
orderStatusId: undefined,
|
||||||
|
fpTime: undefined,
|
||||||
|
pickOrderTime: undefined,
|
||||||
|
startPriceTime: undefined,
|
||||||
|
needEndTime: undefined,
|
||||||
|
endPriceTime: undefined,
|
||||||
|
closeOrderTime: undefined,
|
||||||
|
cancelRemark: undefined,
|
||||||
|
priceUserRemark: undefined,
|
||||||
|
dispUserId: undefined,
|
||||||
|
pickUserId: undefined,
|
||||||
|
priceUserId: undefined,
|
||||||
|
address: undefined,
|
||||||
|
expedited: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 子表的表单 */
|
||||||
|
const subTabsName = ref('orderFile')
|
||||||
|
const orderFileFormRef = ref()
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await BdOrderPreQuoteApi.getBdOrderPreQuote(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 校验子表单
|
||||||
|
try {
|
||||||
|
await orderFileFormRef.value.validate()
|
||||||
|
} catch (e) {
|
||||||
|
subTabsName.value = 'orderFile'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as BdOrderPreQuoteVO
|
||||||
|
// 拼接子表的数据
|
||||||
|
data.orderFiles = orderFileFormRef.value.getData()
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await BdOrderPreQuoteApi.createBdOrderPreQuote(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await BdOrderPreQuoteApi.updateBdOrderPreQuote(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
orderId: undefined,
|
||||||
|
sypplierId: undefined,
|
||||||
|
orderStatusId: undefined,
|
||||||
|
fpTime: undefined,
|
||||||
|
pickOrderTime: undefined,
|
||||||
|
startPriceTime: undefined,
|
||||||
|
needEndTime: undefined,
|
||||||
|
endPriceTime: undefined,
|
||||||
|
closeOrderTime: undefined,
|
||||||
|
cancelRemark: undefined,
|
||||||
|
priceUserRemark: undefined,
|
||||||
|
dispUserId: undefined,
|
||||||
|
pickUserId: undefined,
|
||||||
|
priceUserId: undefined,
|
||||||
|
address: undefined,
|
||||||
|
expedited: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
<template>
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
v-loading="formLoading"
|
||||||
|
label-width="0px"
|
||||||
|
:inline-message="true"
|
||||||
|
>
|
||||||
|
<el-table :data="formData" class="-mt-10px">
|
||||||
|
<el-table-column label="序号" type="index" width="100" />
|
||||||
|
<el-table-column label="文件单据类型" min-width="150">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.fileTypeId`" :rules="formRules.fileTypeId" class="mb-0px!">
|
||||||
|
<el-select v-model="row.fileTypeId" placeholder="请选择文件单据类型">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_FILE_ORDER_TYPE)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="关联文件id" min-width="150">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.infraFileId`" :rules="formRules.infraFileId" class="mb-0px!">
|
||||||
|
<el-input v-model="row.infraFileId" placeholder="请输入关联文件id" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<el-row justify="center" class="mt-3">
|
||||||
|
<el-button @click="handleAdd" round>+ 添加Erp单据文件</el-button>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { BdOrderPreQuoteApi } from '@/api/erp/bdorderprequote'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
orderId: undefined // 关联单号(主表的关联字段)
|
||||||
|
}>()
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const formData = ref([])
|
||||||
|
const formRules = reactive({
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
watch(
|
||||||
|
() => props.orderId,
|
||||||
|
async (val) => {
|
||||||
|
// 1. 重置表单
|
||||||
|
formData.value = []
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
formLoading.value = true
|
||||||
|
formData.value = await BdOrderPreQuoteApi.getOrderFileListByOrderId(val)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
const handleAdd = () => {
|
||||||
|
const row = {
|
||||||
|
id: undefined,
|
||||||
|
orderId: undefined,
|
||||||
|
fileTypeId: undefined,
|
||||||
|
infraFileId: undefined
|
||||||
|
}
|
||||||
|
row.orderId = props.orderId
|
||||||
|
formData.value.push(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = (index) => {
|
||||||
|
formData.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单校验 */
|
||||||
|
const validate = () => {
|
||||||
|
return formRef.value.validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单值 */
|
||||||
|
const getData = () => {
|
||||||
|
return formData.value
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ validate, getData })
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<template>
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="主键" align="center" prop="id" />
|
||||||
|
<el-table-column label="文件单据类型" align="center" prop="fileTypeId">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_FILE_ORDER_TYPE" :value="scope.row.fileTypeId" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="关联文件id" align="center" prop="infraFileId" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import { BdOrderPreQuoteApi } from '@/api/erp/bdorderprequote'
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
orderId?: number // 关联单号(主表的关联字段)
|
||||||
|
}>()
|
||||||
|
const loading = ref(false) // 列表的加载中
|
||||||
|
const list = ref([]) // 列表的数据
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
list.value = await BdOrderPreQuoteApi.getOrderFileListByOrderId(props.orderId)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,317 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
|
||||||
|
<el-form-item label="工单状态" prop="orderStatusId">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.orderStatusId"
|
||||||
|
placeholder="请选择工单状态"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_ORDER_PRE_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分配时间" prop="fpTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.fpTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="接单时间" prop="pickOrderTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.pickOrderTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="关单时间" prop="closeOrderTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.closeOrderTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="address">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.address"
|
||||||
|
placeholder="请输入地址"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:bd-order-pre-quote:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:bd-order-pre-quote:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<el-table-column type="expand">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tabs model-value="orderFile">
|
||||||
|
<el-tab-pane label="Erp单据文件" name="orderFile">
|
||||||
|
<OrderFileList :order-id="scope.row.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="报价单号" align="center" prop="orderId" />
|
||||||
|
<el-table-column label="供应商" align="center" prop="sypplierId" />
|
||||||
|
<el-table-column label="工单状态" align="center" prop="orderStatusId">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_ORDER_PRE_STATUS" :value="scope.row.orderStatusId" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="分配时间"
|
||||||
|
align="center"
|
||||||
|
prop="fpTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="接单时间"
|
||||||
|
align="center"
|
||||||
|
prop="pickOrderTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="开始报价时间"
|
||||||
|
align="center"
|
||||||
|
prop="startPriceTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="最晚报价时间"
|
||||||
|
align="center"
|
||||||
|
prop="needEndTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="结束报价时间"
|
||||||
|
align="center"
|
||||||
|
prop="endPriceTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="关单时间"
|
||||||
|
align="center"
|
||||||
|
prop="closeOrderTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="取消工单原因" align="center" prop="cancelRemark" />
|
||||||
|
<el-table-column label="报价者备注" align="center" prop="priceUserRemark" />
|
||||||
|
<el-table-column label="派单者" align="center" prop="dispUserId" />
|
||||||
|
<el-table-column label="接单者" align="center" prop="pickUserId" />
|
||||||
|
<el-table-column label="报价者" align="center" prop="priceUserId" />
|
||||||
|
<el-table-column label="地址" align="center" prop="address" />
|
||||||
|
<el-table-column label="加急" align="center" prop="expedited" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:bd-order-pre-quote:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:bd-order-pre-quote:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<BdOrderPreQuoteForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { BdOrderPreQuoteApi, BdOrderPreQuoteVO } from '@/api/erp/bdorderprequote'
|
||||||
|
import BdOrderPreQuoteForm from './BdOrderPreQuoteForm.vue'
|
||||||
|
import OrderFileList from './components/OrderFileList.vue'
|
||||||
|
|
||||||
|
/** erp商务预报价 列表 */
|
||||||
|
defineOptions({ name: 'BdOrderPreQuote' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<BdOrderPreQuoteVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
sypplierId: undefined,
|
||||||
|
orderStatusId: undefined,
|
||||||
|
fpTime: [],
|
||||||
|
pickOrderTime: [],
|
||||||
|
startPriceTime: [],
|
||||||
|
needEndTime: [],
|
||||||
|
endPriceTime: [],
|
||||||
|
closeOrderTime: [],
|
||||||
|
cancelRemark: undefined,
|
||||||
|
priceUserRemark: undefined,
|
||||||
|
dispUserId: undefined,
|
||||||
|
pickUserId: undefined,
|
||||||
|
priceUserId: undefined,
|
||||||
|
address: undefined,
|
||||||
|
expedited: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await BdOrderPreQuoteApi.getBdOrderPreQuotePage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await BdOrderPreQuoteApi.deleteBdOrderPreQuote(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await BdOrderPreQuoteApi.exportBdOrderPreQuote(queryParams)
|
||||||
|
download.excel(data, 'erp商务预报价.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId">
|
||||||
|
<!-- 普通显示 -->
|
||||||
|
<el-select v-model="formData.productCategoryId" placeholder="请选择产品分类" @change="limitFaultPart" disabled filterable clearable>
|
||||||
|
<el-option v-for="item in productCategoryList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="故障部位" prop="productFaultPart">
|
||||||
|
<el-select v-model="formData.productFaultPart" placeholder="请选择故障部位">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dictfaultPartListSelect"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="具体故障" prop="productFault">
|
||||||
|
<el-input v-model="formData.productFault" placeholder="请输入具体故障" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售" prop="ifAffectSale">
|
||||||
|
<el-radio-group v-model="formData.ifAffectSale">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售%" prop="affectSalePercentage">
|
||||||
|
<el-input v-model="formData.affectSalePercentage" placeholder="请输入影响销售%" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售金额" prop="affectSaleMoney">
|
||||||
|
<el-input v-model="formData.affectSaleMoney" placeholder="请输入影响销售金额" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收" prop="ifAffectRecycle">
|
||||||
|
<el-radio-group v-model="formData.ifAffectRecycle">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收%" prop="affectRecyclePercentage">
|
||||||
|
<el-input v-model="formData.affectRecyclePercentage" placeholder="请输入影响回收%" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收金额" prop="affectRecycleMoney">
|
||||||
|
<el-input v-model="formData.affectRecycleMoney" placeholder="请输入影响回收金额" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { ProductCategoryFaultApi, ProductCategoryFaultVO } from '@/api/erp/product/category/erpproductcategoryfault'
|
||||||
|
import { ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
import { ProductCategoryPartApi, ProductCategoryPartVO} from '@/api/erp/product/category/productcategorypart'
|
||||||
|
|
||||||
|
/** 从父组件取productCategoryList数组*/
|
||||||
|
const props = defineProps<{
|
||||||
|
productCategoryList: ProductCategoryVO[]
|
||||||
|
productCategoryId: number
|
||||||
|
|
||||||
|
}
|
||||||
|
>();
|
||||||
|
|
||||||
|
/** 定义一个类型部位数组 */
|
||||||
|
const productCategoryPartList = ref<ProductCategoryPartVO[]>([])
|
||||||
|
|
||||||
|
/** 定义一个字典类型的故障部位数组 */
|
||||||
|
let dictfaultPartList = ref<{ value: string, label: string }[]>([])
|
||||||
|
let dictfaultPartListSelect = ref<{ value: string, label: string }[]>([])
|
||||||
|
|
||||||
|
/** ERP 产品分类故障 表单 */
|
||||||
|
defineOptions({ name: 'ProductCategoryFaultForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
productFaultPart: undefined,
|
||||||
|
productFault: undefined,
|
||||||
|
ifAffectSale: undefined,
|
||||||
|
affectSalePercentage: undefined,
|
||||||
|
affectSaleMoney: undefined,
|
||||||
|
ifAffectRecycle: undefined,
|
||||||
|
affectRecyclePercentage: undefined,
|
||||||
|
affectRecycleMoney: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
productCategoryId: [{ required: true, message: '产品分类不能为空', trigger: 'blur' }],
|
||||||
|
productFaultPart: [{ required: true, message: '故障部位不能为空', trigger: 'change' }],
|
||||||
|
productFault: [{ required: true, message: '具体故障不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
formData.value.productCategoryId = props.productCategoryId
|
||||||
|
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryFaultApi.getProductCategoryFault(id)
|
||||||
|
formData.value = {
|
||||||
|
...data,
|
||||||
|
ifAffectRecycle: data.ifAffectRecycle ? 'true' : 'false' ,// 转换为字典对应的值
|
||||||
|
ifAffectSale: data.ifAffectSale? 'true' : 'false' // 转换为字典对应的值
|
||||||
|
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductCategoryFaultVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductCategoryFaultApi.createProductCategoryFault(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductCategoryFaultApi.updateProductCategoryFault(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
productFaultPart: undefined,
|
||||||
|
productFault: undefined,
|
||||||
|
ifAffectSale: undefined,
|
||||||
|
affectSalePercentage: undefined,
|
||||||
|
affectSaleMoney: undefined,
|
||||||
|
ifAffectRecycle: undefined,
|
||||||
|
affectRecyclePercentage: undefined,
|
||||||
|
affectRecycleMoney: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取现在的产品分类id,通过产品分类id查询产品分类部位数组 */
|
||||||
|
const limitFaultPart = (productCategoryId: number) => {
|
||||||
|
if (productCategoryId) {
|
||||||
|
// 清空故障部位
|
||||||
|
formData.value.productFaultPart = undefined
|
||||||
|
ProductCategoryPartApi.getProductCategoryPartPage({ productCategoryId })
|
||||||
|
.then(res => {
|
||||||
|
productCategoryPartList.value = res.list
|
||||||
|
//拿到所有的故障部位,然后在表单中显示
|
||||||
|
const faultPartList = productCategoryPartList.value.map(item => item.productFaultPart)
|
||||||
|
// 过滤出faultPartList中没有的dictfaultPartList
|
||||||
|
dictfaultPartListSelect.value = dictfaultPartList.value.filter(item => faultPartList.includes(item.value))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建页面 */
|
||||||
|
onMounted(() => {
|
||||||
|
dictfaultPartList.value = getStrDictOptions(DICT_TYPE.ERP_PRODUCT_FAULT_PART)
|
||||||
|
dictfaultPartListSelect.value = dictfaultPartList.value
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,352 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productCategoryId"
|
||||||
|
placeholder="请选择产品分类"
|
||||||
|
disabled
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in productCategoryList"
|
||||||
|
:key="dict.id"
|
||||||
|
:label="dict.name"
|
||||||
|
:value="dict.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="故障部位" prop="productFaultPart">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productFaultPart"
|
||||||
|
placeholder="请选择故障部位"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_FAULT_PART)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="具体故障" prop="productFault">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productFault"
|
||||||
|
placeholder="请输入具体故障"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售" prop="ifAffectSale">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.ifAffectSale"
|
||||||
|
placeholder="请选择影响销售"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售%" prop="affectSalePercentage">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.affectSalePercentage"
|
||||||
|
placeholder="请输入影响销售%"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响销售金额" prop="affectSaleMoney">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.affectSaleMoney"
|
||||||
|
placeholder="请输入影响销售金额"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收" prop="ifAffectRecycle">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.ifAffectRecycle"
|
||||||
|
placeholder="请选择影响回收"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收%" prop="affectRecyclePercentage">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.affectRecyclePercentage"
|
||||||
|
placeholder="请输入影响回收%"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="影响回收金额" prop="affectRecycleMoney">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.affectRecycleMoney"
|
||||||
|
placeholder="请输入影响回收金额"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-category-fault:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-category-fault:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品分类" align="center" prop="productCategoryId">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getCategoryName(scope.row.productCategoryId) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="故障部位" align="center" prop="productFaultPart">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_FAULT_PART" :value="scope.row.productFaultPart" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="具体故障" align="center" prop="productFault" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="影响销售" align="center" prop="ifAffectSale" >
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifAffectSale" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="影响销售%" align="center" prop="affectSalePercentage" />
|
||||||
|
<el-table-column label="影响销售金额" align="center" prop="affectSaleMoney" />
|
||||||
|
<el-table-column label="影响回收" align="center" prop="ifAffectRecycle" >
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifAffectRecycle" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="影响回收%" align="center" prop="affectRecyclePercentage" />
|
||||||
|
<el-table-column label="影响回收金额" align="center" prop="affectRecycleMoney" />
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-fault:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-fault:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductCategoryFaultForm ref="formRef" @success="getList" :product-category-list="productCategoryList" :product-category-id="queryParams.productCategoryId"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductCategoryFaultApi, ProductCategoryFaultVO } from '@/api/erp/product/category/erpproductcategoryfault'
|
||||||
|
import ProductCategoryFaultForm from './ProductCategoryFaultForm.vue'
|
||||||
|
import { ProductCategoryApi , ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
|
||||||
|
/** ERP 产品分类的数组 */
|
||||||
|
const productCategoryList = ref<ProductCategoryVO[]>([])
|
||||||
|
|
||||||
|
/** ERP 产品分类故障 列表 */
|
||||||
|
defineOptions({ name: 'ErpProductCategoryFault' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryFaultVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryId: null as any,
|
||||||
|
productFaultPart: undefined,
|
||||||
|
productFault: undefined,
|
||||||
|
createTime: [],
|
||||||
|
ifAffectSale: undefined,
|
||||||
|
affectSalePercentage: undefined,
|
||||||
|
affectSaleMoney: undefined,
|
||||||
|
ifAffectRecycle: undefined,
|
||||||
|
affectRecyclePercentage: undefined,
|
||||||
|
affectRecycleMoney: undefined
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
|
||||||
|
const route = useRoute() // 路由
|
||||||
|
let searchCount = 0
|
||||||
|
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
if(route.query.searchId && searchCount == 0){
|
||||||
|
searchCount++
|
||||||
|
queryParams.productCategoryId = Number(route.query.searchId)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryFaultApi.getProductCategoryFaultPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductCategoryFaultApi.deleteProductCategoryFault(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductCategoryFaultApi.exportProductCategoryFault(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品分类故障.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据用户输入搜索产品分类 */
|
||||||
|
const searchProductCategory = async () => {
|
||||||
|
//构建param对象
|
||||||
|
const params = {
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
productCategoryList.value = await ProductCategoryApi.getProductCategoryList(params)
|
||||||
|
} catch (error) {
|
||||||
|
productCategoryList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据 productCategoryId 获取产品分类名称 */
|
||||||
|
const getCategoryName = (id: number | undefined) => {
|
||||||
|
if (!id) return ''
|
||||||
|
const category = productCategoryList.value.find(item => item.id === id)
|
||||||
|
return category ? category.name : '' // 假设产品分类名称字段为 name
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
searchProductCategory()
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -89,6 +89,25 @@
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
<router-link :to="'/erp/product/product-category-properties?searchId=' + scope.row.id"
|
||||||
|
v-hasPermi="['erp:product-category-properties:query']"
|
||||||
|
v-show="scope.row.status === 0"
|
||||||
|
>
|
||||||
|
<el-button link type="primary"
|
||||||
|
>属性</el-button>
|
||||||
|
</router-link>
|
||||||
|
<router-link :to="'/erp/product/product-category-fault?searchId=' + scope.row.id"
|
||||||
|
v-hasPermi="['erp:product-category-fault:query']"
|
||||||
|
v-show="scope.row.status === 0"
|
||||||
|
>
|
||||||
|
<el-button link type="primary">故障</el-button>
|
||||||
|
</router-link>
|
||||||
|
<router-link :to="'/erp/product/product-category-part?searchId=' + scope.row.id"
|
||||||
|
v-hasPermi="['erp:product-category-part:query']"
|
||||||
|
v-show="scope.row.status === 0"
|
||||||
|
>
|
||||||
|
<el-button link type="primary">部位</el-button>
|
||||||
|
</router-link>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -129,6 +148,7 @@ import download from '@/utils/download'
|
||||||
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
|
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
import ProductCategoryForm from './ProductCategoryForm.vue'
|
import ProductCategoryForm from './ProductCategoryForm.vue'
|
||||||
|
|
||||||
|
|
||||||
/** ERP 产品分类 列表 */
|
/** ERP 产品分类 列表 */
|
||||||
defineOptions({ name: 'ErpProductCategory' })
|
defineOptions({ name: 'ErpProductCategory' })
|
||||||
|
|
||||||
|
|
@ -138,9 +158,12 @@ const { t } = useI18n() // 国际化
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref<ProductCategoryVO[]>([]) // 列表的数据
|
const list = ref<ProductCategoryVO[]>([]) // 列表的数据
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
status: undefined
|
status: undefined,
|
||||||
})
|
})
|
||||||
|
const total = ref(0) // 列表的总数
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
|
@ -172,7 +195,6 @@ const formRef = ref()
|
||||||
const openForm = (type: string, id?: number) => {
|
const openForm = (type: string, id?: number) => {
|
||||||
formRef.value.open(type, id)
|
formRef.value.open(type, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (id: number) => {
|
const handleDelete = async (id: number) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId">
|
||||||
|
<el-select v-model="formData.productCategoryId" placeholder="请选择产品分类" disabled filterable clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="item in productCategoryList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部位" prop="productFaultPart">
|
||||||
|
<el-select v-model="formData.productFaultPart" placeholder="请选择部位">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_FAULT_PART)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
import { ProductCategoryPartApi, ProductCategoryPartVO } from '@/api/erp/product/category/productcategorypart'
|
||||||
|
|
||||||
|
/** 从父组件取productCategoryList数组*/
|
||||||
|
const props = defineProps<{
|
||||||
|
productCategoryList: ProductCategoryVO[]
|
||||||
|
productCategoryId: number
|
||||||
|
}
|
||||||
|
>();
|
||||||
|
|
||||||
|
/** ERP 产品分类部位 表单 */
|
||||||
|
defineOptions({ name: 'ProductCategoryPartForm' })
|
||||||
|
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
productFaultPart: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
productCategoryId: [{ required: true, message: '产品分类不能为空', trigger: 'change' }],
|
||||||
|
productFaultPart: [{ required: true, message: '部位不能为空', trigger: 'change' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
formData.value.productCategoryId = props.productCategoryId
|
||||||
|
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ProductCategoryPartApi.getProductCategoryPart(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductCategoryPartVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductCategoryPartApi.createProductCategoryPart(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductCategoryPartApi.updateProductCategoryPart(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
productFaultPart: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productCategoryId"
|
||||||
|
placeholder="请选择产品分类"
|
||||||
|
disabled
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in productCategoryList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部位" prop="productFaultPart">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productFaultPart"
|
||||||
|
placeholder="请选择部位"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_FAULT_PART)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-category-part:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-category-part:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品分类" align="center" prop="productCategoryId">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getCategoryName(scope.row.productCategoryId) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="部位" align="center" prop="productFaultPart">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_FAULT_PART" :value="scope.row.productFaultPart" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-part:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-part:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductCategoryPartForm ref="formRef" @success="getList" :product-category-list="productCategoryList" :product-category-id="queryParams.productCategoryId"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductCategoryPartApi, ProductCategoryPartVO } from '@/api/erp/product/category/productcategorypart'
|
||||||
|
import ProductCategoryPartForm from './ProductCategoryPartForm.vue'
|
||||||
|
import { ProductCategoryApi , ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
|
||||||
|
const route = useRoute() // 路由
|
||||||
|
let searchCount = 0
|
||||||
|
|
||||||
|
/** ERP 产品分类的数组 */
|
||||||
|
const productCategoryList = ref<ProductCategoryVO[]>([])
|
||||||
|
|
||||||
|
/** ERP 产品分类部位 列表 */
|
||||||
|
defineOptions({ name: 'ErpProductCategoryPart' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryPartVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryId: null as any,
|
||||||
|
productFaultPart: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
if(route.query.searchId && searchCount == 0){
|
||||||
|
searchCount++
|
||||||
|
queryParams.productCategoryId = Number(route.query.searchId)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryPartApi.getProductCategoryPartPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductCategoryPartApi.deleteProductCategoryPart(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductCategoryPartApi.exportProductCategoryPart(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品分类部位.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据用户输入搜索产品分类 */
|
||||||
|
const searchProductCategory = async () => {
|
||||||
|
//构建param对象
|
||||||
|
const params = {
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
productCategoryList.value = await ProductCategoryApi.getProductCategoryList(params)
|
||||||
|
} catch (error) {
|
||||||
|
productCategoryList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据 productCategoryId 获取产品分类名称 */
|
||||||
|
const getCategoryName = (id: number | undefined) => {
|
||||||
|
if (!id) return ''
|
||||||
|
const category = productCategoryList.value.find(item => item.id === id)
|
||||||
|
return category ? category.name : '' // 假设产品分类名称字段为 name
|
||||||
|
}
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
searchProductCategory()
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,211 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId">
|
||||||
|
<el-select v-model="formData.productCategoryId" disabled placeholder="请选择产品分类">
|
||||||
|
|
||||||
|
<el-option
|
||||||
|
v-for="dict in productCategoryList"
|
||||||
|
:key="dict.id"
|
||||||
|
:label="dict.name"
|
||||||
|
:value="dict.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性分类" prop="productPropertiesCategory">
|
||||||
|
<el-radio-group v-model="formData.productPropertiesCategory">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_PRODUCT_PROPERTIES_CATEGORY)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单数属性" prop="ifSingleProperty">
|
||||||
|
<el-radio-group v-model="formData.ifSingleProperty">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性英文" prop="productPropertiesEn">
|
||||||
|
<el-select
|
||||||
|
v-model="formData.productPropertiesEn"
|
||||||
|
placeholder="请选择属性英文"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<div v-if="formData.productPropertiesCategory===0">
|
||||||
|
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_COMMON_PROPERTIES)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value+'#'+dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="formData.productPropertiesCategory===1">
|
||||||
|
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_PROPERTIES)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value+'#'+dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="formData.productPropertiesCategory===2">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_INPUT_PROPERTIES)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value+'#'+dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="必填" prop="ifRequired">
|
||||||
|
<el-radio-group v-model="formData.ifRequired">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item
|
||||||
|
v-if="formData.productPropertiesCategory===1"
|
||||||
|
label="记录sn" prop="ifSn">
|
||||||
|
<el-radio-group v-model="formData.ifSn">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
import { getBoolDictOptions,getStrDictOptions,getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { ProductCategoryPropertiesApi, ProductCategoryPropertiesVO } from '@/api/erp/product/category/productcategoryproperties'
|
||||||
|
import { ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
|
||||||
|
/** 从父组件取数据*/
|
||||||
|
const props = defineProps<{
|
||||||
|
productCategoryList: ProductCategoryVO[]
|
||||||
|
productCategoryId: number
|
||||||
|
}>();
|
||||||
|
|
||||||
|
/** ERP 产品分类属性 表单 */
|
||||||
|
defineOptions({ name: 'ProductCategoryPropertiesForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
ifSingleProperty: [],
|
||||||
|
productPropertiesEn: undefined,
|
||||||
|
productPropertiesCn: undefined,
|
||||||
|
ifRequired: undefined,
|
||||||
|
productPropertiesCategory: undefined,
|
||||||
|
ifSn: false
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
productCategoryId: [{ required: true, message: '类别属性不能为空', trigger: 'change' }],
|
||||||
|
ifSingleProperty: [{ required: true, message: '单数属性不能为空', trigger: 'blur' }],
|
||||||
|
ifRequired: [{ required: true, message: '必填不能为空', trigger: 'change' }],
|
||||||
|
productPropertiesCategory: [{ required: true, message: '属性分类不能为空', trigger: 'change' }],
|
||||||
|
ifSn: [{ required: true, message: '记录sn不能为空', trigger: 'blur' }],
|
||||||
|
productPropertiesCn : [{ required: true, message: '属性中文不能为空', trigger: 'blur' }],
|
||||||
|
productPropertiesEn : [{ required: true, message: '属性英文不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
formData.value.productCategoryId = props.productCategoryId
|
||||||
|
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ProductCategoryPropertiesApi.getProductCategoryProperties(id)
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductCategoryPropertiesVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductCategoryPropertiesApi.createProductCategoryProperties(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductCategoryPropertiesApi.updateProductCategoryProperties(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productCategoryId: null as number | null,
|
||||||
|
ifSingleProperty: [],
|
||||||
|
productPropertiesEn: undefined,
|
||||||
|
productPropertiesCn: undefined,
|
||||||
|
ifRequired: undefined,
|
||||||
|
productPropertiesCategory: undefined,
|
||||||
|
ifSn: false
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,349 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="类别" prop="productCategoryId">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productCategoryId"
|
||||||
|
placeholder="请选择类别"
|
||||||
|
disabled
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in productCategoryList"
|
||||||
|
:key="dict.id"
|
||||||
|
:label="dict.name"
|
||||||
|
:value="dict.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性分类" prop="productPropertiesCategory">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productPropertiesCategory"
|
||||||
|
placeholder="请选择属性分类"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getStrDictOptions(DICT_TYPE.ERP_PRODUCT_PROPERTIES_CATEGORY)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单数属性" prop="ifSingleProperty">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.ifSingleProperty"
|
||||||
|
placeholder="请选择单数属性"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性英文" prop="productPropertiesEn">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productPropertiesEn"
|
||||||
|
placeholder="请输入设备属性英文"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="属性中文" prop="productPropertiesCn">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productPropertiesCn"
|
||||||
|
placeholder="请输入设备属性中文"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="必填" prop="ifRequired">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.ifRequired"
|
||||||
|
placeholder="请选择是否必填"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="记录sn" prop="ifSn">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.ifSn"
|
||||||
|
placeholder="请选择是否记录sn"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-category-properties:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-category-properties:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品分类" align="center" prop="productCategoryId">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getCategoryName(scope.row.productCategoryId) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="单数属性" align="center" prop="ifSingleProperty">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifSingleProperty" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="属性英文" align="center" prop="productPropertiesEn" />
|
||||||
|
<el-table-column label="属性中文" align="center" prop="productPropertiesCn" />
|
||||||
|
<el-table-column label="必填" align="center" prop="ifRequired">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifRequired" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="属性分类" align="center" prop="productPropertiesCategory">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_PROPERTIES_CATEGORY" :value="scope.row.productPropertiesCategory" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="记录sn" align="center" prop="ifSn">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifSn" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<router-link :to="'/erp/product/product-category-properties-category-map?productCategoryPropertiesId=' + scope.row.id+'&productPropertiesCategory='+scope.row.productPropertiesCategory"
|
||||||
|
|
||||||
|
v-show="scope.row.productPropertiesCategory !== 2"
|
||||||
|
v-hasPermi="['erp:product-category-properties-category-map:query']"
|
||||||
|
>
|
||||||
|
<el-button link type="primary"
|
||||||
|
>绑定</el-button>
|
||||||
|
</router-link>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductCategoryPropertiesForm ref="formRef" @success="getList" :product-category-id="queryParams.productCategoryId" :product-category-list="productCategoryList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getBoolDictOptions,getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductCategoryPropertiesApi, ProductCategoryPropertiesVO } from '@/api/erp/product/category/productcategoryproperties'
|
||||||
|
import ProductCategoryPropertiesForm from './ProductCategoryPropertiesForm.vue'
|
||||||
|
import { ProductCategoryApi , ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
|
||||||
|
const route = useRoute() // 路由
|
||||||
|
let searchCount = 0
|
||||||
|
|
||||||
|
|
||||||
|
/** ERP 产品分类的数组 */
|
||||||
|
const productCategoryList = ref<ProductCategoryVO[]>([])
|
||||||
|
/** ERP 产品分类属性 列表 */
|
||||||
|
defineOptions({ name: 'ProductCategoryProperties' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryPropertiesVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryId: null as any,
|
||||||
|
ifSingleProperty: undefined,
|
||||||
|
productPropertiesEn: undefined,
|
||||||
|
productPropertiesCn: undefined,
|
||||||
|
ifRequired: undefined,
|
||||||
|
productPropertiesCategory: undefined,
|
||||||
|
ifSn: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
if(route.query.searchId && searchCount == 0){
|
||||||
|
searchCount++
|
||||||
|
queryParams.productCategoryId = Number(route.query.searchId)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryPropertiesApi.getProductCategoryPropertiesPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductCategoryPropertiesApi.deleteProductCategoryProperties(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductCategoryPropertiesApi.exportProductCategoryProperties(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品分类属性.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据用户输入搜索类别 */
|
||||||
|
const searchProductCategory = async () => {
|
||||||
|
//构建param对象
|
||||||
|
const params = {
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
productCategoryList.value = await ProductCategoryApi.getProductCategoryList(params)
|
||||||
|
} catch (error) {
|
||||||
|
productCategoryList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据 productCategoryId 获取类别名称 */
|
||||||
|
const getCategoryName = (id: number | undefined) => {
|
||||||
|
if (!id) return ''
|
||||||
|
const category = productCategoryList.value.find(item => item.id === id)
|
||||||
|
return category ? category.name : '' // 假设类别名称字段为 name
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
searchProductCategory()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类属性" prop="productCategoryPropertiesId">
|
||||||
|
<el-select v-model="formData.productCategoryPropertiesId" placeholder="请选择产品分类属性">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_PRODUCT_COMMON_PROPERTIES)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品分类属性值" prop="productCategoryPropertiesValue">
|
||||||
|
<el-input v-model="formData.productCategoryPropertiesValue" placeholder="请输入产品分类属性值" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { ProductCategoryPropertiesValueApi, ProductCategoryPropertiesValueVO } from '@/api/erp/product/category/productcategoryproperties/productcategorypropertiesvalue'
|
||||||
|
|
||||||
|
/** ERP 产品分类属性值 表单 */
|
||||||
|
defineOptions({ name: 'ProductCategoryPropertiesValueForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productCategoryPropertiesId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
productCategoryPropertiesId: [{ required: true, message: '产品分类属性不能为空', trigger: 'change' }],
|
||||||
|
productCategoryPropertiesValue: [{ required: true, message: '产品分类属性值不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ProductCategoryPropertiesValueApi.getProductCategoryPropertiesValue(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductCategoryPropertiesValueVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductCategoryPropertiesValueApi.createProductCategoryPropertiesValue(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductCategoryPropertiesValueApi.updateProductCategoryPropertiesValue(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productCategoryPropertiesId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,209 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品分类属性" prop="productCategoryPropertiesId">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.productCategoryPropertiesId"
|
||||||
|
placeholder="请选择产品分类属性"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.ERP_PRODUCT_COMMON_PROPERTIES)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品分类属性值" prop="productCategoryPropertiesValue">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productCategoryPropertiesValue"
|
||||||
|
placeholder="请输入产品分类属性值"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-category-properties-value:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-category-properties-value:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品分类属性" align="center" prop="productCategoryPropertiesId">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_COMMON_PROPERTIES" :value="scope.row.productCategoryPropertiesId" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品分类属性值" align="center" prop="productCategoryPropertiesValue" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties-value:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties-value:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductCategoryPropertiesValueForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductCategoryPropertiesValueApi, ProductCategoryPropertiesValueVO } from '@/api/erp/product/category/productcategoryproperties/productcategorypropertiesvalue'
|
||||||
|
import ProductCategoryPropertiesValueForm from './ProductCategoryPropertiesValueForm.vue'
|
||||||
|
|
||||||
|
/** ERP 产品分类属性值 列表 */
|
||||||
|
defineOptions({ name: 'ErpProductCategoryPropertiesValue' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryPropertiesValueVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryPropertiesId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryPropertiesValueApi.getProductCategoryPropertiesValuePage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductCategoryPropertiesValueApi.deleteProductCategoryPropertiesValue(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductCategoryPropertiesValueApi.exportProductCategoryPropertiesValue(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品分类属性值.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
<template>
|
||||||
|
<Dialog title="新增分类属性值" v-model="valueDialogVisible">
|
||||||
|
<el-form ref="valueFormRef" :model="valueFormData" :rules="valueFormRules" label-width="100px" v-loading="formLoading">
|
||||||
|
|
||||||
|
<el-form-item label="分类属性值" prop="productCategoryPropertiesValue">
|
||||||
|
<el-input v-model="valueFormData.productCategoryPropertiesValue" placeholder="请输入分类属性值" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="addProductCategoryPropertiesValue" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="valueDialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
|
||||||
|
<el-form-item label="分类属性" prop="productCategoryPropertiesId" v-show="false">
|
||||||
|
<el-input v-model="formData.productCategoryPropertiesId" placeholder="请输入分类属性" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类属性" prop="productPropertiesCn">
|
||||||
|
<el-input v-model="formData.productPropertiesCn" placeholder="请输入分类属性" clearable disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品分类" prop="productCategoryId" v-if="productPropertiesCategory === 1">
|
||||||
|
<el-tree-select v-model="formData.productCategoryId" :data="productCategoryTree" :props="defaultProps"
|
||||||
|
check-strictly default-expand-all placeholder="请选择上级编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row v-if="productPropertiesCategory === 0">
|
||||||
|
<el-col :span="21">
|
||||||
|
<el-form-item label="分类属性值" prop="productCategoryPropertiesValue">
|
||||||
|
<el-select v-model="formData.productCategoryPropertiesValue" placeholder="请选择产品分类属性值" clearable>
|
||||||
|
<el-option v-for="dict in productCategoryPropertiesValueList" :key="dict.id"
|
||||||
|
:label="dict.productCategoryPropertiesValue" :value="dict.productCategoryPropertiesValue" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1">
|
||||||
|
<span></span>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="openValueForm">新 增</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ProductCategoryPropertiesCategoryMapApi, ProductCategoryPropertiesCategoryMapVO } from '@/api/erp/product/category/productcategoryproperties/propertiescategorymap'
|
||||||
|
import { ProductCategoryApi } from '@/api/erp/product/category'
|
||||||
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
|
import { ProductCategoryPropertiesApi } from '@/api/erp/product/category/productcategoryproperties'
|
||||||
|
import { ProductCategoryPropertiesValueApi, ProductCategoryPropertiesValueVO } from '@/api/erp/product/category/productcategoryproperties/productcategorypropertiesvalue'
|
||||||
|
|
||||||
|
|
||||||
|
/** 产品属性类别 */
|
||||||
|
let productPropertiesCategory = ref()
|
||||||
|
|
||||||
|
/** 产品分类的list */
|
||||||
|
const productCategoryTree = ref() // 树形结构
|
||||||
|
|
||||||
|
/** 从父组件取数据*/
|
||||||
|
const props = defineProps<{
|
||||||
|
productPropertiesCn: string,
|
||||||
|
productCategoryPropertiesId: number,
|
||||||
|
}>();
|
||||||
|
|
||||||
|
/** ERP 产品分类属性绑定 表单 */
|
||||||
|
defineOptions({ name: 'ProductCategoryPropertiesCategoryMapForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
//分类属性值新增弹窗
|
||||||
|
const valueDialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const valueFormData = ref({
|
||||||
|
productCategoryPropertiesValue: null as any
|
||||||
|
})
|
||||||
|
const valueFormRules = reactive({
|
||||||
|
productCategoryPropertiesValue: [
|
||||||
|
{ required: true, message: '请输入分类属性值', trigger: 'blur' },
|
||||||
|
]
|
||||||
|
})
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productPropertiesCn: null as any,
|
||||||
|
productCategoryId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined,
|
||||||
|
productCategoryPropertiesId: null as any
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
/** 分类属性值list */
|
||||||
|
const productCategoryPropertiesValueList = ref()
|
||||||
|
|
||||||
|
/** 新增分类属性值 */
|
||||||
|
const addProductCategoryPropertiesValue = async () => {
|
||||||
|
const data = {
|
||||||
|
productCategoryPropertiesId: props.productCategoryPropertiesId,
|
||||||
|
productCategoryPropertiesValue: valueFormData.value.productCategoryPropertiesValue
|
||||||
|
}
|
||||||
|
await ProductCategoryPropertiesValueApi.createProductCategoryPropertiesValue(data).then((res) => {
|
||||||
|
getAllProductCategoryPropertiesValue()
|
||||||
|
valueDialogVisible.value = false
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询分类属性值的可选项 */
|
||||||
|
const getAllProductCategoryPropertiesValue = async () => {
|
||||||
|
await ProductCategoryPropertiesValueApi.getProductCategoryPropertiesValuePage({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
productCategoryPropertiesId: props.productCategoryPropertiesId
|
||||||
|
}).then((res) => {
|
||||||
|
productCategoryPropertiesValueList.value = res.list
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 判断使用下拉还是使用自定义属性 */
|
||||||
|
const getProductPropertiesCategory = async () => {
|
||||||
|
|
||||||
|
ProductCategoryPropertiesApi.getProductCategoryProperties(props.productCategoryPropertiesId).then((res) => {
|
||||||
|
productPropertiesCategory.value = res.productPropertiesCategory
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/** 打开分类属性值弹窗 */
|
||||||
|
const openValueForm = () => {
|
||||||
|
valueDialogVisible.value = true
|
||||||
|
}
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
formData.value.productCategoryPropertiesId = props.productCategoryPropertiesId
|
||||||
|
formData.value.productPropertiesCn = props.productPropertiesCn
|
||||||
|
await getProductPropertiesCategory()
|
||||||
|
await getAllProductCategoryPropertiesValue()
|
||||||
|
getAllProductCategory()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ProductCategoryPropertiesCategoryMapApi.getProductCategoryPropertiesCategoryMap(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
console.log(formData.value)
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductCategoryPropertiesCategoryMapVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductCategoryPropertiesCategoryMapApi.createProductCategoryPropertiesCategoryMap(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductCategoryPropertiesCategoryMapApi.updateProductCategoryPropertiesCategoryMap(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productPropertiesCn: null as any,
|
||||||
|
productCategoryId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined,
|
||||||
|
productCategoryPropertiesId: null as any
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取所有产品分类 */
|
||||||
|
const getAllProductCategory = async () => {
|
||||||
|
productCategoryTree.value = []
|
||||||
|
const data = await ProductCategoryApi.getProductCategoryList({})
|
||||||
|
const root: Tree = { id: 0, name: '顶级产品分类', children: [] }
|
||||||
|
root.children = handleTree(data, 'id', 'parentId')
|
||||||
|
productCategoryTree.value.push(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 通过分类属性查询分类属性的详情 */
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="分类属性">
|
||||||
|
<el-input
|
||||||
|
v-model="productPropertiesCn"
|
||||||
|
placeholder="请输入分类属性"
|
||||||
|
clearable
|
||||||
|
disabled
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-category-properties-category-map:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-category-properties-category-map:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品分类" align="center" prop="productCategoryValue" v-if="productPropertiesCategory===1"/>
|
||||||
|
<el-table-column label="分类属性值" align="center" prop="productCategoryPropertiesValue" v-if="productPropertiesCategory===0"/>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties-category-map:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-category-properties-category-map:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductCategoryPropertiesCategoryMapForm ref="formRef" @success="getList" :product-properties-cn="productPropertiesCn" :product-category-properties-id="Number(route.query.productCategoryPropertiesId)"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductCategoryPropertiesCategoryMapApi, ProductCategoryPropertiesCategoryMapVO } from '@/api/erp/product/category/productcategoryproperties/propertiescategorymap'
|
||||||
|
import ProductCategoryPropertiesCategoryMapForm from './ProductCategoryPropertiesCategoryMapForm.vue'
|
||||||
|
import { ProductCategoryPropertiesApi } from '@/api/erp/product/category/productcategoryproperties'
|
||||||
|
|
||||||
|
const route = useRoute() // 路由
|
||||||
|
let searchCount = 0
|
||||||
|
/** ERP 产品分类属性绑定 列表 */
|
||||||
|
defineOptions({ name: 'ErpProductCategoryPropertiesCategoryMap' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryPropertiesCategoryMapVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryPropertiesId: null as any,
|
||||||
|
productCategoryId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
/** 分类属性中文 */
|
||||||
|
let productPropertiesCn = ref('')
|
||||||
|
/** 产品属性分类 */
|
||||||
|
let productPropertiesCategory = ref()
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
if(route.query.productCategoryPropertiesId && searchCount == 0){
|
||||||
|
searchCount++
|
||||||
|
queryParams.productCategoryPropertiesId = Number(route.query.productCategoryPropertiesId)
|
||||||
|
}
|
||||||
|
if(route.query.productPropertiesCategory){
|
||||||
|
productPropertiesCategory.value = Number(route.query.productPropertiesCategory)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryPropertiesCategoryMapApi.getProductCategoryPropertiesCategoryMapPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductCategoryPropertiesCategoryMapApi.deleteProductCategoryPropertiesCategoryMap(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductCategoryPropertiesCategoryMapApi.exportProductCategoryPropertiesCategoryMap(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品分类属性绑定.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 根据用户输入搜索类别 */
|
||||||
|
const searchProductCategoryProperties = async () => {
|
||||||
|
//通过分类属性id查询详情
|
||||||
|
if (!route.query.productCategoryPropertiesId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ProductCategoryPropertiesApi.getProductCategoryProperties(Number(route.query.productCategoryPropertiesId)).then(res => {
|
||||||
|
productPropertiesCn.value = res.productPropertiesCn
|
||||||
|
})
|
||||||
|
}catch (error) {
|
||||||
|
message.error('查询分类属性失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
searchProductCategoryProperties()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
<!-- ERP 产品的新增/修改 -->
|
<!-- ERP 产品的新增/修改 -->
|
||||||
<template>
|
<template>
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
<el-form
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
|
||||||
ref="formRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="100px"
|
|
||||||
v-loading="formLoading"
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="名称" prop="name">
|
<el-form-item label="名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入名称" />
|
<el-input v-model="formData.name" disabled placeholder="请输入名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
|
|
@ -21,37 +15,46 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="分类" prop="categoryId">
|
<el-form-item label="分类" prop="categoryId">
|
||||||
<el-tree-select
|
<el-tree-select filterable v-model="formData.categoryId" :data="categoryList" :props="defaultProps" check-strictly
|
||||||
v-model="formData.categoryId"
|
default-expand-all placeholder="请选择分类" class="w-1/1" />
|
||||||
:data="categoryList"
|
</el-form-item>
|
||||||
:props="defaultProps"
|
</el-col>
|
||||||
check-strictly
|
<el-col :span="12">
|
||||||
default-expand-all
|
|
||||||
placeholder="请选择分类"
|
<el-form-item label="产品品牌" prop="brandId">
|
||||||
class="w-1/1"
|
<el-select v-model="formData.brandId" placeholder="请输入产品品牌" filterable clearable class="!w-240px">
|
||||||
/>
|
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.ERP_PRODUCT_BRAND)" :key="dict.value"
|
||||||
|
:label="dict.label" :value="dict.value" @click="handleBrandModelClick(dict.label)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="产品型号" prop="model">
|
||||||
|
<el-input v-model="formData.model" @blur="handleModelBlur" placeholder="请输入产品型号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="单位" prop="unitId">
|
<el-form-item label="单位" prop="unitId">
|
||||||
<el-select v-model="formData.unitId" clearable placeholder="请选择单位" class="w-1/1">
|
<el-select v-model="formData.unitId" clearable placeholder="请选择单位" class="w-1/1">
|
||||||
<el-option
|
<el-option v-for="unit in unitList" :key="unit.id" :label="unit.name" :value="unit.id" />
|
||||||
v-for="unit in unitList"
|
|
||||||
:key="unit.id"
|
|
||||||
:label="unit.name"
|
|
||||||
:value="unit.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio
|
<el-radio v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value"
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
:value="dict.value">
|
||||||
:key="dict.value"
|
{{ dict.label }}
|
||||||
:value="dict.value"
|
</el-radio>
|
||||||
>
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="一物一码" prop="ifQr">
|
||||||
|
<el-radio-group v-model="formData.ifQr">
|
||||||
|
<el-radio v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value"
|
||||||
|
:value="dict.value">
|
||||||
{{ dict.label }}
|
{{ dict.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
|
@ -64,56 +67,31 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="保质期天数" prop="expiryDay">
|
<el-form-item label="保质期天数" prop="expiryDay">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.expiryDay" placeholder="请输入保质期天数" :min="0" :precision="0"
|
||||||
v-model="formData.expiryDay"
|
class="!w-1/1" />
|
||||||
placeholder="请输入保质期天数"
|
|
||||||
:min="0"
|
|
||||||
:precision="0"
|
|
||||||
class="!w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="重量(kg)" prop="weight">
|
<el-form-item label="重量(kg)" prop="weight">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.weight" placeholder="请输入重量(kg)" :min="0" class="!w-1/1" />
|
||||||
v-model="formData.weight"
|
|
||||||
placeholder="请输入重量(kg)"
|
|
||||||
:min="0"
|
|
||||||
class="!w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="采购价格" prop="purchasePrice">
|
<el-form-item label="采购价格" prop="purchasePrice">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.purchasePrice" placeholder="请输入采购价格,单位:元" :min="0" :precision="2"
|
||||||
v-model="formData.purchasePrice"
|
class="!w-1/1" />
|
||||||
placeholder="请输入采购价格,单位:元"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
class="!w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="销售价格" prop="salePrice">
|
<el-form-item label="销售价格" prop="salePrice">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.salePrice" placeholder="请输入销售价格,单位:元" :min="0" :precision="2"
|
||||||
v-model="formData.salePrice"
|
class="!w-1/1" />
|
||||||
placeholder="请输入销售价格,单位:元"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
class="!w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="最低价格" prop="minPrice">
|
<el-form-item label="最低价格" prop="minPrice">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.minPrice" placeholder="请输入最低价格,单位:元" :min="0" :precision="2"
|
||||||
v-model="formData.minPrice"
|
class="!w-1/1" />
|
||||||
placeholder="请输入最低价格,单位:元"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
class="!w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
|
|
@ -149,25 +127,32 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: '',
|
||||||
barCode: undefined,
|
barCode: undefined,
|
||||||
categoryId: undefined,
|
categoryId: undefined,
|
||||||
|
brandId: undefined,
|
||||||
|
model: undefined,
|
||||||
unitId: undefined,
|
unitId: undefined,
|
||||||
status: undefined,
|
status: 0,
|
||||||
standard: undefined,
|
standard: undefined,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
expiryDay: undefined,
|
expiryDay: undefined,
|
||||||
weight: undefined,
|
weight: undefined,
|
||||||
purchasePrice: undefined,
|
purchasePrice: undefined,
|
||||||
salePrice: undefined,
|
salePrice: undefined,
|
||||||
minPrice: undefined
|
minPrice: undefined,
|
||||||
|
ifQr: undefined
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
name: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
|
||||||
barCode: [{ required: true, message: '产品条码不能为空', trigger: 'blur' }],
|
barCode: [{ required: true, message: '产品条码不能为空', trigger: 'blur' }],
|
||||||
categoryId: [{ required: true, message: '产品分类编号不能为空', trigger: 'blur' }],
|
categoryId: [{ required: true, message: '产品分类编号不能为空', trigger: 'blur' }],
|
||||||
|
brandId: [{ required: true, message: '产品品牌不能为空', trigger: 'blur' }],
|
||||||
|
model: [{ required: true, message: '产品型号不能为空', trigger: 'blur' }],
|
||||||
unitId: [{ required: true, message: '单位编号不能为空', trigger: 'blur' }],
|
unitId: [{ required: true, message: '单位编号不能为空', trigger: 'blur' }],
|
||||||
status: [{ required: true, message: '产品状态不能为空', trigger: 'blur' }]
|
status: [{ required: true, message: '产品状态不能为空', trigger: 'blur' }],
|
||||||
|
ifQr: [{ required: true, message: '一物一码不能为空', trigger: 'blur' }]
|
||||||
|
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const categoryList = ref<ProductCategoryVO[]>([]) // 产品分类列表
|
const categoryList = ref<ProductCategoryVO[]>([]) // 产品分类列表
|
||||||
|
|
@ -219,14 +204,32 @@ const submitForm = async () => {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let brand = ''
|
||||||
|
/** 品牌选择后 */
|
||||||
|
const handleBrandModelClick = (label?:string) => {
|
||||||
|
if (label) {
|
||||||
|
brand = label
|
||||||
|
if (formData.value.model) {
|
||||||
|
formData.value.name = brand + ' ' + formData.value.model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** 型号失去焦点后 */
|
||||||
|
const handleModelBlur = () => {
|
||||||
|
if (formData.value.model && brand!=='') {
|
||||||
|
formData.value.name = brand +' ' + formData.value.model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: '',
|
||||||
barCode: undefined,
|
barCode: undefined,
|
||||||
categoryId: undefined,
|
categoryId: undefined,
|
||||||
|
brandId: undefined,
|
||||||
|
model: undefined,
|
||||||
unitId: undefined,
|
unitId: undefined,
|
||||||
status: CommonStatusEnum.ENABLE,
|
status: CommonStatusEnum.ENABLE,
|
||||||
standard: undefined,
|
standard: undefined,
|
||||||
|
|
@ -235,7 +238,8 @@ const resetForm = () => {
|
||||||
weight: undefined,
|
weight: undefined,
|
||||||
purchasePrice: undefined,
|
purchasePrice: undefined,
|
||||||
salePrice: undefined,
|
salePrice: undefined,
|
||||||
minPrice: undefined
|
minPrice: undefined,
|
||||||
|
ifQr: undefined
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
<template>
|
||||||
|
<!-- 列表 -->
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="70%">
|
||||||
|
<ContentWrap>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="单数属性" align="center" prop="ifSingleProperty">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifSingleProperty" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="属性英文" align="center" prop="productPropertiesEn" />
|
||||||
|
<el-table-column label="属性中文" align="center" prop="productPropertiesCn" />
|
||||||
|
<el-table-column label="必填" align="center" prop="ifRequired">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifRequired" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="属性分类" align="center" prop="productPropertiesCategory">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_PROPERTIES_CATEGORY" :value="scope.row.productPropertiesCategory" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="记录sn" align="center" prop="ifSn">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifRequired" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<!-- 普通属性 -->
|
||||||
|
<router-link
|
||||||
|
v-show="scope.row.productPropertiesCategory === 0"
|
||||||
|
:to="'/erp/product/product-category-properties-category-map?productCategoryPropertiesId=' + scope.row.id+'&productId='+fProductId+'&productPropertiesCategory='+scope.row.productPropertiesCategory+'&productCategoryId='+scope.row.productCategoryId+''"
|
||||||
|
v-hasPermi="['erp:product-properties-map:query']">
|
||||||
|
<el-button link type="primary">绑定</el-button>
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-show="scope.row.productPropertiesCategory === 1"
|
||||||
|
:to="'/erp/product/product-properties-map?productCategoryPropertiesId=' + scope.row.id+'&productId='+fProductId+'&productPropertiesCategory='+scope.row.productPropertiesCategory+'&productCategoryId='+scope.row.productCategoryId+''"
|
||||||
|
v-hasPermi="['erp:product-properties-map:query']">
|
||||||
|
<el-button link type="primary">绑定</el-button>
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList" />
|
||||||
|
</ContentWrap>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import { ProductCategoryPropertiesApi, ProductCategoryPropertiesVO } from '@/api/erp/product/category/productcategoryproperties'
|
||||||
|
|
||||||
|
/** 展示表格 */
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogTitle = ref('')
|
||||||
|
/** ERP 产品分类属性 列表 */
|
||||||
|
defineOptions({ name: 'ProductProperties' })
|
||||||
|
|
||||||
|
/** 传递过来的产品id */
|
||||||
|
let fProductId = ref()
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductCategoryPropertiesVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productCategoryId: null as any,
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ProductCategoryPropertiesApi.getProductCategoryPropertiesPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (productId: any,productCategoryId?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = "产品属性"
|
||||||
|
queryParams.productCategoryId = productCategoryId
|
||||||
|
fProductId = productId
|
||||||
|
await getList()
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="分类" prop="categoryId">
|
<el-form-item label="分类" prop="categoryId">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="queryParams.categoryId"
|
v-model="queryParams.categoryId"
|
||||||
|
|
@ -31,6 +32,7 @@
|
||||||
class="!w-240px"
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
|
@ -58,10 +60,15 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
<el-table-column label="条码" align="center" prop="barCode" />
|
<el-table-column label="条码" width="150" align="center" prop="barCode" />
|
||||||
<el-table-column label="名称" align="center" prop="name" />
|
<el-table-column label="名称" width="300" align="center" prop="name" />
|
||||||
<el-table-column label="规格" align="center" prop="standard" />
|
<el-table-column label="分类" width="150" align="center" prop="categoryName" />
|
||||||
<el-table-column label="分类" align="center" prop="categoryName" />
|
<el-table-column label="品牌" width="150" align="center" prop="brandId">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_PRODUCT_BRAND" :value="scope.row.brandId" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="型号" width="150" align="center" prop="model" />
|
||||||
<el-table-column label="单位" align="center" prop="unitName" />
|
<el-table-column label="单位" align="center" prop="unitName" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="采购价格"
|
label="采购价格"
|
||||||
|
|
@ -86,6 +93,11 @@
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="一物一码" align="center" prop="ifQr">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.ifQr" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="创建时间"
|
label="创建时间"
|
||||||
align="center"
|
align="center"
|
||||||
|
|
@ -93,8 +105,16 @@
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center" width="110">
|
<el-table-column label="操作" align="center" fixed="right" width="160">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openPropertiesForm(scope.row.id,scope.row.categoryId)"
|
||||||
|
v-hasPermi="['erp:product-properties-map:query']"
|
||||||
|
>
|
||||||
|
属性
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
@ -125,6 +145,10 @@
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<ProductForm ref="formRef" @success="getList" />
|
<ProductForm ref="formRef" @success="getList" />
|
||||||
|
<!-- 产品属性弹窗 -->
|
||||||
|
<ProductPropertiesForm ref="formPropertiesRef" @success="getList" />
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
@ -133,9 +157,10 @@ import download from '@/utils/download'
|
||||||
import { ProductApi, ProductVO } from '@/api/erp/product/product'
|
import { ProductApi, ProductVO } from '@/api/erp/product/product'
|
||||||
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
|
import { ProductCategoryApi, ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
import ProductForm from './ProductForm.vue'
|
import ProductForm from './ProductForm.vue'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions,DICT_TYPE } from '@/utils/dict'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
import { erpPriceTableColumnFormatter } from '@/utils'
|
import { erpPriceTableColumnFormatter } from '@/utils'
|
||||||
|
import ProductPropertiesForm from './ProductPropertiesForm.vue'
|
||||||
|
|
||||||
/** ERP 产品列表 */
|
/** ERP 产品列表 */
|
||||||
defineOptions({ name: 'ErpProduct' })
|
defineOptions({ name: 'ErpProduct' })
|
||||||
|
|
@ -150,7 +175,9 @@ const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
categoryId: undefined
|
categoryId: undefined,
|
||||||
|
brandId: undefined,
|
||||||
|
model: undefined,
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
@ -186,6 +213,12 @@ const openForm = (type: string, id?: number) => {
|
||||||
formRef.value.open(type, id)
|
formRef.value.open(type, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 产品属性 */
|
||||||
|
const formPropertiesRef = ref()
|
||||||
|
const openPropertiesForm = (id: number,productCategoryId: number) => {
|
||||||
|
formPropertiesRef.value.open(id,productCategoryId)
|
||||||
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (id: number) => {
|
const handleDelete = async (id: number) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品id" prop="productId">
|
||||||
|
<el-input v-model="formData.productId" disabled placeholder="请输入产品id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类属性" prop="productCategoryPropertiesId">
|
||||||
|
<el-input v-model="formData.productCategoryPropertiesId" disabled placeholder="请输入产品分类属性id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="属性" prop="productPropertiesProductId">
|
||||||
|
<el-select v-model="formData.productPropertiesProductId" placeholder="请选择产品属性产品">
|
||||||
|
<el-option
|
||||||
|
v-for="item in products"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类属性值" prop="productCategoryPropertiesValue">
|
||||||
|
<el-input v-model="formData.productCategoryPropertiesValue" placeholder="请输入产品分类属性值" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ProductPropertiesMapApi, ProductPropertiesMapVO } from '@/api/erp/product/product/productpropertiesmap'
|
||||||
|
import { ProductCategoryPropertiesCategoryMapApi,ProductCategoryPropertiesCategoryMapVO } from '@/api/erp/product/category/productcategoryproperties/propertiescategorymap'
|
||||||
|
import { ProductCategoryApi,ProductCategoryVO } from '@/api/erp/product/category'
|
||||||
|
import { ProductApi,ProductVO } from '@/api/erp/product/product'
|
||||||
|
|
||||||
|
/** 从父组件取值 */
|
||||||
|
const props = defineProps({
|
||||||
|
productCategoryPropertiesId: {
|
||||||
|
type: Number,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
productPropertiesCategory:{
|
||||||
|
type: Number,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
productId:{
|
||||||
|
type: Number,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/** ERP 产品属性映射 表单 */
|
||||||
|
defineOptions({ name: 'ProductPropertiesMapForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
productId: null as any,
|
||||||
|
productCategoryPropertiesId: null as any,
|
||||||
|
productPropertiesProductId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
productCategoryPropertiesId: [{ required: true, message: '产品分类属性id不能为空', trigger: 'blur' }],
|
||||||
|
productId: [{ required: true, message: '产品id不能为空', trigger: 'blur' }],
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
// 产品列表
|
||||||
|
const products = ref<ProductVO[]>([])
|
||||||
|
|
||||||
|
/** 通过 productCategoryPropertiesId查询所有的分类id */
|
||||||
|
const getProductPropertiesCategoryList = async () => {
|
||||||
|
if (props.productCategoryPropertiesId) {
|
||||||
|
//构建查询条件
|
||||||
|
const params = {
|
||||||
|
productCategoryPropertiesId: props.productCategoryPropertiesId
|
||||||
|
}
|
||||||
|
ProductCategoryPropertiesCategoryMapApi.getProductCategoryPropertiesCategoryMapPage(params).then((res) => {
|
||||||
|
const data = res.list as ProductCategoryPropertiesCategoryMapVO[]
|
||||||
|
//将所有的productCategoryId 汇总成数组
|
||||||
|
const productCategoryIds = data.map((item) => item.productCategoryId)
|
||||||
|
getProductList(productCategoryIds)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 通过productCategoryIds查询所有相关的product */
|
||||||
|
const getProductList = async (productCategoryIds: number[]) => {
|
||||||
|
if (productCategoryIds.length > 0) {
|
||||||
|
//构建查询条件
|
||||||
|
ProductApi.getProductListByCategoryIds(productCategoryIds).then((res) => {
|
||||||
|
|
||||||
|
products.value = res as ProductVO[]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
//赋值
|
||||||
|
formData.value.productId = props.productId
|
||||||
|
formData.value.productCategoryPropertiesId = props.productCategoryPropertiesId
|
||||||
|
await getProductPropertiesCategoryList()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ProductPropertiesMapApi.getProductPropertiesMap(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ProductPropertiesMapVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ProductPropertiesMapApi.createProductPropertiesMap(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ProductPropertiesMapApi.updateProductPropertiesMap(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
productId: null as any,
|
||||||
|
productCategoryPropertiesId: null as any,
|
||||||
|
productPropertiesProductId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="产品id" prop="productId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productId"
|
||||||
|
placeholder="请输入产品id"
|
||||||
|
disabled
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类属性" prop="productCategoryPropertiesId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productCategoryPropertiesId"
|
||||||
|
placeholder="请输入产品分类属性"
|
||||||
|
disabled
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:product-properties-map:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:product-properties-map:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||||
|
<el-table-column label="分类属性" align="center" prop="productCategoryPropertiesValue" />
|
||||||
|
<el-table-column label="属性名称" align="center" prop="productPropertiesName" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-properties-map:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:product-properties-map:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<ProductPropertiesMapForm ref="formRef" @success="getList" :product-id="route.query.productId" :product-category-properties-id="queryParams.productCategoryPropertiesId" :product-properties-category="productPropertiesCategory"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { ProductPropertiesMapApi, ProductPropertiesMapVO } from '@/api/erp/product/product/productpropertiesmap'
|
||||||
|
import ProductPropertiesMapForm from './ProductPropertiesMapForm.vue'
|
||||||
|
|
||||||
|
const route = useRoute() // 路由
|
||||||
|
let searchCount = 0
|
||||||
|
/** ERP 产品属性映射 列表 */
|
||||||
|
defineOptions({ name: 'ErpProductPropertiesMap' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<ProductPropertiesMapVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productId: null as any,
|
||||||
|
productCategoryPropertiesId: null as any,
|
||||||
|
productPropertiesProductId: undefined,
|
||||||
|
productCategoryPropertiesValue: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
const productPropertiesCategory = ref()
|
||||||
|
|
||||||
|
/** 通过路由获取次产品属性关联的所有的值 */
|
||||||
|
const getProductPropertiesProductList = async () => {
|
||||||
|
if(route.query.productCategoryPropertiesId){
|
||||||
|
queryParams.productCategoryPropertiesId = Number(route.query.productCategoryPropertiesId)
|
||||||
|
}
|
||||||
|
if(route.query.productId){
|
||||||
|
queryParams.productId = Number(route.query.productId)
|
||||||
|
}
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ProductPropertiesMapApi.getProductPropertiesMapPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ProductPropertiesMapApi.deleteProductPropertiesMap(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ProductPropertiesMapApi.exportProductPropertiesMap(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品属性映射.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getProductPropertiesProductList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -238,6 +238,11 @@ const open = async (type: string, id?: number) => {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
formData.value = await PurchaseInApi.getPurchaseIn(id)
|
formData.value = await PurchaseInApi.getPurchaseIn(id)
|
||||||
|
formData.value.items.forEach((item) => {
|
||||||
|
if(item.ifQr===0){
|
||||||
|
item.qrCodeLineCount = item.count
|
||||||
|
}
|
||||||
|
})
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
@ -286,6 +291,19 @@ const submitForm = async () => {
|
||||||
// 校验表单
|
// 校验表单
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
await itemFormRef.value.validate()
|
await itemFormRef.value.validate()
|
||||||
|
//校验每行的码的数量和入库数量是否一致
|
||||||
|
const items = formData.value.items
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i]
|
||||||
|
//先判断本行是否需要一物一码
|
||||||
|
if (item.ifQr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item.qrCodeLineCount !== item.count) {
|
||||||
|
message.error(`第 ${i + 1} 行的入库数量和码的数量不同`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
|
|
@ -22,7 +24,7 @@
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择仓库"
|
placeholder="请选择仓库"
|
||||||
@change="onChangeWarehouse($event, row)"
|
@change="onChangeWarehouse(row)"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in warehouseList"
|
v-for="item in warehouseList"
|
||||||
|
|
@ -34,6 +36,30 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="货位" min-width="125">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item
|
||||||
|
:prop="`${$index}.warehouseLocationId`"
|
||||||
|
:rules="formRules.warehouseLocationId"
|
||||||
|
class="mb-0px!"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
v-model="row.warehouseLocationId"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
placeholder="请选择货位"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in locationList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="产品名称" min-width="180">
|
<el-table-column label="产品名称" min-width="180">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
|
|
@ -62,27 +88,25 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="原数量"
|
label="已入库/原数量"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
min-width="80"
|
min-width="120"
|
||||||
v-if="formData[0]?.totalCount != null"
|
v-if="formData[0]?.totalCount != null"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
<el-input disabled v-model="row.totalCount" :formatter="erpCountInputFormatter" />
|
<el-input disabled :value="`${row.inCount}/${row.totalCount}`" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="码" fixed="right" min-width="40">
|
||||||
label="已入库"
|
<template #default="{ row, $index }">
|
||||||
fixed="right"
|
|
||||||
min-width="80"
|
|
||||||
v-if="formData[0]?.inCount != null"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
<el-input disabled v-model="row.inCount" :formatter="erpCountInputFormatter" />
|
<el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
|
||||||
|
<Icon icon="fa:qrcode" />
|
||||||
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -92,7 +116,8 @@
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="row.count"
|
v-model="row.count"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
:min="0.001"
|
:min="1"
|
||||||
|
:max="row.totalCount"
|
||||||
:precision="3"
|
:precision="3"
|
||||||
class="!w-100%"
|
class="!w-100%"
|
||||||
/>
|
/>
|
||||||
|
|
@ -159,23 +184,64 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" fixed="right" label="操作" width="60">
|
<el-table-column label="操作" align="center" fixed="right" width="120">
|
||||||
<template #default="{ $index }">
|
<template #default="{ $index }">
|
||||||
<el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
|
<el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
|
||||||
—
|
<span v-show="formData.length > 1 && !disabled" style="color: red">删除</span>
|
||||||
|
<span v-show="formData.length === 1 || disabled">删除</span>
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:disabled="formData[$index].count <= 1"
|
||||||
|
@click="openSplitDialog($index)"
|
||||||
|
link
|
||||||
|
style="color: blue"
|
||||||
|
>
|
||||||
|
拆分
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- 一物一码扫码弹窗 -->
|
||||||
|
<Dialog :title="productName" v-model="qrDialogVisible" :appendToBody="true">
|
||||||
|
<!-- 显示有效行数 -->
|
||||||
|
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
|
||||||
|
<div>需要扫描数: {{ qrNeedCount }}</div>
|
||||||
|
|
||||||
|
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitQr" type="primary"> 确 定 </el-button>
|
||||||
|
<el-button @click="qrDialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
<!-- 拆分弹窗 -->
|
||||||
|
<Dialog title="拆分" v-model="splitDialogVisible" :appendToBody="true">
|
||||||
|
<el-input-number
|
||||||
|
v-model="splitCount"
|
||||||
|
:min="1"
|
||||||
|
:max="currentRow.count"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="splitItem" type="primary"> 确 定 </el-button>
|
||||||
|
<el-button @click="splitDialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { WarehouseApi as WarehouseLocactionApi, WarehouseLocationVO } from '@/api/erp/warehouse'
|
||||||
import { StockApi } from '@/api/erp/stock/stock'
|
import { StockApi } from '@/api/erp/stock/stock'
|
||||||
import {
|
import {
|
||||||
erpCountInputFormatter,
|
erpCountInputFormatter,
|
||||||
erpPriceInputFormatter,
|
erpPriceInputFormatter,
|
||||||
erpPriceMultiply,
|
erpPriceMultiply,
|
||||||
getSumValue
|
getSumValue,
|
||||||
|
matchRulesFromDictOptions
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
||||||
|
|
||||||
|
|
@ -183,16 +249,100 @@ const props = defineProps<{
|
||||||
items: undefined
|
items: undefined
|
||||||
disabled: false
|
disabled: false
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref([])
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
|
warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
|
||||||
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
||||||
|
warehouseLocationId: [{ required: true, message: '货位不能为空', trigger: 'blur' }],
|
||||||
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref([]) // 表单 Ref
|
const formRef = ref([]) // 表单 Ref
|
||||||
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
||||||
|
const locationList = ref<WarehouseLocationVO[]>([]) // 仓库列表
|
||||||
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
||||||
|
//一物一码弹窗
|
||||||
|
const qrDialogVisible = ref(false)
|
||||||
|
// 扫码内容
|
||||||
|
const qrCodes = ref('')
|
||||||
|
// 当前点击行
|
||||||
|
const currentRow = ref<(typeof props.items)[0]>(undefined)
|
||||||
|
// 当前行号
|
||||||
|
const currentRowIndex = ref(-1)
|
||||||
|
// 一物一码弹窗名
|
||||||
|
const productName = ref('')
|
||||||
|
// 记录二维码文本域中的有效行数
|
||||||
|
const qrCodeLineCount = ref(0)
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
// 需要扫描二维码个数
|
||||||
|
const qrNeedCount = computed(() => {
|
||||||
|
return currentRow.value?.count
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听二维码文本域内容的变化
|
||||||
|
const onQrCodeChange = () => {
|
||||||
|
// 检查 qrCode.value 是否为 undefined 或 null
|
||||||
|
if (qrCodes.value) {
|
||||||
|
const lines = qrCodes.value.split('\n')
|
||||||
|
// 先将每一行去除首尾空格
|
||||||
|
const trimmedLines = lines.map((line) => line.trim())
|
||||||
|
const validLines = trimmedLines.filter((line) => {
|
||||||
|
return matchRulesFromDictOptions(line)
|
||||||
|
})
|
||||||
|
// 去重
|
||||||
|
const uniqueLines = [...new Set(validLines)]
|
||||||
|
qrCodeLineCount.value = uniqueLines.length
|
||||||
|
|
||||||
|
// 检查有效行数是否超过 row.count
|
||||||
|
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
|
||||||
|
message.warning('输入的有效行数不能超过该产品的数量!')
|
||||||
|
// 截取多余的行数
|
||||||
|
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n')
|
||||||
|
qrCodeLineCount.value = currentRow.value.count
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qrCodeLineCount.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 控制一物一码弹窗
|
||||||
|
const openQrDialog = (index: number) => {
|
||||||
|
// 确保 currentRow 更新为当前点击的行
|
||||||
|
currentRow.value = formData.value[index] // 使用解构赋值确保创建一个新对象
|
||||||
|
currentRowIndex.value = index
|
||||||
|
// 检查当前行是否有二维码数据
|
||||||
|
if (currentRow.value.qrcodes) {
|
||||||
|
qrCodes.value = currentRow.value.qrcodes
|
||||||
|
} else {
|
||||||
|
qrCodes.value = '' // 如果没有二维码数据,清空文本域
|
||||||
|
}
|
||||||
|
// 更新弹窗标题
|
||||||
|
productName.value = currentRow.value.productName
|
||||||
|
// 重新计算有效行数
|
||||||
|
onQrCodeChange()
|
||||||
|
// 显示弹窗
|
||||||
|
qrDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 提交扫码 */
|
||||||
|
const submitQr = async () => {
|
||||||
|
// 扫码内容不能为空
|
||||||
|
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 找到当前行在 formData 中的索引
|
||||||
|
const index = currentRowIndex.value // 获取当前行的索引
|
||||||
|
if (index !== -1 && formData.value[index]) {
|
||||||
|
// 确保索引有效且对应行存在
|
||||||
|
// 更新 formData 中对应行的 qrcode 值
|
||||||
|
formData.value[index].qrcodes = qrCodes.value
|
||||||
|
//更新有效行数
|
||||||
|
formData.value[index].qrCodeLineCount = qrCodeLineCount.value
|
||||||
|
}
|
||||||
|
// 关闭弹窗
|
||||||
|
qrDialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
/** 初始化设置入库项 */
|
/** 初始化设置入库项 */
|
||||||
watch(
|
watch(
|
||||||
|
|
@ -271,10 +421,56 @@ const handleAdd = () => {
|
||||||
}
|
}
|
||||||
formData.value.push(row)
|
formData.value.push(row)
|
||||||
}
|
}
|
||||||
|
const queryLocationParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
warehouseId: undefined as unknown
|
||||||
|
})
|
||||||
|
|
||||||
|
//仓库变更,同步变更货位列表
|
||||||
|
const onChangeWarehouse = async (row: (typeof props.items)[0]) => {
|
||||||
|
queryLocationParams.warehouseId = row.warehouseId
|
||||||
|
try {
|
||||||
|
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams)
|
||||||
|
if (response) {
|
||||||
|
if (response.list.length !== 0) {
|
||||||
|
locationList.value = response.list
|
||||||
|
} else {
|
||||||
|
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('获取货位列表失败,响应为空')
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response) {
|
||||||
|
// Axios错误,有响应体
|
||||||
|
console.error(
|
||||||
|
'获取货位列表失败,HTTP错误码:',
|
||||||
|
error.response.status,
|
||||||
|
',错误信息:',
|
||||||
|
error.response.data
|
||||||
|
)
|
||||||
|
} else if (error.request) {
|
||||||
|
// 发出了请求,但没有收到响应
|
||||||
|
console.error('获取货位列表失败,没有收到响应')
|
||||||
|
} else {
|
||||||
|
// 其他错误
|
||||||
|
console.error('获取货位列表时发生错误:', error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = (index: number) => {
|
const handleDelete = (index: number) => {
|
||||||
formData.value.splice(index, 1)
|
const deletedRow = formData.value.splice(index, 1)[0]
|
||||||
|
const deletedCount = deletedRow.count
|
||||||
|
const productId = deletedRow.productId
|
||||||
|
|
||||||
|
formData.value.forEach((row) => {
|
||||||
|
if (row.productId === productId) {
|
||||||
|
row.totalCount += deletedCount // 更新 totalCount 为当前行的数量加上被删除行的数量
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 加载库存 */
|
/** 加载库存 */
|
||||||
|
|
@ -296,5 +492,42 @@ defineExpose({ validate })
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
||||||
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
|
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
|
||||||
|
locationList.value = onChangeWarehouse({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
warehouseId: defaultWarehouse.value?.id
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 拆分弹窗
|
||||||
|
const splitDialogVisible = ref(false)
|
||||||
|
const splitCount = ref(1)
|
||||||
|
|
||||||
|
// 控制拆分弹窗
|
||||||
|
const openSplitDialog = (index: number) => {
|
||||||
|
currentRow.value = formData.value[index]
|
||||||
|
currentRowIndex.value = index
|
||||||
|
splitCount.value = 1
|
||||||
|
splitDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拆分操作
|
||||||
|
const splitItem = () => {
|
||||||
|
if (splitCount.value >= currentRow.value.count) {
|
||||||
|
message.warning('拆分数量不能大于或等于当前数量!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentRow.value.count -= splitCount.value
|
||||||
|
currentRow.value.totalCount = currentRow.value.count // 更新 totalCount 为当前行的数量
|
||||||
|
|
||||||
|
const newRow = {
|
||||||
|
...currentRow.value,
|
||||||
|
count: splitCount.value,
|
||||||
|
inCount: 0,
|
||||||
|
totalCount: currentRow.value.totalCount // 更新 totalCount 为当前行的数量
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.value.splice(currentRowIndex.value + 1, 0, newRow)
|
||||||
|
splitDialogVisible.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -66,11 +66,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="产品单价" fixed="right" min-width="120">
|
<el-table-column label="产品单价" fixed="right" min-width="120">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item
|
<el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
|
||||||
:prop="`${$index}.productPrice`"
|
|
||||||
:rules="formRules.productPrice"
|
|
||||||
class="mb-0px!"
|
|
||||||
>
|
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="row.productPrice"
|
v-model="row.productPrice"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
|
|
@ -157,7 +153,6 @@ const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref([])
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
||||||
productPrice: [{ required: true, message: '产品单价不能为空', trigger: 'blur' }],
|
|
||||||
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref([]) // 表单 Ref
|
const formRef = ref([]) // 表单 Ref
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
|
||||||
import PurchaseOrderReturnEnableList from '@/views/erp/purchase/order/components/PurchaseOrderReturnEnableList.vue'
|
import PurchaseOrderReturnEnableList from '@/views/erp/purchase/order/components/PurchaseOrderReturnEnableList.vue'
|
||||||
import { PurchaseOrderVO } from '@/api/erp/purchase/order'
|
import { PurchaseOrderVO } from '@/api/erp/purchase/order'
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
|
import { PurchaseInApi } from '@/api/erp/purchase/in'
|
||||||
|
|
||||||
/** ERP 采购退货表单 */
|
/** ERP 采购退货表单 */
|
||||||
defineOptions({ name: 'PurchaseReturnForm' })
|
defineOptions({ name: 'PurchaseReturnForm' })
|
||||||
|
|
@ -214,6 +215,12 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
const subTabsName = ref('item')
|
const subTabsName = ref('item')
|
||||||
const itemFormRef = ref()
|
const itemFormRef = ref()
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
orderNo: undefined
|
||||||
|
}) //获取采购入库单号
|
||||||
|
|
||||||
/** 计算 discountPrice、totalPrice 价格 */
|
/** 计算 discountPrice、totalPrice 价格 */
|
||||||
watch(
|
watch(
|
||||||
() => formData.value,
|
() => formData.value,
|
||||||
|
|
@ -242,6 +249,11 @@ const open = async (type: string, id?: number) => {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
formData.value = await PurchaseReturnApi.getPurchaseReturn(id)
|
formData.value = await PurchaseReturnApi.getPurchaseReturn(id)
|
||||||
|
formData.value.items.forEach((item) => {
|
||||||
|
if (item.ifQr === 0) {
|
||||||
|
item.qrCodeLineCount = item.count
|
||||||
|
}
|
||||||
|
})
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +277,7 @@ const openPurchaseOrderReturnEnableList = () => {
|
||||||
purchaseOrderReturnEnableListRef.value.open()
|
purchaseOrderReturnEnableListRef.value.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
|
const handlePurchaseOrderChange = async (order: PurchaseOrderVO) => {
|
||||||
// 将订单设置到退货单
|
// 将订单设置到退货单
|
||||||
formData.value.orderId = order.id
|
formData.value.orderId = order.id
|
||||||
formData.value.orderNo = order.no
|
formData.value.orderNo = order.no
|
||||||
|
|
@ -274,13 +286,25 @@ const handlePurchaseOrderChange = (order: PurchaseOrderVO) => {
|
||||||
formData.value.discountPercent = order.discountPercent
|
formData.value.discountPercent = order.discountPercent
|
||||||
formData.value.remark = order.remark
|
formData.value.remark = order.remark
|
||||||
formData.value.fileUrl = order.fileUrl
|
formData.value.fileUrl = order.fileUrl
|
||||||
// 将订单项设置到退货单项
|
|
||||||
order.items.forEach((item) => {
|
// 获取与采购订单号相关的采购入库单号列表
|
||||||
item.count = item.inCount - item.returnCount
|
const data = await PurchaseInApi.getPurchaseInPage(queryParams)
|
||||||
item.orderItemId = item.id
|
const purchaseInList = data.list
|
||||||
item.id = undefined
|
const items: { productId: any; count: any; orderItemId: any; id: undefined }[] = []
|
||||||
|
purchaseInList.forEach((purchaseIn) => {
|
||||||
|
purchaseIn.items.forEach((item) => {
|
||||||
|
if (item.count > 0) {
|
||||||
|
items.push({
|
||||||
|
...item,
|
||||||
|
count: item.count,
|
||||||
|
orderItemId: item.id,
|
||||||
|
id: undefined
|
||||||
})
|
})
|
||||||
formData.value.items = order.items.filter((item) => item.count > 0)
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// 按入库单顺序展示 items
|
||||||
|
formData.value.items = items
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 提交表单 */
|
/** 提交表单 */
|
||||||
|
|
@ -289,6 +313,19 @@ const submitForm = async () => {
|
||||||
// 校验表单
|
// 校验表单
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
await itemFormRef.value.validate()
|
await itemFormRef.value.validate()
|
||||||
|
//校验每行的码的数量和入库数量是否一致
|
||||||
|
const items = formData.value.items
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i]
|
||||||
|
//先判断本行是否需要一物一码
|
||||||
|
if (item.ifQr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (item.qrcodes.split('\n').length !== item.count) {
|
||||||
|
message.error(`第 ${i + 1} 行的退货数量和码的数量不同`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,37 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form
|
<div>
|
||||||
ref="formRef"
|
<div>
|
||||||
:model="formData"
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="0px"
|
||||||
:rules="formRules"
|
:inline-message="true" :disabled="disabled">
|
||||||
v-loading="formLoading"
|
|
||||||
label-width="0px"
|
|
||||||
:inline-message="true"
|
|
||||||
:disabled="disabled"
|
|
||||||
>
|
|
||||||
<el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
|
<el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
|
||||||
<el-table-column label="序号" type="index" align="center" width="60" />
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
<el-table-column label="仓库名称" min-width="125">
|
<el-table-column label="仓库名称" min-width="125">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.warehouseId`" :rules="formRules.warehouseId" class="mb-0px!">
|
||||||
|
<el-select :disabled="!row.ifQr" v-model="row.warehouseId" clearable filterable placeholder="请选择仓库"
|
||||||
|
@change="onChangeWarehouse($event, row)">
|
||||||
|
<el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="货位" min-width="125">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
:prop="`${$index}.warehouseId`"
|
:prop="`${$index}.warehouseLocationId`"
|
||||||
:rules="formRules.warehouseId"
|
:rules="formRules.warehouseLocationId"
|
||||||
class="mb-0px!"
|
class="mb-0px!"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="row.warehouseId"
|
v-model="row.warehouseLocationId"
|
||||||
|
:disabled="!row.ifQr"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
placeholder="请选择仓库"
|
placeholder="请选择货位"
|
||||||
@change="onChangeWarehouse($event, row)"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in warehouseList"
|
v-for="item in locationList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
|
|
@ -55,6 +61,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="单位" min-width="80">
|
<el-table-column label="单位" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
|
|
@ -62,77 +69,61 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="已出库" fixed="right" min-width="80" v-if="formData[0]?.inCount != null">
|
||||||
label="已出库"
|
|
||||||
fixed="right"
|
|
||||||
min-width="80"
|
|
||||||
v-if="formData[0]?.inCount != null"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
<el-input disabled v-model="row.inCount" :formatter="erpCountInputFormatter" />
|
<el-input disabled v-model="row.inCount" :formatter="erpCountInputFormatter" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column label="已退货" fixed="right" min-width="80" v-if="formData[0]?.returnCount != null">
|
||||||
label="已退货"
|
|
||||||
fixed="right"
|
|
||||||
min-width="80"
|
|
||||||
v-if="formData[0]?.returnCount != null"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
<el-input disabled v-model="row.returnCount" :formatter="erpCountInputFormatter" />
|
<el-input disabled v-model="row.returnCount" :formatter="erpCountInputFormatter" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="码" fixed="right" min-width="40">
|
||||||
|
<template #default="{ row ,$index}">
|
||||||
|
<el-form-item class="mb-0px!">
|
||||||
|
|
||||||
|
<el-button :disabled="row.ifQr" @click="openQrTable($index,row)" link>
|
||||||
|
<Icon icon="fa:qrcode" />
|
||||||
|
</el-button>
|
||||||
|
<!-- <el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
|
||||||
|
<Icon icon="fa:qrcode" />
|
||||||
|
</el-button> -->
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="数量" prop="count" fixed="right" min-width="140">
|
<el-table-column label="数量" prop="count" fixed="right" min-width="140">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
|
<el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
|
||||||
<el-input-number
|
<el-input-number v-model="row.count" controls-position="right" :min="0.001" :precision="3"
|
||||||
v-model="row.count"
|
class="!w-100%" />
|
||||||
controls-position="right"
|
|
||||||
:min="0.001"
|
|
||||||
:precision="3"
|
|
||||||
class="!w-100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="产品单价" fixed="right" min-width="120">
|
<el-table-column label="产品单价" fixed="right" min-width="120">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
|
<el-form-item :prop="`${$index}.productPrice`" class="mb-0px!">
|
||||||
<el-input-number
|
<el-input-number v-model="row.productPrice" controls-position="right" :min="0.01" :precision="2"
|
||||||
v-model="row.productPrice"
|
class="!w-100%" />
|
||||||
controls-position="right"
|
|
||||||
:min="0.01"
|
|
||||||
:precision="2"
|
|
||||||
class="!w-100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="金额" prop="totalProductPrice" fixed="right" min-width="100">
|
<el-table-column label="金额" prop="totalProductPrice" fixed="right" min-width="100">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.totalProductPrice`" class="mb-0px!">
|
<el-form-item :prop="`${$index}.totalProductPrice`" class="mb-0px!">
|
||||||
<el-input
|
<el-input disabled v-model="row.totalProductPrice" :formatter="erpPriceInputFormatter" />
|
||||||
disabled
|
|
||||||
v-model="row.totalProductPrice"
|
|
||||||
:formatter="erpPriceInputFormatter"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="税率(%)" fixed="right" min-width="115">
|
<el-table-column label="税率(%)" fixed="right" min-width="115">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-form-item :prop="`${$index}.taxPercent`" class="mb-0px!">
|
<el-form-item :prop="`${$index}.taxPercent`" class="mb-0px!">
|
||||||
<el-input-number
|
<el-input-number v-model="row.taxPercent" controls-position="right" :min="0" :precision="2"
|
||||||
v-model="row.taxPercent"
|
class="!w-100%" />
|
||||||
controls-position="right"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
class="!w-100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -168,14 +159,41 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- 一物一码扫码弹窗 -->
|
||||||
|
<Dialog :title="productName" v-model="qrDialogVisible" :appendToBody="true">
|
||||||
|
<!-- 显示有效行数 -->
|
||||||
|
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
|
||||||
|
<div>需要扫描数: {{ qrNeedCount }}</div>
|
||||||
|
|
||||||
|
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitQr" type="primary">
|
||||||
|
确 定
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="qrDialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
<PurchaseReturnItemQrForm ref="qrCodeTableDialogRef" :currentRowIndex="currentRowIndex" :currentRow="currentRow" @close="onQrDialogClose" @submit-data="onQrCodeList" />
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { WarehouseApi as WarehouseLocactionApi, WarehouseLocationVO } from '@/api/erp/warehouse'
|
||||||
|
import PurchaseReturnItemQrForm from './PurchaseReturnItemQrForm.vue';
|
||||||
|
|
||||||
|
|
||||||
import { StockApi } from '@/api/erp/stock/stock'
|
import { StockApi } from '@/api/erp/stock/stock'
|
||||||
import {
|
import {
|
||||||
erpCountInputFormatter,
|
erpCountInputFormatter,
|
||||||
erpPriceInputFormatter,
|
erpPriceInputFormatter,
|
||||||
erpPriceMultiply,
|
erpPriceMultiply,
|
||||||
getSumValue
|
getSumValue,
|
||||||
|
matchRulesFromDictOptions
|
||||||
|
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
||||||
|
|
||||||
|
|
@ -187,12 +205,113 @@ const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref([])
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
|
warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
|
||||||
|
warehouseLocationId: [{ required: true, message: '货位不能为空', trigger: 'blur' }],
|
||||||
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
|
||||||
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRef = ref([]) // 表单 Ref
|
const formRef = ref([]) // 表单 Ref
|
||||||
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
||||||
|
const locationList = ref<WarehouseLocationVO[]>([]) // 仓库列表
|
||||||
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
||||||
|
//一物一码弹窗
|
||||||
|
const qrDialogVisible = ref(false)
|
||||||
|
// 扫码内容
|
||||||
|
const qrCodes = ref('')
|
||||||
|
// 当前点击行
|
||||||
|
const currentRow = ref<typeof props.items[0]>(undefined)
|
||||||
|
// 当前行号
|
||||||
|
const currentRowIndex = ref()
|
||||||
|
// 一物一码弹窗名
|
||||||
|
const productName = ref('')
|
||||||
|
// 记录二维码文本域中的有效行数
|
||||||
|
const qrCodeLineCount = ref(0);
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
// 引用二维码表格弹窗组件
|
||||||
|
const qrCodeTableDialogRef = ref();
|
||||||
|
|
||||||
|
const queryLocationParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 100,
|
||||||
|
warehouseId: undefined as unknown
|
||||||
|
})
|
||||||
|
//接收子组件传过来的数据
|
||||||
|
const onQrCodeList = (qrCodeList, index) => {
|
||||||
|
//判断qrCodeList是否为空
|
||||||
|
if (qrCodeList.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//遍历qrCodeList转为qrcodes字符串
|
||||||
|
let qrcodes = ''
|
||||||
|
qrCodeList.forEach((item) => {
|
||||||
|
qrcodes += item.qr + '\n'
|
||||||
|
})
|
||||||
|
//去掉末尾的换行符
|
||||||
|
qrcodes = qrcodes.slice(0, -1)
|
||||||
|
//更新formData中对应行的qrcodes值
|
||||||
|
formData.value[index].qrcodes = qrcodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开二维码表格弹窗
|
||||||
|
const openQrTable = (index:number,row) => {
|
||||||
|
currentRow.value =row;
|
||||||
|
currentRowIndex.value = index;
|
||||||
|
qrCodeTableDialogRef.value.open(row,index);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理二维码表格弹窗关闭事件
|
||||||
|
const onQrDialogClose = () => {
|
||||||
|
// 可在这里添加一些关闭弹窗后的逻辑
|
||||||
|
};
|
||||||
|
// 需要扫描二维码个数
|
||||||
|
const qrNeedCount = computed(() => {
|
||||||
|
return currentRow.value?.count
|
||||||
|
})
|
||||||
|
// 监听二维码文本域内容的变化
|
||||||
|
const onQrCodeChange = () => {
|
||||||
|
// 检查 qrCode.value 是否为 undefined 或 null
|
||||||
|
if (qrCodes.value) {
|
||||||
|
const lines = qrCodes.value.split('\n');
|
||||||
|
// 先将每一行去除首尾空格
|
||||||
|
const trimmedLines = lines.map(line => line.trim());
|
||||||
|
const validLines = trimmedLines.filter(line =>{
|
||||||
|
return matchRulesFromDictOptions(line)
|
||||||
|
});
|
||||||
|
// 去重
|
||||||
|
const uniqueLines = [...new Set(validLines)];
|
||||||
|
qrCodeLineCount.value = uniqueLines.length;
|
||||||
|
|
||||||
|
// 检查有效行数是否超过 row.count
|
||||||
|
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
|
||||||
|
message.warning('输入的有效行数不能超过该产品的数量!');
|
||||||
|
// 截取多余的行数
|
||||||
|
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n');
|
||||||
|
qrCodeLineCount.value = currentRow.value.count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qrCodeLineCount.value = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交扫码 */
|
||||||
|
const submitQr = async () => {
|
||||||
|
// 扫码内容不能为空
|
||||||
|
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 找到当前行在 formData 中的索引
|
||||||
|
const index = currentRowIndex.value; // 获取当前行的索引
|
||||||
|
if (index !== -1 && formData.value[index]) { // 确保索引有效且对应行存在
|
||||||
|
// 更新 formData 中对应行的 qrcode 值
|
||||||
|
formData.value[index].qrcodes = qrCodes.value;
|
||||||
|
//更新有效行数
|
||||||
|
formData.value[index].qrCodeLineCount = qrCodeLineCount.value;
|
||||||
|
}
|
||||||
|
// 关闭弹窗
|
||||||
|
qrDialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** 初始化设置出库项 */
|
/** 初始化设置出库项 */
|
||||||
watch(
|
watch(
|
||||||
|
|
@ -232,6 +351,25 @@ watch(
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 控制一物一码弹窗
|
||||||
|
const openQrDialog = (index: number) => {
|
||||||
|
// 确保 currentRow 更新为当前点击的行
|
||||||
|
currentRow.value = formData.value[index]; // 使用解构赋值确保创建一个新对象
|
||||||
|
currentRowIndex.value = index;
|
||||||
|
// 检查当前行是否有二维码数据
|
||||||
|
if (currentRow.value.qrcodes) {
|
||||||
|
qrCodes.value = currentRow.value.qrcodes;
|
||||||
|
} else {
|
||||||
|
qrCodes.value = ''; // 如果没有二维码数据,清空文本域
|
||||||
|
}
|
||||||
|
// 更新弹窗标题
|
||||||
|
productName.value = currentRow.value.productName;
|
||||||
|
// 重新计算有效行数
|
||||||
|
onQrCodeChange();
|
||||||
|
// 显示弹窗
|
||||||
|
qrDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
/** 合计 */
|
/** 合计 */
|
||||||
const getSummaries = (param: SummaryMethodProps) => {
|
const getSummaries = (param: SummaryMethodProps) => {
|
||||||
const { columns, data } = param
|
const { columns, data } = param
|
||||||
|
|
@ -253,6 +391,36 @@ const getSummaries = (param: SummaryMethodProps) => {
|
||||||
return sums
|
return sums
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//仓库变更,同步变更货位列表
|
||||||
|
const onChangeWarehouse = async (row: typeof props.items[0]) => {
|
||||||
|
queryLocationParams.warehouseId = row.warehouseId;
|
||||||
|
try {
|
||||||
|
const response = await WarehouseLocactionApi.getWarehouseLocationPage(queryLocationParams);
|
||||||
|
if (response) {
|
||||||
|
if (response.list.length !== 0) {
|
||||||
|
locationList.value = response.list;
|
||||||
|
} else {
|
||||||
|
console.error('获取货位列表失败,错误码:', response.code, ',错误信息:', response.msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('获取货位列表失败,响应为空');
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response) {
|
||||||
|
// Axios错误,有响应体
|
||||||
|
console.error('获取货位列表失败,HTTP错误码:', error.response.status, ',错误信息:', error.response.data);
|
||||||
|
} else if (error.request) {
|
||||||
|
// 发出了请求,但没有收到响应
|
||||||
|
console.error('获取货位列表失败,没有收到响应');
|
||||||
|
} else {
|
||||||
|
// 其他错误
|
||||||
|
console.error('获取货位列表时发生错误:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
const row = {
|
const row = {
|
||||||
|
|
@ -296,5 +464,7 @@ defineExpose({ validate })
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
|
||||||
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
|
defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
|
||||||
|
locationList.value = onChangeWarehouse({pageNo: 1,pageSize: 100,warehouseId: defaultWarehouse.value?.id})
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="二维码列表" width="60%">
|
||||||
|
|
||||||
|
<el-form ref="formRef" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="20">
|
||||||
|
<el-form-item label="二维码" prop="no">
|
||||||
|
<el-input v-model="qr" ref="qrInputRef" placeholder="扫描二维码" @keyup.enter="handleQrEnter" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-form-item v-show="false" label="隐藏字段">
|
||||||
|
<el-input v-model="qrHiden" placeholder="隐藏字段" @keyup.enter="handleQrEnter" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table :data="qrCodeRowList">
|
||||||
|
<!-- 序号 -->
|
||||||
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
|
<el-table-column prop="qr" label="二维码" />
|
||||||
|
<el-table-column prop="warehouseName" label="仓库" />
|
||||||
|
<el-table-column prop="warehouseLocationName" label="货位" />
|
||||||
|
<el-table-column prop="productName" label="产品名称" />
|
||||||
|
<el-table-column prop="productUnitName" label="产品单位" />
|
||||||
|
<!-- 操作列 -->
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button @click="deleteRow(scope.$index)" link>
|
||||||
|
—
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</ContentWrap>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="submitQr">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, defineProps, defineEmits } from 'vue';
|
||||||
|
import {
|
||||||
|
matchRulesFromDictOptions
|
||||||
|
} from '@/utils'
|
||||||
|
import { PurchaseReturnItemsQrApi } from '@/api/erp/purchase/return/purchasereturnitemsqr/index';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
currentRow: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
currentRowIndex: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 监听 currentRowIndex 的变化
|
||||||
|
watch(() => props.currentRowIndex, (newIndex) => {
|
||||||
|
// 在这里处理 currentRowIndex 变化的逻辑
|
||||||
|
console.log('currentRowIndex 已更新为:', newIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const qr = ref('');
|
||||||
|
const qrHiden = ref('');
|
||||||
|
// 新增 ref 用于获取输入框 DOM 元素
|
||||||
|
const qrInputRef = ref(null);
|
||||||
|
|
||||||
|
const emits = defineEmits(['submit-data', 'close']);
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const qrCodeRowList = ref([]);
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
|
||||||
|
const open = async (row,index)=>{
|
||||||
|
// 当 currentRow 变化时,更新 qrCodeRowList
|
||||||
|
qrCodeRowList.value = [];
|
||||||
|
if (row.qrcodes) {
|
||||||
|
row.qrcodes.split('\n').forEach((item) => {
|
||||||
|
const newRow = { ...row, qr: item };
|
||||||
|
qrCodeRowList.value.push(newRow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交扫码 */
|
||||||
|
const submitQr = async () => {
|
||||||
|
// 扫码内容不能为空
|
||||||
|
if (qrCodeRowList.value.length === 0) {
|
||||||
|
message.warning('请扫描二维码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//判断二维码数与数量是否一致
|
||||||
|
if (qrCodeRowList.value.length !== props.currentRow.count) {
|
||||||
|
message.warning('扫码数量与数量不一致');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 找到当前行在 formData 中的索引
|
||||||
|
const index = props.currentRowIndex; // 获取当前行的索引
|
||||||
|
// 触发自定义事件 'submit-data' 并传递 qrCodeRowList 数据
|
||||||
|
emits('submit-data', qrCodeRowList.value, index);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理二维码输入
|
||||||
|
const handleQrEnter = () => {
|
||||||
|
|
||||||
|
if (!matchRulesFromDictOptions(qr.value)) {
|
||||||
|
// 提示用户输入的二维码格式不正确
|
||||||
|
message.warning('二维码格式不正确');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//将二维码填充到传入的当行数据中,并作为元素添加到列表中
|
||||||
|
const newRow = { ...props.currentRow, qr: qr.value };
|
||||||
|
qrCodeRowList.value.push(newRow);
|
||||||
|
// 清空输入框
|
||||||
|
qr.value = '';
|
||||||
|
// 让光标聚焦到输入框
|
||||||
|
if (qrInputRef.value) {
|
||||||
|
qrInputRef.value.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除行的方法
|
||||||
|
const deleteRow = (index: number) => {
|
||||||
|
qrCodeRowList.value.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
close
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -303,6 +303,19 @@ const submitForm = async () => {
|
||||||
// 校验表单
|
// 校验表单
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
await itemFormRef.value.validate()
|
await itemFormRef.value.validate()
|
||||||
|
//校验每行的码的数量和入库数量是否一致
|
||||||
|
const items = formData.value.items
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i]
|
||||||
|
//先判断本行是否需要一物一码
|
||||||
|
if (item.ifQr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item.qrCodeLineCount !== item.count) {
|
||||||
|
message.error(`第 ${i + 1} 行的入库数量和码的数量不同`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div><div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
|
|
@ -10,30 +11,6 @@
|
||||||
>
|
>
|
||||||
<el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
|
<el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
|
||||||
<el-table-column label="序号" type="index" align="center" width="60" />
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
<el-table-column label="仓库名称" min-width="125">
|
|
||||||
<template #default="{ row, $index }">
|
|
||||||
<el-form-item
|
|
||||||
:prop="`${$index}.warehouseId`"
|
|
||||||
:rules="formRules.warehouseId"
|
|
||||||
class="mb-0px!"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="row.warehouseId"
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
placeholder="请选择仓库"
|
|
||||||
@change="onChangeWarehouse($event, row)"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in warehouseList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="产品名称" min-width="180">
|
<el-table-column label="产品名称" min-width="180">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-form-item class="mb-0px!">
|
<el-form-item class="mb-0px!">
|
||||||
|
|
@ -62,6 +39,15 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="码" fixed="right" min-width="40">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<el-form-item class="mb-0px!">
|
||||||
|
<el-button :disabled="row.ifQr" @click="openQrDialog($index)" link>
|
||||||
|
<Icon icon="fa:qrcode" />
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="原数量"
|
label="原数量"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
|
|
@ -168,6 +154,24 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- 一物一码扫码弹窗 -->
|
||||||
|
<Dialog :title="productName" v-model="qrDialogVisible" :appendToBody="true">
|
||||||
|
<!-- 显示有效行数 -->
|
||||||
|
<div>输入的有效行数: {{ qrCodeLineCount }}</div>
|
||||||
|
<div>需要扫描数: {{ qrNeedCount }}</div>
|
||||||
|
|
||||||
|
<el-input type="textarea" v-model="qrCodes" :rows="10" @input="onQrCodeChange" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitQr" type="primary">
|
||||||
|
确 定
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="qrDialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { StockApi } from '@/api/erp/stock/stock'
|
import { StockApi } from '@/api/erp/stock/stock'
|
||||||
|
|
@ -175,7 +179,9 @@ import {
|
||||||
erpCountInputFormatter,
|
erpCountInputFormatter,
|
||||||
erpPriceInputFormatter,
|
erpPriceInputFormatter,
|
||||||
erpPriceMultiply,
|
erpPriceMultiply,
|
||||||
getSumValue
|
getSumValue,
|
||||||
|
matchRulesFromDictOptions
|
||||||
|
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
|
||||||
|
|
||||||
|
|
@ -193,6 +199,86 @@ const formRules = reactive({
|
||||||
const formRef = ref([]) // 表单 Ref
|
const formRef = ref([]) // 表单 Ref
|
||||||
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
const warehouseList = ref<WarehouseVO[]>([]) // 仓库列表
|
||||||
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
const defaultWarehouse = ref<WarehouseVO>(undefined) // 默认仓库
|
||||||
|
//一物一码弹窗
|
||||||
|
const qrDialogVisible = ref(false)
|
||||||
|
// 扫码内容
|
||||||
|
const qrCodes = ref('')
|
||||||
|
// 当前点击行
|
||||||
|
const currentRow = ref<typeof props.items[0]>(undefined)
|
||||||
|
// 当前行号
|
||||||
|
const currentRowIndex = ref(-1)
|
||||||
|
// 一物一码弹窗名
|
||||||
|
const productName = ref('')
|
||||||
|
// 记录二维码文本域中的有效行数
|
||||||
|
const qrCodeLineCount = ref(0);
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
// 需要扫描二维码个数
|
||||||
|
const qrNeedCount = computed(() => {
|
||||||
|
return currentRow.value?.count
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听二维码文本域内容的变化
|
||||||
|
const onQrCodeChange = () => {
|
||||||
|
// 检查 qrCode.value 是否为 undefined 或 null
|
||||||
|
if (qrCodes.value) {
|
||||||
|
const lines = qrCodes.value.split('\n');
|
||||||
|
// 先将每一行去除首尾空格
|
||||||
|
const trimmedLines = lines.map(line => line.trim());
|
||||||
|
const validLines = trimmedLines.filter(line =>{
|
||||||
|
return matchRulesFromDictOptions(line)
|
||||||
|
});
|
||||||
|
// 去重
|
||||||
|
const uniqueLines = [...new Set(validLines)];
|
||||||
|
qrCodeLineCount.value = uniqueLines.length;
|
||||||
|
|
||||||
|
// 检查有效行数是否超过 row.count
|
||||||
|
if (currentRow.value && qrCodeLineCount.value > currentRow.value.count) {
|
||||||
|
message.warning('输入的有效行数不能超过该产品的数量!');
|
||||||
|
// 截取多余的行数
|
||||||
|
qrCodes.value = validLines.slice(0, currentRow.value.count).join('\n');
|
||||||
|
qrCodeLineCount.value = currentRow.value.count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qrCodeLineCount.value = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交扫码 */
|
||||||
|
const submitQr = async () => {
|
||||||
|
// 扫码内容不能为空
|
||||||
|
if (qrCodes.value == null || qrCodes.value == undefined || qrCodes.value === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 找到当前行在 formData 中的索引
|
||||||
|
const index = currentRowIndex.value; // 获取当前行的索引
|
||||||
|
if (index !== -1 && formData.value[index]) { // 确保索引有效且对应行存在
|
||||||
|
// 更新 formData 中对应行的 qrcode 值
|
||||||
|
formData.value[index].qrcodes = qrCodes.value;
|
||||||
|
//更新有效行数
|
||||||
|
formData.value[index].qrCodeLineCount = qrCodeLineCount.value;
|
||||||
|
}
|
||||||
|
// 关闭弹窗
|
||||||
|
qrDialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 控制一物一码弹窗
|
||||||
|
const openQrDialog = (index: number) => {
|
||||||
|
// 确保 currentRow 更新为当前点击的行
|
||||||
|
currentRow.value = formData.value[index]; // 使用解构赋值确保创建一个新对象
|
||||||
|
currentRowIndex.value = index;
|
||||||
|
// 检查当前行是否有二维码数据
|
||||||
|
if (currentRow.value.qrcodes) {
|
||||||
|
qrCodes.value = currentRow.value.qrcodes;
|
||||||
|
} else {
|
||||||
|
qrCodes.value = ''; // 如果没有二维码数据,清空文本域
|
||||||
|
}
|
||||||
|
// 更新弹窗标题
|
||||||
|
productName.value = currentRow.value.productName;
|
||||||
|
// 重新计算有效行数
|
||||||
|
onQrCodeChange();
|
||||||
|
// 显示弹窗
|
||||||
|
qrDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
/** 初始化设置出库项 */
|
/** 初始化设置出库项 */
|
||||||
watch(
|
watch(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" title="二维码列表" width="60%">
|
||||||
|
|
||||||
|
<el-form ref="formRef" label-width="100px">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="20">
|
||||||
|
<el-form-item label="二维码" prop="no">
|
||||||
|
<el-input v-model="qr" ref="qrInputRef" placeholder="扫描二维码" @keyup.enter="handleQrEnter" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-form-item v-show="false" label="隐藏字段">
|
||||||
|
<el-input v-model="qrHiden" placeholder="隐藏字段" @keyup.enter="handleQrEnter" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table :data="qrCodeRowList">
|
||||||
|
<!-- 序号 -->
|
||||||
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
|
<el-table-column prop="qr" label="二维码" />
|
||||||
|
<el-table-column prop="warehouseName" label="仓库" />
|
||||||
|
<el-table-column prop="warehouseLocationName" label="货位" />
|
||||||
|
<el-table-column prop="productName" label="产品名称" />
|
||||||
|
<el-table-column prop="productUnitName" label="产品单位" />
|
||||||
|
<!-- 操作列 -->
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button @click="deleteRow(scope.$index)" link>
|
||||||
|
—
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</ContentWrap>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="submitQr">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, defineProps, defineEmits } from 'vue';
|
||||||
|
import {
|
||||||
|
matchRulesFromDictOptions
|
||||||
|
} from '@/utils'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
currentRow: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
currentRowIndex: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 监听 currentRowIndex 的变化
|
||||||
|
watch(() => props.currentRowIndex, (newIndex) => {
|
||||||
|
// 在这里处理 currentRowIndex 变化的逻辑
|
||||||
|
console.log('currentRowIndex 已更新为:', newIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const qr = ref('');
|
||||||
|
const qrHiden = ref('');
|
||||||
|
// 新增 ref 用于获取输入框 DOM 元素
|
||||||
|
const qrInputRef = ref(null);
|
||||||
|
|
||||||
|
const emits = defineEmits(['submit-data', 'close']);
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const qrCodeRowList = ref([]);
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
|
||||||
|
const open = async (row,index)=>{
|
||||||
|
// 当 currentRow 变化时,更新 qrCodeRowList
|
||||||
|
qrCodeRowList.value = [];
|
||||||
|
if (row.qrcodes) {
|
||||||
|
row.qrcodes.split('\n').forEach((item) => {
|
||||||
|
const newRow = { ...row, qr: item };
|
||||||
|
qrCodeRowList.value.push(newRow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 提交扫码 */
|
||||||
|
const submitQr = async () => {
|
||||||
|
// 扫码内容不能为空
|
||||||
|
if (qrCodeRowList.value.length === 0) {
|
||||||
|
message.warning('请扫描二维码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//判断二维码数与数量是否一致
|
||||||
|
if (qrCodeRowList.value.length !== props.currentRow.count) {
|
||||||
|
message.warning('扫码数量与数量不一致');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 找到当前行在 formData 中的索引
|
||||||
|
const index = props.currentRowIndex; // 获取当前行的索引
|
||||||
|
// 触发自定义事件 'submit-data' 并传递 qrCodeRowList 数据
|
||||||
|
emits('submit-data', qrCodeRowList.value, index);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理二维码输入
|
||||||
|
const handleQrEnter = () => {
|
||||||
|
|
||||||
|
if (!matchRulesFromDictOptions(qr.value)) {
|
||||||
|
// 提示用户输入的二维码格式不正确
|
||||||
|
message.warning('二维码格式不正确');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//将二维码填充到传入的当行数据中,并作为元素添加到列表中
|
||||||
|
const newRow = { ...props.currentRow, qr: qr.value };
|
||||||
|
qrCodeRowList.value.push(newRow);
|
||||||
|
// 清空输入框
|
||||||
|
qr.value = '';
|
||||||
|
// 让光标聚焦到输入框
|
||||||
|
if (qrInputRef.value) {
|
||||||
|
qrInputRef.value.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除行的方法
|
||||||
|
const deleteRow = (index: number) => {
|
||||||
|
qrCodeRowList.value.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
close
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="销售出库编号" prop="outId">
|
||||||
|
<el-input v-model="formData.outId" placeholder="请输入销售出库编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="销售订单项编号" prop="orderItemId">
|
||||||
|
<el-input v-model="formData.orderItemId" placeholder="请输入销售订单项编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="销售出库单项编号" prop="outItemId">
|
||||||
|
<el-input v-model="formData.outItemId" placeholder="请输入销售出库单项编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input v-model="formData.warehouseId" placeholder="请输入仓库编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-input v-model="formData.productId" placeholder="请输入产品编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品单位单位" prop="productUnitId">
|
||||||
|
<el-input v-model="formData.productUnitId" placeholder="请输入产品单位单位" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品单价" prop="productPrice">
|
||||||
|
<el-input v-model="formData.productPrice" placeholder="请输入产品单价" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="数量" prop="count">
|
||||||
|
<el-input v-model="formData.count" placeholder="请输入数量" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="总价" prop="totalPrice">
|
||||||
|
<el-input v-model="formData.totalPrice" placeholder="请输入总价" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="税率,百分比" prop="taxPercent">
|
||||||
|
<el-input v-model="formData.taxPercent" placeholder="请输入税率,百分比" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="税额,单位:元" prop="taxPrice">
|
||||||
|
<el-input v-model="formData.taxPrice" placeholder="请输入税额,单位:元" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="formData.remark" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { SaleOutItemsQrApi, SaleOutItemsQrVO } from '@/api/erp/sale/out/saleoutitemsqr'
|
||||||
|
|
||||||
|
|
||||||
|
/** ERP 销售出库项二维码 表单 */
|
||||||
|
defineOptions({ name: 'SaleOutItemsQrForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
outId: undefined,
|
||||||
|
orderItemId: undefined,
|
||||||
|
outItemId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
productUnitId: undefined,
|
||||||
|
productPrice: undefined,
|
||||||
|
count: undefined,
|
||||||
|
totalPrice: undefined,
|
||||||
|
taxPercent: undefined,
|
||||||
|
taxPrice: undefined,
|
||||||
|
remark: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
outId: [{ required: true, message: '销售出库编号不能为空', trigger: 'blur' }],
|
||||||
|
orderItemId: [{ required: true, message: '销售订单项编号不能为空', trigger: 'blur' }],
|
||||||
|
outItemId: [{ required: true, message: '销售出库单项编号不能为空', trigger: 'blur' }],
|
||||||
|
warehouseId: [{ required: true, message: '仓库编号不能为空', trigger: 'blur' }],
|
||||||
|
productId: [{ required: true, message: '产品编号不能为空', trigger: 'blur' }],
|
||||||
|
productUnitId: [{ required: true, message: '产品单位单位不能为空', trigger: 'blur' }],
|
||||||
|
productPrice: [{ required: true, message: '产品单价不能为空', trigger: 'blur' }],
|
||||||
|
count: [{ required: true, message: '数量不能为空', trigger: 'blur' }],
|
||||||
|
totalPrice: [{ required: true, message: '总价不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await SaleOutItemsQrApi.getSaleOutItemsQr(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as SaleOutItemsQrVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await SaleOutItemsQrApi.createSaleOutItemsQr(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await SaleOutItemsQrApi.updateSaleOutItemsQr(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
outId: undefined,
|
||||||
|
orderItemId: undefined,
|
||||||
|
outItemId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
productUnitId: undefined,
|
||||||
|
productPrice: undefined,
|
||||||
|
count: undefined,
|
||||||
|
totalPrice: undefined,
|
||||||
|
taxPercent: undefined,
|
||||||
|
taxPrice: undefined,
|
||||||
|
remark: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="销售出库编号" prop="outId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.outId"
|
||||||
|
placeholder="请输入销售出库编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="销售订单项编号" prop="orderItemId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.orderItemId"
|
||||||
|
placeholder="请输入销售订单项编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="销售出库单项编号" prop="outItemId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.outItemId"
|
||||||
|
placeholder="请输入销售出库单项编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.warehouseId"
|
||||||
|
placeholder="请输入仓库编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productId"
|
||||||
|
placeholder="请输入产品编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品单位单位" prop="productUnitId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productUnitId"
|
||||||
|
placeholder="请输入产品单位单位"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品单价" prop="productPrice">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productPrice"
|
||||||
|
placeholder="请输入产品单价"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="数量" prop="count">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.count"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="总价" prop="totalPrice">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.totalPrice"
|
||||||
|
placeholder="请输入总价"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="税率,百分比" prop="taxPercent">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.taxPercent"
|
||||||
|
placeholder="请输入税率,百分比"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="税额,单位:元" prop="taxPrice">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.taxPrice"
|
||||||
|
placeholder="请输入税额,单位:元"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.remark"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:sale-out-items-qr:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:sale-out-items-qr:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="销售出库编号" align="center" prop="outId" />
|
||||||
|
<el-table-column label="销售订单项编号" align="center" prop="orderItemId" />
|
||||||
|
<el-table-column label="销售出库单项编号" align="center" prop="outItemId" />
|
||||||
|
<el-table-column label="仓库编号" align="center" prop="warehouseId" />
|
||||||
|
<el-table-column label="产品编号" align="center" prop="productId" />
|
||||||
|
<el-table-column label="产品单位单位" align="center" prop="productUnitId" />
|
||||||
|
<el-table-column label="产品单价" align="center" prop="productPrice" />
|
||||||
|
<el-table-column label="数量" align="center" prop="count" />
|
||||||
|
<el-table-column label="总价" align="center" prop="totalPrice" />
|
||||||
|
<el-table-column label="税率,百分比" align="center" prop="taxPercent" />
|
||||||
|
<el-table-column label="税额,单位:元" align="center" prop="taxPrice" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:sale-out-items-qr:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:sale-out-items-qr:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<SaleOutItemsQrForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { SaleOutItemsQrApi, SaleOutItemsQrVO } from '@/api/erp/sale/out/saleoutitemsqr'
|
||||||
|
import SaleOutItemsQrForm from './SaleOutItemsQrForm.vue'
|
||||||
|
|
||||||
|
/** ERP 销售出库项二维码 列表 */
|
||||||
|
defineOptions({ name: 'ErpSaleOutItemsQr' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<SaleOutItemsQrVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
outId: undefined,
|
||||||
|
orderItemId: undefined,
|
||||||
|
outItemId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
productUnitId: undefined,
|
||||||
|
productPrice: undefined,
|
||||||
|
count: undefined,
|
||||||
|
totalPrice: undefined,
|
||||||
|
taxPercent: undefined,
|
||||||
|
taxPrice: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await SaleOutItemsQrApi.getSaleOutItemsQrPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await SaleOutItemsQrApi.deleteSaleOutItemsQr(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await SaleOutItemsQrApi.exportSaleOutItemsQr(queryParams)
|
||||||
|
download.excel(data, 'ERP 销售出库项二维码.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="明细编号" prop="recordId">
|
||||||
|
<el-input v-model="formData.recordId" placeholder="请输入明细编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-input v-model="formData.productId" placeholder="请输入产品编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input v-model="formData.warehouseId" placeholder="请输入仓库编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="货位编号" prop="warehouseLocationId">
|
||||||
|
<el-input v-model="formData.warehouseLocationId" placeholder="请输入货位编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务类型" prop="bizType">
|
||||||
|
<el-select v-model="formData.bizType" placeholder="请选择业务类型">
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务编号" prop="bizId">
|
||||||
|
<el-input v-model="formData.bizId" placeholder="请输入业务编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务项编号" prop="bizItemId">
|
||||||
|
<el-input v-model="formData.bizItemId" placeholder="请输入业务项编号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务单号" prop="bizNo">
|
||||||
|
<el-input v-model="formData.bizNo" placeholder="请输入业务单号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { StockRecordQrApi, StockRecordQrVO } from '@/api/erp/stock/record/stockrecordqr'
|
||||||
|
|
||||||
|
|
||||||
|
/** ERP 产品库存明细二维码 表单 */
|
||||||
|
defineOptions({ name: 'StockRecordQrForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
recordId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
warehouseLocationId: undefined,
|
||||||
|
bizType: undefined,
|
||||||
|
bizId: undefined,
|
||||||
|
bizItemId: undefined,
|
||||||
|
bizNo: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
recordId: [{ required: true, message: '明细编号不能为空', trigger: 'blur' }],
|
||||||
|
productId: [{ required: true, message: '产品编号不能为空', trigger: 'blur' }],
|
||||||
|
warehouseId: [{ required: true, message: '仓库编号不能为空', trigger: 'blur' }],
|
||||||
|
warehouseLocationId: [{ required: true, message: '货位编号不能为空', trigger: 'blur' }],
|
||||||
|
bizType: [{ required: true, message: '业务类型不能为空', trigger: 'change' }],
|
||||||
|
bizId: [{ required: true, message: '业务编号不能为空', trigger: 'blur' }],
|
||||||
|
bizItemId: [{ required: true, message: '业务项编号不能为空', trigger: 'blur' }],
|
||||||
|
bizNo: [{ required: true, message: '业务单号不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await StockRecordQrApi.getStockRecordQr(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as StockRecordQrVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await StockRecordQrApi.createStockRecordQr(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await StockRecordQrApi.updateStockRecordQr(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
recordId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
warehouseLocationId: undefined,
|
||||||
|
bizType: undefined,
|
||||||
|
bizId: undefined,
|
||||||
|
bizItemId: undefined,
|
||||||
|
bizNo: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,269 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="明细编号" prop="recordId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.recordId"
|
||||||
|
placeholder="请输入明细编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.productId"
|
||||||
|
placeholder="请输入产品编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.warehouseId"
|
||||||
|
placeholder="请输入仓库编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="货位编号" prop="warehouseLocationId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.warehouseLocationId"
|
||||||
|
placeholder="请输入货位编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务类型" prop="bizType">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.bizType"
|
||||||
|
placeholder="请选择业务类型"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务编号" prop="bizId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.bizId"
|
||||||
|
placeholder="请输入业务编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务项编号" prop="bizItemId">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.bizItemId"
|
||||||
|
placeholder="请输入业务项编号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="业务单号" prop="bizNo">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.bizNo"
|
||||||
|
placeholder="请输入业务单号"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.createTime"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-220px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:stock-record-qr:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:stock-record-qr:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="二维码" align="center" prop="qr" min-width="100" />
|
||||||
|
<el-table-column label="明细编号" align="center" prop="recordId" />
|
||||||
|
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||||
|
<el-table-column label="仓库" align="center" prop="warehouseName" />
|
||||||
|
<el-table-column label="货位" align="center" prop="warehouseLocationName" />
|
||||||
|
<el-table-column label="类型" align="center" prop="bizType" min-width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.ERP_STOCK_RECORD_BIZ_TYPE" :value="scope.row.bizType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="业务单号" align="center" prop="bizNo" />
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:stock-record-qr:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:stock-record-qr:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<StockRecordQrForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { StockRecordQrApi, StockRecordQrVO } from '@/api/erp/stock/record/stockrecordqr'
|
||||||
|
import StockRecordQrForm from './StockRecordQrForm.vue'
|
||||||
|
|
||||||
|
/** ERP 产品库存明细二维码 列表 */
|
||||||
|
defineOptions({ name: 'ErpStockRecordQr' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<StockRecordQrVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
recordId: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
warehouseLocationId: undefined,
|
||||||
|
bizType: undefined,
|
||||||
|
bizId: undefined,
|
||||||
|
bizItemId: undefined,
|
||||||
|
bizNo: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await StockRecordQrApi.getStockRecordQrPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await StockRecordQrApi.deleteStockRecordQr(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await StockRecordQrApi.exportStockRecordQr(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品库存明细二维码.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -80,6 +80,7 @@
|
||||||
:formatter="erpCountTableColumnFormatter"
|
:formatter="erpCountTableColumnFormatter"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="仓库" align="center" prop="warehouseName" />
|
<el-table-column label="仓库" align="center" prop="warehouseName" />
|
||||||
|
<el-table-column label="货位" align="center" prop="warehouseLocationName" />
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="二维码" prop="qr">
|
||||||
|
<el-input v-model="formData.qr" placeholder="请输入二维码" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-select v-model="formData.productId" placeholder="请选择产品编号">
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input v-model="formData.warehouseId" placeholder="请输入仓库编号" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { StockQrApi, StockQrVO } from '@/api/erp/stock/stock/stockqr'
|
||||||
|
|
||||||
|
/** ERP 产品库存二维码 表单 */
|
||||||
|
defineOptions({ name: 'StockQrForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
qr: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
qr: [{ required: true, message: '二维码不能为空', trigger: 'blur' }],
|
||||||
|
productId: [{ required: true, message: '产品编号不能为空', trigger: 'change' }],
|
||||||
|
warehouseId: [{ required: true, message: '仓库编号不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await StockQrApi.getStockQr(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as StockQrVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await StockQrApi.createStockQr(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await StockQrApi.updateStockQr(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
qr: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
|
||||||
|
<el-form-item label="二维码" prop="qr">
|
||||||
|
<el-input v-model="queryParams.qr" placeholder="请输入二维码" clearable @keyup.enter="handleQuery" class="!w-240px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="产品编号" prop="productId">
|
||||||
|
<el-select v-model="queryParams.productId" placeholder="请选择产品编号" clearable class="!w-240px">
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库编号" prop="warehouseId">
|
||||||
|
<el-input v-model="queryParams.warehouseId" placeholder="请输入仓库编号" clearable @keyup.enter="handleQuery"
|
||||||
|
class="!w-240px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker v-model="queryParams.createTime" value-format="YYYY-MM-DD HH:mm:ss" type="daterange"
|
||||||
|
start-placeholder="开始日期" end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" class="!w-220px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery">
|
||||||
|
<Icon icon="ep:search" class="mr-5px" /> 搜索
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetQuery">
|
||||||
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['erp:stock-qr:create']">
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button type="success" plain @click="handleExport" :loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:stock-qr:export']">
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="二维码" align="center" prop="qr" />
|
||||||
|
<el-table-column label="二维码图片" align="center" prop="qrImg">
|
||||||
|
<template #default="scope">
|
||||||
|
<img :src="scope.row.qrImgUrl" alt="二维码图片" class="w-50px h-50px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||||
|
<el-table-column label="仓库" align="center" prop="warehouseName" />
|
||||||
|
<el-table-column label="货位" align="center" prop="warehouseLocationName" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['erp:stock-qr:update']">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['erp:stock-qr:delete']">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList" />
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<StockQrForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { StockQrApi, StockQrVO } from '@/api/erp/stock/stock/stockqr'
|
||||||
|
import StockQrForm from './StockQrForm.vue'
|
||||||
|
import QRCode from 'qrcode' // 引入 qrcode 库
|
||||||
|
|
||||||
|
/** ERP 产品库存二维码 列表 */
|
||||||
|
defineOptions({ name: 'ErpStockQr' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<StockQrVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
qr: undefined,
|
||||||
|
productId: undefined,
|
||||||
|
warehouseId: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
// 生成二维码图片的函数
|
||||||
|
const generateQrCodeImage = async (qrValue: string): Promise<string> => {
|
||||||
|
try {
|
||||||
|
const base64 = await QRCode.toDataURL(qrValue)
|
||||||
|
return base64
|
||||||
|
} catch (error) {
|
||||||
|
console.error('生成二维码失败:', error)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await StockQrApi.getStockQrPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
// 遍历列表,为每个元素生成二维码图片
|
||||||
|
for (const item of list.value) {
|
||||||
|
if (item.qr) {
|
||||||
|
const imageUrl = await generateQrCodeImage(item.qr)
|
||||||
|
item.qrImgUrl = imageUrl // 假设添加一个新的属性 qrImgUrl 来存储图片链接
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await StockQrApi.deleteStockQr(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await StockQrApi.exportStockQr(queryParams)
|
||||||
|
download.excel(data, 'ERP 产品库存二维码.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="仓库名称" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入仓库名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库地址" prop="address">
|
||||||
|
<el-input v-model="formData.address" placeholder="请输入仓库地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库状态" prop="status">
|
||||||
|
<el-radio-group v-model="formData.status">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓储费" prop="warehousePrice">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData.warehousePrice"
|
||||||
|
placeholder="请输入仓储费,单位:元/天/KG"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
class="!w-1/1"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="搬运费" prop="truckagePrice">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData.truckagePrice"
|
||||||
|
placeholder="请输入搬运费,单位:元"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
class="!w-1/1"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="负责人" prop="principal">
|
||||||
|
<el-input v-model="formData.principal" placeholder="请输入负责人" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData.sort"
|
||||||
|
placeholder="请输入排序"
|
||||||
|
:precision="0"
|
||||||
|
class="!w-1/1"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/warehouse'
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
|
||||||
|
/** ERP 仓库 表单 */
|
||||||
|
defineOptions({ name: 'WarehouseForm' })
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
address: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
principal: undefined,
|
||||||
|
warehousePrice: undefined,
|
||||||
|
truckagePrice: undefined,
|
||||||
|
status: undefined,
|
||||||
|
defaultStatus: undefined
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
name: [{ required: true, message: '仓库名称不能为空', trigger: 'blur' }],
|
||||||
|
sort: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
|
||||||
|
status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await WarehouseApi.getWarehouse(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as WarehouseVO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await WarehouseApi.createWarehouse(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await WarehouseApi.updateWarehouse(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
address: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
principal: undefined,
|
||||||
|
warehousePrice: undefined,
|
||||||
|
truckagePrice: undefined,
|
||||||
|
status: undefined,
|
||||||
|
defaultStatus: undefined
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="货位名称" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入货位名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData.sort"
|
||||||
|
placeholder="请输入排序"
|
||||||
|
:precision="0"
|
||||||
|
class="!w-1/1"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="formData.remark" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="货位状态" prop="status">
|
||||||
|
<el-radio-group v-model="formData.status">
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { WarehouseApi } from '@/api/erp/warehouse'
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
status: undefined,
|
||||||
|
warehouseId: 0
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
name: [{ required: true, message: '货位名称不能为空', trigger: 'blur' }],
|
||||||
|
sort: [{ required: true, message: '排序不能为空', trigger: 'blur' }],
|
||||||
|
status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }],
|
||||||
|
warehouseId: [{ required: true, message: '仓库编号不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id: number, warehouseId: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
formData.value.warehouseId = warehouseId
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await WarehouseApi.getWarehouseLocation(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await WarehouseApi.createWarehouseLocation(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await WarehouseApi.updateWarehouseLocation(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
status: undefined,
|
||||||
|
warehouseId: 0
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
<template>
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:warehouse:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="货位编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="货位名称" align="center" prop="name" />
|
||||||
|
<el-table-column label="排序" align="center" prop="sort" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="货位状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:warehouse:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:warehouse:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<WarehouseLocationForm ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import { WarehouseApi } from '@/api/erp/warehouse'
|
||||||
|
import WarehouseLocationForm from './WarehouseLocationForm.vue'
|
||||||
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
warehouseId?: number // 仓库编号(主表的关联字段)
|
||||||
|
}>()
|
||||||
|
const loading = ref(false) // 列表的加载中
|
||||||
|
const list = ref([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
warehouseId: undefined as unknown
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
watch(
|
||||||
|
() => props.warehouseId,
|
||||||
|
(val: number) => {
|
||||||
|
if (!val) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
queryParams.warehouseId = val
|
||||||
|
handleQuery()
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await WarehouseApi.getWarehouseLocationPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
if (!props.warehouseId) {
|
||||||
|
message.error('请选择一个ERP 仓库')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formRef.value.open(type, id, props.warehouseId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await WarehouseApi.deleteWarehouseLocation(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,275 @@
|
||||||
|
<template>
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
<el-form-item label="仓库名称" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.name"
|
||||||
|
placeholder="请输入仓库名称"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="仓库状态" prop="status">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.status"
|
||||||
|
placeholder="请选择仓库状态"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['erp:warehouse:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['erp:warehouse:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
highlight-current-row
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
<el-table-column label="仓库名称" align="center" prop="name" />
|
||||||
|
<el-table-column label="仓库地址" align="center" prop="address" />
|
||||||
|
<el-table-column
|
||||||
|
label="仓储费"
|
||||||
|
align="center"
|
||||||
|
prop="warehousePrice"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
label="搬运费"
|
||||||
|
align="center"
|
||||||
|
prop="truckagePrice"
|
||||||
|
:formatter="erpPriceTableColumnFormatter"
|
||||||
|
/>
|
||||||
|
<el-table-column label="负责人" align="center" prop="principal" />
|
||||||
|
<el-table-column label="备注" align="center" prop="remark" />
|
||||||
|
<el-table-column label="排序" align="center" prop="sort" />
|
||||||
|
<el-table-column label="状态" align="center" prop="status">
|
||||||
|
<template #default="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否默认" align="center" prop="defaultStatus">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.defaultStatus"
|
||||||
|
:active-value="true"
|
||||||
|
:inactive-value="false"
|
||||||
|
@change="handleDefaultStatusChange(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
|
width="180px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['erp:warehouse:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['erp:warehouse:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<WarehouseForm ref="formRef" @success="getList" />
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<el-tabs model-value="warehouseLocation">
|
||||||
|
<el-tab-pane label="ERP 仓库货位" name="warehouseLocation">
|
||||||
|
<WarehouseLocationList :warehouse-id="currentRow.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { WarehouseApi, WarehouseVO } from '@/api/erp/warehouse'
|
||||||
|
import WarehouseForm from './WarehouseForm.vue'
|
||||||
|
import WarehouseLocationList from './components/WarehouseLocationList.vue'
|
||||||
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { erpPriceTableColumnFormatter } from '@/utils'
|
||||||
|
|
||||||
|
/** ERP 仓库 列表 */
|
||||||
|
defineOptions({ name: 'Warehouse' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
|
const loading = ref(true) // 列表的加载中
|
||||||
|
const list = ref<WarehouseVO[]>([]) // 列表的数据
|
||||||
|
const total = ref(0) // 列表的总页数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: undefined,
|
||||||
|
address: undefined,
|
||||||
|
sort: undefined,
|
||||||
|
remark: undefined,
|
||||||
|
principal: undefined,
|
||||||
|
warehousePrice: undefined,
|
||||||
|
truckagePrice: undefined,
|
||||||
|
status: undefined,
|
||||||
|
defaultStatus: undefined,
|
||||||
|
createTime: []
|
||||||
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
|
/** 查询列表 */
|
||||||
|
const getList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await WarehouseApi.getWarehousePage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
const handleQuery = () => {
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await WarehouseApi.deleteWarehouse(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 修改默认状态 */
|
||||||
|
const handleDefaultStatusChange = async (row: WarehouseVO) => {
|
||||||
|
try {
|
||||||
|
// 修改状态的二次确认
|
||||||
|
const text = row.defaultStatus ? '设置' : '取消'
|
||||||
|
await message.confirm('确认要' + text + '"' + row.name + '"默认吗?')
|
||||||
|
// 发起修改状态
|
||||||
|
await WarehouseApi.updateWarehouseDefaultStatus(row.id, row.defaultStatus)
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch (e) {
|
||||||
|
// 取消后,进行恢复按钮
|
||||||
|
row.defaultStatus = !row.defaultStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await WarehouseApi.exportWarehouse(queryParams)
|
||||||
|
download.excel(data, 'ERP 仓库.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 选中行操作 */
|
||||||
|
const currentRow = ref({
|
||||||
|
id: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
// 选中行
|
||||||
|
const handleCurrentChange = (row) => {
|
||||||
|
currentRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue