Commit e1734774 by wuqian

商品注册--余生成入库单

parent 07c79315
...@@ -51,12 +51,12 @@ declare module 'vue' { ...@@ -51,12 +51,12 @@ declare module 'vue' {
ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable'] ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTableV2: typeof import('element-plus/es')['ElTableV2']
ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs'] ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag'] ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline'] ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree'] ElTree: typeof import('element-plus/es')['ElTree']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
......
...@@ -88,3 +88,12 @@ export function getByIdApi(id: number) { ...@@ -88,3 +88,12 @@ export function getByIdApi(id: number) {
params: { id }, params: { id },
}) })
} }
// 注册不通过=删除商品
export function deleteProductApi(data?: {
ids: string
remark?: string | null
}) {
return axios.get<never, BaseRespData<never>>('custom/product/info/delete', {
params: { ...data },
})
}
...@@ -306,5 +306,5 @@ export interface InterReceiptItem { ...@@ -306,5 +306,5 @@ export interface InterReceiptItem {
remark: string remark: string
factoryCode: string factoryCode: string
factoryId: number | null factoryId: number | null
productList: unknown[] productList: ProductSku[]
} }
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
></CustomizeTable> ></CustomizeTable>
</div> </div>
</el-form> </el-form>
<template v-if="!['look'].includes(modeTitle)" #footer> <template v-if="!['preview'].includes(modeTitle)" #footer>
<span class="form-footer"> <span class="form-footer">
<el-button @click="visible = false">取消</el-button> <el-button @click="visible = false">取消</el-button>
<el-button v-if="isAddOrEdit" type="primary" @click="submitProduct" <el-button v-if="isAddOrEdit" type="primary" @click="submitProduct"
...@@ -310,6 +310,7 @@ import { ...@@ -310,6 +310,7 @@ import {
createProductApi, createProductApi,
updateProductApi, updateProductApi,
updateStatusApi, updateStatusApi,
deleteProductApi,
} from '@/api/product' } from '@/api/product'
import CustomizeTable from '@/components/VxeTable.tsx' import CustomizeTable from '@/components/VxeTable.tsx'
const tableRef = ref<InstanceType<typeof CustomizeTable> | null>(null) const tableRef = ref<InstanceType<typeof CustomizeTable> | null>(null)
...@@ -324,6 +325,7 @@ import { ...@@ -324,6 +325,7 @@ import {
ProductSku, ProductSku,
CurrencyType, CurrencyType,
InterProductType, InterProductType,
TableRowData,
} from '@/types/api/product' } from '@/types/api/product'
import { IAllList } from '@/types/api/podUsOrder' import { IAllList } from '@/types/api/podUsOrder'
const visible = defineModel<boolean>('visible', { default: false }) const visible = defineModel<boolean>('visible', { default: false })
...@@ -449,7 +451,7 @@ const formRules = reactive({ ...@@ -449,7 +451,7 @@ const formRules = reactive({
const titleMap = { const titleMap = {
add: '新增', add: '新增',
edit: '编辑', edit: '编辑',
look: '查看详情', preview: '查看详情',
success: '注册完成', success: '注册完成',
confirm: '供应链确定', confirm: '供应链确定',
} as const } as const
...@@ -457,7 +459,7 @@ type ModeType = keyof typeof titleMap ...@@ -457,7 +459,7 @@ type ModeType = keyof typeof titleMap
const modeTitle = ref<ModeType>('add') const modeTitle = ref<ModeType>('add')
const isAddOrEdit = computed(() => ['add', 'edit'].includes(modeTitle.value)) const isAddOrEdit = computed(() => ['add', 'edit'].includes(modeTitle.value))
const isLookOrConfirm = computed(() => const isLookOrConfirm = computed(() =>
['look', 'confirm'].includes(modeTitle.value), ['preview', 'confirm'].includes(modeTitle.value),
) )
import ImageView from '@/components/ImageView.vue' import ImageView from '@/components/ImageView.vue'
const popupTitle = computed(() => titleMap[modeTitle.value as ModeType]) const popupTitle = computed(() => titleMap[modeTitle.value as ModeType])
...@@ -628,9 +630,9 @@ const tableConfig = computed<TableColumn[]>(() => { ...@@ -628,9 +630,9 @@ const tableConfig = computed<TableColumn[]>(() => {
label: 'SKU图片', label: 'SKU图片',
attrs: { align: 'center', width: 80 }, attrs: { align: 'center', width: 80 },
render: { render: {
default: ({ row }: { row: ProductSku }) => { default: ({ row }: { row: TableRowData }) => {
return h(ImageView, { return h(ImageView, {
src: row.image, src: row.image as string,
alt: 'SKU图片', alt: 'SKU图片',
}) })
}, },
...@@ -653,7 +655,7 @@ const tableConfig = computed<TableColumn[]>(() => { ...@@ -653,7 +655,7 @@ const tableConfig = computed<TableColumn[]>(() => {
attrs: { align: 'center', width: 250 }, attrs: { align: 'center', width: 250 },
render: { render: {
header: () => [ header: () => [
'对外报价 ', h('span', '对外报价 '),
h( h(
ElSelect, ElSelect,
{ {
...@@ -838,13 +840,12 @@ const optionSelection = (row: SkuPropertyValue) => { ...@@ -838,13 +840,12 @@ const optionSelection = (row: SkuPropertyValue) => {
if (!arr.length) return if (!arr.length) return
// 清除之前的勾选 // 清除之前的勾选
tableRef.value?.clearCheckbox() tableRef.value?.clearCheckbox()
// arr是选中的表格行,此时表格高亮并滚动到arr的第一行,表格也勾选了
tableSelection.value = arr tableSelection.value = arr
// 滚动到第一行并高亮 // 滚动到第一行并高亮
tableRef.value?.scrollToRow(arr[0]) tableRef.value?.scrollToRow(arr[0] as unknown as TableRowData)
// 勾选所有匹配行 // 勾选所有匹配行
arr.forEach((item) => { arr.forEach((item) => {
tableRef.value?.setCheckboxRow(item, true) tableRef.value?.setCheckboxRow(item as unknown as TableRowData, true)
}) })
} }
const optionDelete = (i: number, code: string) => { const optionDelete = (i: number, code: string) => {
...@@ -953,9 +954,9 @@ const submitProduct = async () => { ...@@ -953,9 +954,9 @@ const submitProduct = async () => {
const shouldSubmit = checkDataChange(customChanges) const shouldSubmit = checkDataChange(customChanges)
if (shouldSubmit) { if (shouldSubmit) {
res = await updateProductApi({ res = await updateProductApi({
...customChanges!, // 非空断言(或 ?? {}) ...customChanges!,
id: editForm.id, // 覆盖/补充 id id: editForm.id,
}) } as ProductDetail)
} else { } else {
return ElMessage.warning('未检测到数据变更,无需提交') return ElMessage.warning('未检测到数据变更,无需提交')
} }
...@@ -971,12 +972,33 @@ const submitProduct = async () => { ...@@ -971,12 +972,33 @@ const submitProduct = async () => {
ElMessage.error(res.message) ElMessage.error(res.message)
} }
} }
// 公共更新状态方法 const updateStatus = async (params: {
const updateStatus = async (remark: string | null) => { status?: string
remark?: string | null
}) => {
try { try {
const res = await updateStatusApi({ const res = await updateStatusApi({
ids: String(editForm.id), // 确保字符串类型 ids: String(editForm.id),
status: '-10', // 根据业务确定状态码,或作为参数传入 remark: null,
...params,
})
if (res.code === 200) {
visible.value = false
emits('success')
ElMessage.success(res.message)
} else {
ElMessage.error(res.message)
}
} catch (error) {
console.error(error)
ElMessage.error('操作失败,请稍后重试')
}
}
// 通用删除/驳回
const doReject = async (remark: string) => {
try {
const res = await deleteProductApi({
ids: String(editForm.id),
remark, remark,
}) })
if (res.code === 200) { if (res.code === 200) {
...@@ -991,13 +1013,11 @@ const updateStatus = async (remark: string | null) => { ...@@ -991,13 +1013,11 @@ const updateStatus = async (remark: string | null) => {
ElMessage.error('操作失败,请稍后重试') ElMessage.error('操作失败,请稍后重试')
} }
} }
// 通过(无需原因) // 通过(无需原因)
const passBtn = async () => { const passBtn = () => updateStatus({ status: '-10' })
await updateStatus(null)
}
// 驳回(需要输入原因) // 驳回(需要输入原因)
const failBtn = async () => { const failBtn = async () => {
let remark: string
try { try {
const { value } = await ElMessageBox.prompt('', '提示', { const { value } = await ElMessageBox.prompt('', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
...@@ -1006,12 +1026,13 @@ const failBtn = async () => { ...@@ -1006,12 +1026,13 @@ const failBtn = async () => {
inputPattern: /.+/, inputPattern: /.+/,
inputErrorMessage: '请输入驳回原因', inputErrorMessage: '请输入驳回原因',
}) })
await updateStatus(value) remark = value
} catch { } catch {
// 用户取消输入,不执行任何操作 return // 用户取消,静默退出
} }
await doReject(remark)
} }
/** 构建 skuProperties(基于当前选中的属性值) */ // 构建 skuProperties(基于当前选中的属性值
function buildSkuProperties() { function buildSkuProperties() {
const result: SkuProperty[] = [] const result: SkuProperty[] = []
for (const iterator of tableSkuArr.value) { for (const iterator of tableSkuArr.value) {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<ElSelect <ElSelect
v-model="editForm.warehouseId" v-model="editForm.warehouseId"
clearable clearable
:disabled="formId" disabled
placeholder="请选择仓库" placeholder="请选择仓库"
style="width: 160px" style="width: 160px"
@change="handleWarehouseChange(editForm.warehouseId)" @change="handleWarehouseChange(editForm.warehouseId)"
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
import { defineModel, defineEmits, defineProps, defineExpose } from 'vue' import { defineModel, defineEmits, defineProps, defineExpose } from 'vue'
const visible = defineModel<boolean>('visible', { default: false }) const visible = defineModel<boolean>('visible', { default: false })
const emits = defineEmits(['success']) const emits = defineEmits(['success'])
import { InterReceiptItem, ProductSku } from '@/types/api/product' import { InterReceiptItem, ProductSku, TableRowData } from '@/types/api/product'
import { warehouseInfo } from '@/api/warehouse' import { warehouseInfo } from '@/api/warehouse'
const props = defineProps({ const props = defineProps({
warehouseList: { warehouseList: {
...@@ -84,6 +84,9 @@ const props = defineProps({ ...@@ -84,6 +84,9 @@ const props = defineProps({
required: true, required: true,
}, },
}) })
const rules = {
warehouseId: [{ required: true, message: '请选择仓库', trigger: 'change' }],
}
const createDefaultForm = ( const createDefaultForm = (
overrides?: Partial<InterReceiptItem>, overrides?: Partial<InterReceiptItem>,
): InterReceiptItem => ({ ): InterReceiptItem => ({
...@@ -101,12 +104,11 @@ const submitProduct = () => { ...@@ -101,12 +104,11 @@ const submitProduct = () => {
visible.value = false visible.value = false
emits('success') emits('success')
} }
const open = (data: ProductSku) => { const open = (data: ProductSku[]) => {
visible.value = true visible.value = true
editForm.productList = data editForm.productList = data
} }
import CustomizeTable from '@/components/VxeTable.tsx' import CustomizeTable from '@/components/VxeTable.tsx'
import type { VxeTablePropTypes } from 'vxe-table'
const tableRef = ref<InstanceType<typeof CustomizeTable> | null>(null) const tableRef = ref<InstanceType<typeof CustomizeTable> | null>(null)
import { TableColumn } from '@/components/VxeTable' import { TableColumn } from '@/components/VxeTable'
import ImageView from '@/components/ImageView.vue' import ImageView from '@/components/ImageView.vue'
...@@ -117,9 +119,9 @@ const tableConfig = computed<TableColumn[]>(() => { ...@@ -117,9 +119,9 @@ const tableConfig = computed<TableColumn[]>(() => {
label: 'SKU图片', label: 'SKU图片',
attrs: { align: 'center', width: 80 }, attrs: { align: 'center', width: 80 },
render: { render: {
default: ({ row }: { row: ProductSku }) => { default: ({ row }: { row: TableRowData }) => {
return h(ImageView, { return h(ImageView, {
src: row.image, src: row.image as string,
alt: 'SKU图片', alt: 'SKU图片',
}) })
}, },
...@@ -229,8 +231,8 @@ const handleWarehouseChange = (val: number | string | undefined) => { ...@@ -229,8 +231,8 @@ const handleWarehouseChange = (val: number | string | undefined) => {
) )
editForm.warehouseName = found ? found.name : '' editForm.warehouseName = found ? found.name : ''
} }
const receiptTableSelection = ref([]) const receiptTableSelection = ref<ProductSku[]>([])
const productSelectionChange = (v) => { const productSelectionChange = (v: ProductSku[]) => {
receiptTableSelection.value = v receiptTableSelection.value = v
} }
defineExpose({ defineExpose({
......
...@@ -154,9 +154,12 @@ ...@@ -154,9 +154,12 @@
取消注册 取消注册
</ElButton> </ElButton>
</ElFormItem> </ElFormItem>
<!-- v-if="['10,20,30,1'].includes(nodeCode)" -->
<ElFormItem> <ElFormItem>
<ElButton type="success" @click="generateWarehouseReceiptBtn"> <ElButton
v-if="['10,20,30,1'].includes(nodeCode)"
type="success"
@click="generateWarehouseReceiptBtn"
>
生成入库单 生成入库单
</ElButton> </ElButton>
</ElFormItem> </ElFormItem>
...@@ -170,7 +173,6 @@ ...@@ -170,7 +173,6 @@
:key="cardItem.id" :key="cardItem.id"
class="card-list-item" class="card-list-item"
@click="cardClick(cardItem)" @click="cardClick(cardItem)"
@mouseleave="handleChangeImages(null, cardItem)"
> >
<CommonCard <CommonCard
:card-item="cardItem" :card-item="cardItem"
...@@ -196,7 +198,7 @@ ...@@ -196,7 +198,7 @@
height="28" height="28"
src="@/assets/images/preview.png" src="@/assets/images/preview.png"
alt="" alt=""
@click="obtainProductInfoBtn(cardItem.id, 'look')" @click="obtainProductInfoBtn(cardItem.id, 'preview')"
/> />
<img <img
v-if="['-20', '-10'].includes(nodeCode)" v-if="['-20', '-10'].includes(nodeCode)"
...@@ -213,7 +215,7 @@ ...@@ -213,7 +215,7 @@
title="供应链确认" title="供应链确认"
width="26" width="26"
height="26" height="26"
src="@/assets/images/registration.png" src="@/assets/images/confirm.png"
alt="" alt=""
@click="obtainProductInfoBtn(cardItem.id, 'confirm')" @click="obtainProductInfoBtn(cardItem.id, 'confirm')"
/> />
...@@ -229,7 +231,6 @@ ...@@ -229,7 +231,6 @@
:key="index" :key="index"
:title="item" :title="item"
class="item-image" class="item-image"
@mousemove="handleChangeImages(item, cardItem)"
> >
<img <img
:src="item" :src="item"
...@@ -306,17 +307,13 @@ ...@@ -306,17 +307,13 @@
<RightClickMenu <RightClickMenu
ref="rightMenuRef" ref="rightMenuRef"
:show-copy-count="false" :show-copy-count="false"
:show-copy-shop-number="false"
:show-copy-sub-shop-number="false" :show-copy-sub-shop-number="false"
@on-change="rightChange" @on-change="rightChange"
> >
<!-- <template #default> <template #default>
<div class="menu-item" @click="rightChange('order-number')"> <div class="menu-item" @click="rightChange('sku')">复制SKU</div>
复制订单号 </template>
</div>
<div class="menu-item" @click="rightChange('factorySubOrderNumber')">
复制生产单号
</div>
</template> -->
</RightClickMenu> </RightClickMenu>
<el-dialog v-model="dialogVisible" width="35%"> <el-dialog v-model="dialogVisible" width="35%">
<img :src="dialogImageUrl" alt="商品预览图片" /> <img :src="dialogImageUrl" alt="商品预览图片" />
...@@ -347,6 +344,7 @@ import { ...@@ -347,6 +344,7 @@ import {
CurrencyType, CurrencyType,
ProcessTypeData, ProcessTypeData,
InterProductType, InterProductType,
ProductSku,
} from '@/types/api/product' } from '@/types/api/product'
import { import {
clearNonEmptyChildren, clearNonEmptyChildren,
...@@ -434,11 +432,6 @@ const isSelectStatused = (data: InterCardItem) => { ...@@ -434,11 +432,6 @@ const isSelectStatused = (data: InterCardItem) => {
) )
return index !== -1 return index !== -1
} }
const currentImage = ref('')
const handleChangeImages = (item: string | null, cardItem: InterCardItem) => {
currentImage.value = cardItem?.img_url || ''
}
const dialogVisible = ref(false) const dialogVisible = ref(false)
const dialogImageUrl = ref('') const dialogImageUrl = ref('')
const handlePictureCardPreview = (fileUrl: string) => { const handlePictureCardPreview = (fileUrl: string) => {
...@@ -455,7 +448,19 @@ const rightClick = (e: MouseEvent) => { ...@@ -455,7 +448,19 @@ const rightClick = (e: MouseEvent) => {
}) })
} }
const rightChange = async (code: string) => { const rightChange = async (code: string) => {
console.log('code', code) if (code === 'select-all') {
cardSelection.value = JSON.parse(JSON.stringify(tableData.value))
} else if (code === 'cancel-select') {
cardSelection.value = []
} else if (code === 'sku') {
const str = (tableData.value as InterCardItem[])
.map((item) => item?.sku)
.filter(Boolean)
.join(',')
if (!str) return ElMessage.warning('当前数据没有SKU')
navigator.clipboard.writeText(str)
ElMessage.success('复制成功')
}
} }
import { useOptions } from '@/utils/product' import { useOptions } from '@/utils/product'
const { getOptions } = useOptions() const { getOptions } = useOptions()
...@@ -486,14 +491,14 @@ const currencyList = ref<CurrencyType[]>([]) ...@@ -486,14 +491,14 @@ const currencyList = ref<CurrencyType[]>([])
onMounted(async () => { onMounted(async () => {
loadTreeData() loadTreeData()
const result = await getOptions(['category', 'craft', 'currency']) const result = await getOptions(['category', 'craft', 'currency'])
categoryTree.value = result.category categoryTree.value = result.category as unknown as InterCategoryNode[]
const data: InterCraftItem[] = result.craft const data: InterCraftItem[] = result.craft as unknown as InterCraftItem[]
craftList.value = data.map((item) => ({ craftList.value = data.map((item) => ({
id: item.id, id: item.id,
name: item.craft_name, name: item.craft_name,
warehouseName: processTypeMap[item.craft_type] ?? '其他', warehouseName: processTypeMap[item.craft_type] ?? '其他',
})) as IAllList[] })) as IAllList[]
currencyList.value = result.currency currencyList.value = result.currency as unknown as CurrencyType[]
}) })
const suspendTabs = ref<IntercategoryTree[]>([]) const suspendTabs = ref<IntercategoryTree[]>([])
const activeSuspendTab = ref<string>('33') const activeSuspendTab = ref<string>('33')
...@@ -528,7 +533,10 @@ const addProductInfo = () => { ...@@ -528,7 +533,10 @@ const addProductInfo = () => {
createVisible.value = true createVisible.value = true
shopRef.value?.open('add') shopRef.value?.open('add')
} }
const obtainProductInfoBtn = async (id: number, type: string) => { const obtainProductInfoBtn = async (
id: number,
type: 'add' | 'edit' | 'preview' | 'confirm' | 'success',
) => {
const loading = ElLoading.service({ const loading = ElLoading.service({
lock: true, lock: true,
text: '加载中...', text: '加载中...',
...@@ -609,7 +617,8 @@ const warehouseList = ref<warehouseInfo[]>([]) ...@@ -609,7 +617,8 @@ const warehouseList = ref<warehouseInfo[]>([])
const generateWarehouseReceiptBtn = async () => { const generateWarehouseReceiptBtn = async () => {
try { try {
const warehouseResult = await getOptions(['warehouse']) const warehouseResult = await getOptions(['warehouse'])
warehouseList.value = warehouseResult.warehouse warehouseList.value =
warehouseResult.warehouse as unknown as warehouseInfo[]
const loading = ElLoading.service({ const loading = ElLoading.service({
lock: true, lock: true,
text: '加载中...', text: '加载中...',
...@@ -620,7 +629,9 @@ const generateWarehouseReceiptBtn = async () => { ...@@ -620,7 +629,9 @@ const generateWarehouseReceiptBtn = async () => {
const id = cardSelection.value[0].id const id = cardSelection.value[0].id
const res = await getByIdApi(id) const res = await getByIdApi(id)
if (res.code === 200) { if (res.code === 200) {
const productList = res.data?.productList || [] const productList =
(res.data as unknown as { productList: ProductSku[] })?.productList ||
[]
receiptVisible.value = true receiptVisible.value = true
receiptRef.value?.open?.(productList) receiptRef.value?.open?.(productList)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment