feat(wms):增加 code 字段生成(从后端到前端),用户更可控

wms
YunaiV 2026-05-15 10:22:37 +08:00
parent 5f944548a3
commit d128df618e
11 changed files with 141 additions and 11 deletions

View File

@ -3,6 +3,7 @@ import request from '@/config/axios'
// WMS 商品品牌 VO
export interface ItemBrandVO {
id?: number
code?: string
name?: string
createTime?: Date
}

View File

@ -4,6 +4,7 @@ import request from '@/config/axios'
export interface ItemCategoryVO {
id?: number
parentId?: number
code?: string
name?: string
sort?: number
status?: number

View File

@ -22,7 +22,11 @@
</el-col>
<el-col :span="12">
<el-form-item label="商品编号" prop="code">
<el-input v-model="formData.code" maxlength="20" placeholder="请输入商品编号" />
<el-input v-model="formData.code" maxlength="20" placeholder="请输入商品编号">
<template #append>
<el-button @click="formData.code = generateWmsCode('I')">生成</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@ -68,15 +72,23 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column label="编号/条码" width="220">
<el-table-column label="编号/条码" width="260">
<template #default="scope">
<el-input v-model="scope.row.code" maxlength="64" class="!w-1/1" placeholder="编号" />
<el-input v-model="scope.row.code" maxlength="64" class="!w-1/1" placeholder="编号">
<template #append>
<el-button @click="scope.row.code = generateWmsCode('S')">生成</el-button>
</template>
</el-input>
<el-input
v-model="scope.row.barCode"
maxlength="64"
class="!w-1/1 mt-5px"
placeholder="条码为空时,提交后自动生成"
/>
placeholder="条码"
>
<template #append>
<el-button @click="scope.row.barCode = generateWmsCode()">生成</el-button>
</template>
</el-input>
</template>
</el-table-column>
<el-table-column label="长/宽/高(cm)" width="210">
@ -168,6 +180,7 @@ import { FormRules } from 'element-plus'
import { ItemApi, ItemVO } from '@/api/wms/md/item'
import { ItemSkuVO } from '@/api/wms/md/item/sku'
import { DIMENSION_PRECISION, PRICE_PRECISION, WEIGHT_PRECISION } from '@/views/wms/utils/format'
import { generateWmsCode } from '@/views/wms/utils/constants'
import ItemBrandSelect from './brand/components/ItemBrandSelect.vue'
import ItemCategorySelect from './category/components/ItemCategorySelect.vue'
@ -192,6 +205,7 @@ const formData = ref<ItemVO>({
skus: []
})
const formRules = reactive<FormRules>({
code: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '商品名称不能为空', trigger: 'blur' }],
categoryId: [{ required: true, message: '商品分类不能为空', trigger: 'change' }],
skus: [{ required: true, message: '至少包含一个商品规格', trigger: 'change' }]

View File

@ -8,6 +8,13 @@
:rules="formRules"
label-width="100px"
>
<el-form-item label="品牌编号" prop="code">
<el-input v-model="formData.code" maxlength="20" placeholder="请输入品牌编号">
<template #append>
<el-button @click="formData.code = generateWmsCode('B')">生成</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="品牌名称" prop="name">
<el-input v-model="formData.name" maxlength="30" placeholder="请输入品牌名称" />
</el-form-item>
@ -21,6 +28,7 @@
<script lang="ts" setup>
import { ItemBrandApi, ItemBrandVO } from '@/api/wms/md/item/brand'
import { generateWmsCode } from '@/views/wms/utils/constants'
/** WMS 商品品牌表单 */
defineOptions({ name: 'WmsItemBrandForm' })
@ -34,9 +42,11 @@ const formLoading = ref(false) // 表单的加载中1修改时的数据加
const formType = ref('') // create - update -
const formData = ref<ItemBrandVO>({
id: undefined,
code: undefined,
name: undefined
})
const formRules = reactive({
code: [{ required: true, message: '品牌编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '品牌名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
@ -87,6 +97,7 @@ const submitForm = async () => {
const resetForm = () => {
formData.value = {
id: undefined,
code: undefined,
name: undefined
}
formRef.value?.resetFields()

View File

@ -9,6 +9,15 @@
class="-mb-15px"
label-width="68px"
>
<el-form-item label="品牌编号" prop="code">
<el-input
v-model="queryParams.code"
class="!w-240px"
clearable
placeholder="请输入品牌编号"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="品牌名称" prop="name">
<el-input
v-model="queryParams.name"
@ -53,6 +62,7 @@
<!-- 品牌列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" label="品牌编号" prop="code" width="160" />
<el-table-column align="center" label="品牌名称" prop="name" />
<el-table-column
:formatter="dateFormatter"
@ -113,6 +123,7 @@ const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: undefined,
name: undefined
})
const queryFormRef = ref() //

View File

@ -16,9 +16,15 @@
check-strictly
default-expand-all
placeholder="请选择上级分类"
value-key="categoryId"
/>
</el-form-item>
<el-form-item label="分类编号" prop="code">
<el-input v-model="formData.code" maxlength="20" placeholder="请输入分类编号">
<template #append>
<el-button @click="formData.code = generateWmsCode('C')">生成</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="分类名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入分类名称" />
</el-form-item>
@ -53,6 +59,7 @@ import { defaultProps, handleTree } from '@/utils/tree'
import { CommonStatusEnum } from '@/utils/constants'
import { FormRules } from 'element-plus'
import { ItemCategoryApi, ItemCategoryVO } from '@/api/wms/md/item/category'
import { generateWmsCode } from '@/views/wms/utils/constants'
/** WMS 商品分类表单 */
defineOptions({ name: 'WmsItemCategoryForm' })
@ -67,12 +74,14 @@ const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref<ItemCategoryVO>({
id: undefined,
parentId: undefined,
code: undefined,
name: undefined,
sort: 0,
status: CommonStatusEnum.ENABLE
})
const formRules = reactive<FormRules>({
parentId: [{ required: true, message: '上级分类不能为空', trigger: 'blur' }],
code: [{ required: true, message: '分类编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
@ -140,6 +149,7 @@ const resetForm = (parentId?: number) => {
formData.value = {
id: undefined,
parentId,
code: undefined,
name: undefined,
sort: 0,
status: CommonStatusEnum.ENABLE

View File

@ -9,6 +9,15 @@
class="-mb-15px"
label-width="68px"
>
<el-form-item label="分类编号" prop="code">
<el-input
v-model="queryParams.code"
class="!w-240px"
clearable
placeholder="请输入分类编号"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="分类名称" prop="name">
<el-input
v-model="queryParams.name"
@ -71,6 +80,7 @@
row-key="id"
>
<el-table-column label="分类名称" prop="name" />
<el-table-column align="center" label="分类编号" prop="code" width="160" />
<el-table-column align="center" label="排序" prop="sort" width="120" />
<el-table-column align="center" label="状态" prop="status" width="120">
<template #default="scope">
@ -137,6 +147,7 @@ const list = ref<ItemCategoryVO[]>([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 100,
code: undefined,
name: undefined,
status: undefined
})

View File

@ -162,6 +162,9 @@ const selectedList = ref<ItemSkuVO[]>([]) // 已选择 SKU 列表
const selectedMap = ref<Map<number, ItemSkuVO>>(new Map()) // SKU
const preSelectedIds = ref<number[]>([]) // SKU
const disabledSelectedIds = ref<Set<number>>(new Set()) // 使 SKU
const multiple = ref(true) //
const preselectDisabled = ref(true) // SKU
const syncingSingleSelection = ref(false) //
const tableRef = ref<InstanceType<typeof ElTable>>() // Ref
const queryFormRef = ref() //
const getDefaultQueryParams = () => ({
@ -179,8 +182,13 @@ const emit = defineEmits<{
}>()
/** 打开弹窗 */
const open = async (selectedIds?: number[]) => {
const open = async (
selectedIds?: number[],
options?: { multiple?: boolean; preselectDisabled?: boolean }
) => {
dialogVisible.value = true
multiple.value = options?.multiple ?? true
preselectDisabled.value = options?.preselectDisabled ?? true
Object.assign(queryParams, getDefaultQueryParams())
selectedList.value = []
selectedMap.value = new Map()
@ -219,7 +227,7 @@ const loadSkuList = async () => {
/** 初始化已选 SKU */
const initSelectedList = () => {
if (preSelectedIds.value.length === 0) {
if (!preselectDisabled.value || preSelectedIds.value.length === 0) {
return
}
allList.value.forEach((sku) => {
@ -286,7 +294,34 @@ const isRowSelectable = (row: ItemSkuVO) => {
}
/** 选择变化 */
const handleSelectionChange = (rows: ItemSkuVO[]) => {
const handleSelectionChange = async (rows: ItemSkuVO[]) => {
if (syncingSingleSelection.value) {
return
}
if (!multiple.value) {
let row: ItemSkuVO | undefined
for (let i = rows.length - 1; i >= 0; i--) {
const item = rows[i]
if (item.id && !disabledSelectedIds.value.has(item.id)) {
row = item
break
}
}
selectedMap.value = new Map()
if (row?.id) {
selectedMap.value.set(row.id, row)
}
selectedList.value = Array.from(selectedMap.value.values())
syncingSingleSelection.value = true
await nextTick()
tableRef.value?.clearSelection()
if (row) {
tableRef.value?.toggleRowSelection(row, true)
}
await nextTick()
syncingSingleSelection.value = false
return
}
const currentPageIds = list.value.map((row) => row.id).filter((id): id is number => !!id)
currentPageIds.forEach((id) => {
if (!disabledSelectedIds.value.has(id)) {
@ -306,6 +341,11 @@ const handleRowDblClick = (row: ItemSkuVO) => {
if (row.id && disabledSelectedIds.value.has(row.id)) {
return
}
if (!multiple.value) {
emit('change', [row])
dialogVisible.value = false
return
}
tableRef.value?.toggleRowSelection(row)
}

View File

@ -11,7 +11,11 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="往来企业编号" prop="code">
<el-input v-model="formData.code" maxlength="20" placeholder="请输入往来企业编号" />
<el-input v-model="formData.code" maxlength="20" placeholder="请输入往来企业编号">
<template #append>
<el-button @click="formData.code = generateWmsCode('M')">生成</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@ -88,6 +92,7 @@
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { MerchantApi, MerchantVO } from '@/api/wms/md/merchant'
import { generateWmsCode } from '@/views/wms/utils/constants'
/** WMS 往来企业表单 */
defineOptions({ name: 'WmsMerchantForm' })

View File

@ -12,7 +12,11 @@
<el-input v-model="formData.name" maxlength="50" placeholder="请输入仓库名称" />
</el-form-item>
<el-form-item label="仓库编号" prop="code">
<el-input v-model="formData.code" maxlength="20" placeholder="请输入仓库编号" />
<el-input v-model="formData.code" maxlength="20" placeholder="请输入仓库编号">
<template #append>
<el-button @click="formData.code = generateWmsCode('W')">生成</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number
@ -40,6 +44,7 @@
<script lang="ts" setup>
import { WarehouseApi, WarehouseVO } from '@/api/wms/md/warehouse'
import { generateWmsCode } from '@/views/wms/utils/constants'
/** WMS 仓库表单 */
defineOptions({ name: 'WmsWarehouseForm' })

View File

@ -29,3 +29,24 @@ export const CustomerMerchantTypeList = [
MerchantTypeEnum.CUSTOMER,
MerchantTypeEnum.CUSTOMER_SUPPLIER
]
/**
* WMS /
*
* @param prefix
* - `I`
* - `S` SKU
* - `W`
* - `M`
* - / SKU
* @returns + 8
*
*
*/
export const generateWmsCode = (prefix: string = ''): string => {
let result = ''
for (let i = 0; i < 8; i++) {
result += Math.floor(Math.random() * 10).toString()
}
return prefix + result
}