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