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
592e50b9
Commit
592e50b9
authored
Jun 27, 2025
by
wuqian
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wq' into dev
parents
b9784686
1570ee52
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
383 additions
and
12 deletions
+383
-12
src/api/auth.ts
+39
-2
src/components/NavMenu.vue
+29
-2
src/router/index.ts
+14
-5
src/router/menu.ts
+5
-1
src/types/api/user.ts
+10
-0
src/views/system/CustomersPage.vue
+253
-0
src/views/warehouse/position.vue
+33
-2
No files found.
src/api/auth.ts
View file @
592e50b9
import
{
BasePaginationData
,
BaseRespData
}
from
'@/types/api'
import
axios
from
'./axios'
import
{
LoginReq
,
LoginResp
}
from
'@/types/api/auth'
import
{
UserEditForm
,
userData
,
userSearchForm
}
from
'@/types/api/user'
import
{
UserEditForm
,
userData
,
customSearchForm
,
userSearchForm
,
customData
,
}
from
'@/types/api/user'
import
{
NameSpaceList
}
from
'@/types/api/deliveryNote'
export
function
loginApi
(
data
:
LoginReq
)
{
...
...
@@ -50,7 +56,38 @@ export function deleteUserApi(ids: string) {
params
:
{
ids
:
ids
},
})
}
export
function
getRelList
(
data
:
customSearchForm
,
currentPage
:
number
,
pageSize
:
number
,
)
{
return
axios
.
post
<
never
,
BasePaginationData
<
customData
>>
(
'/dbDiyUser/getRelList'
,
{
...
data
,
currentPage
,
pageSize
,
},
)
}
export
function
getBySkuApi
(
sku
:
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
customSearchForm
>>
(
'/dbDiyUser/getBySku'
,
{
params
:
{
sku
:
sku
},
},
)
}
export
function
addRelApi
(
userId
?:
number
|
string
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/dbDiyUser/addRel'
,
{
params
:
{
userId
:
userId
},
})
}
export
function
removeRelApi
(
relId
?:
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
never
>>
(
'/dbDiyUser/removeRel'
,
{
params
:
{
relId
:
relId
},
})
}
export
function
getDetailsByIdApi
(
id
:
number
)
{
return
axios
.
get
<
never
,
BaseRespData
<
UserEditForm
>>
(
'/factory/factoryUser/get'
,
...
...
src/components/NavMenu.vue
View file @
592e50b9
...
...
@@ -10,7 +10,7 @@
mode=
"horizontal"
background-color=
"#001529"
text-color=
"#fff"
style=
"border-bottom: none
;
"
style=
"border-bottom: none"
:default-active=
"defaultActive"
router
>
...
...
@@ -178,7 +178,12 @@ import userUserStore from '@/store/user'
import
type
{
FormRules
}
from
'element-plus'
import
{
useValue
}
from
'@/utils/hooks/useValue'
import
{
changePasswordApi
}
from
'@/api/auth'
interface
MenuItem
{
index
:
string
id
:
number
label
:
string
children
?:
MenuItem
[]
}
interface
PasswordForm
{
oldPwd
:
string
newPwd
:
string
...
...
@@ -409,6 +414,28 @@ watch(activeTab, (newTab) => {
watch
(
tabs
,
checkScrollArrows
)
// 初始化时确保活动标签可见
onMounted
(()
=>
{
let
showCustomerManagement
=
false
const
userJson
=
localStorage
.
getItem
(
'user'
)
if
(
userJson
)
{
try
{
const
user
=
JSON
.
parse
(
userJson
)
if
(
user
&&
user
.
factory
&&
user
.
factory
.
type
===
2
)
{
showCustomerManagement
=
true
}
}
catch
(
e
)
{
// ignore
}
}
if
(
!
showCustomerManagement
)
{
const
systemSettingsMenu
=
menuList
.
find
(
(
item
:
MenuItem
)
=>
item
.
label
===
'系统设置'
,
)
if
(
systemSettingsMenu
&&
systemSettingsMenu
.
children
)
{
systemSettingsMenu
.
children
=
systemSettingsMenu
.
children
.
filter
(
(
child
:
MenuItem
)
=>
child
.
index
!==
'/system/customers'
,
)
}
}
// 初始检查
checkScrollArrows
()
...
...
src/router/index.ts
View file @
592e50b9
...
...
@@ -29,6 +29,7 @@ import WarehousePosition from '@/views/warehouse/position.vue'
import
receiptDoc
from
'@/views/warehouse/receiptDoc.vue'
import
issueDoc
from
'@/views/warehouse/issueDoc.vue'
import
ExternalAuthorisationPage
from
'@/views/system/externalAuthorisationPage.vue'
import
CustomersPage
from
'@/views/system/CustomersPage.vue'
const
router
=
createRouter
({
history
:
createWebHistory
(),
routes
:
[
...
...
@@ -94,11 +95,18 @@ const router = createRouter({
component
:
UserPage
,
},
{
path
:
'/system/external-authorisation'
,
path
:
'/system/external-authorisation'
,
meta
:
{
title
:
'外部授权'
title
:
'外部授权'
,
},
component
:
ExternalAuthorisationPage
component
:
ExternalAuthorisationPage
,
},
{
path
:
'/system/customers'
,
meta
:
{
title
:
'客户管理'
,
},
component
:
CustomersPage
,
},
{
path
:
'/system/delivery-note'
,
...
...
@@ -134,7 +142,8 @@ const router = createRouter({
title
:
'物流方式'
,
},
component
:
()
=>
import
(
'@/views/logistics/logisticsMethod.vue'
),
},{
},
{
path
:
'/logistics/logisticsCompany'
,
meta
:
{
title
:
'物流公司'
,
...
...
@@ -176,7 +185,7 @@ const router = createRouter({
},
component
:
()
=>
import
(
'@/views/logistics/logisticsCalculate.vue'
),
},
{
{
path
:
'/logistics/sortingConfiguration'
,
meta
:
{
title
:
'分拣配置'
,
...
...
src/router/menu.ts
View file @
592e50b9
...
...
@@ -175,6 +175,11 @@ const menu: MenuItem[] = [
id
:
5
,
label
:
'外部授权'
,
},
{
index
:
'/system/customers'
,
id
:
6
,
label
:
'客户管理'
,
},
],
},
...
...
@@ -191,5 +196,4 @@ const menu: MenuItem[] = [
// ]
// },
]
export
default
menu
src/types/api/user.ts
View file @
592e50b9
...
...
@@ -20,3 +20,13 @@ export interface UserEditForm {
account
:
string
status
:
string
|
number
}
export
interface
customSearchForm
{
sku
?:
string
userMark
?:
string
id
?:
number
|
string
}
export
interface
customData
{
relId
?:
number
sku
?:
string
userMark
?:
string
}
src/views/system/CustomersPage.vue
0 → 100644
View file @
592e50b9
<
template
>
<div
class=
"user-page flex-column card h-100 overflow-hidden"
>
<div
class=
"header-filter-form"
>
<ElForm
:model=
"searchForm"
inline
>
<ElFormItem
label=
"客户识别码"
prop=
"sku"
>
<ElInput
v-model=
"searchForm.sku"
placeholder=
"请输入客户识别码"
clearable
style=
"width: 200px"
/>
</ElFormItem>
<ElFormItem
label=
"客户标识"
prop=
"userMark"
>
<ElInput
v-model=
"searchForm.userMark"
placeholder=
"请输入客户标识"
clearable
style=
"width: 200px"
/>
</ElFormItem>
<ElFormItem>
<ElButton
type=
"primary"
@
click=
"search"
>
查询
</ElButton>
</ElFormItem>
<ElFormItem>
<ElButton
@
click=
"resetSearchForm"
>
重置
</ElButton>
</ElFormItem>
<ElFormItem>
<ElButton
type=
"success"
@
click=
"addUser"
>
绑定客户
</ElButton>
</ElFormItem>
</ElForm>
</div>
<div
class=
"user-content flex-1 flex-column overflow-hidden"
>
<div
class=
"user-list flex-1 overflow-hidden"
>
<ElTable
:data=
"tableData"
default-expand-all
style=
"width: 100%; height: 100%"
>
<ElTableColumn
type=
"index"
header-align=
"center"
align=
"center"
label=
"序号"
width=
"55"
/>
<ElTableColumn
prop=
"sku"
header-align=
"center"
align=
"center"
label=
"客户识别码"
/>
<ElTableColumn
prop=
"userMark"
header-align=
"center"
align=
"center"
label=
"客户标识"
/>
<ElTableColumn
label=
"操作"
width=
"130"
header-align=
"center"
align=
"center"
>
<template
#
default=
"scope"
>
<el-icon
size=
"24"
title=
"解除绑定"
color=
"#f56c6c"
style=
"cursor: pointer; vertical-align: middle"
@
click=
"editUser(scope.row)"
>
<Delete
/>
</el-icon>
</
template
>
</ElTableColumn>
</ElTable>
</div>
<ElPagination
v-model:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:page-sizes=
"[100, 200, 300, 400, 500]"
background
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"total"
style=
"margin: 10px auto 0; text-align: right"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
></ElPagination>
</div>
</div>
<ElDialog
v-model=
"dialogVisible"
:title=
"!relId ? '绑定客户' : '解绑客户'"
width=
"600px"
:close-on-click-modal=
"false"
@
opened=
"onOpenedUserForm"
>
<div
class=
"dialog-form"
>
<ElForm
ref=
"editFormRef"
:model=
"editForm"
:rules=
"rules"
label-width=
"120px"
>
<ElFormItem
label=
"客户识别码:"
prop=
"sku"
>
<ElInput
v-if=
"!relId"
v-model=
"editForm.sku"
placeholder=
"请输入客户识别码"
clearable
>
<
template
#
append
>
<el-button
:icon=
"Search"
@
click=
"getSkuByInfo"
></el-button>
</
template
>
</ElInput>
<span
v-else
style=
"font-weight: bold"
>
{{ editForm.sku }}
</span>
</ElFormItem>
<ElFormItem
label=
"客户标识:"
prop=
"userMark"
>
<span
style=
"font-weight: bold"
>
{{ editForm.userMark }}
</span>
</ElFormItem>
</ElForm>
</div>
<
template
#
footer
>
<div
class=
"dialog-footer"
>
<ElButton
@
click=
"dialogVisible = false"
>
取消
</ElButton>
<ElButton
type=
"primary"
@
click=
"save"
>
确定
</ElButton>
</div>
</
template
>
</ElDialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
getBySkuApi
,
addRelApi
,
removeRelApi
,
getRelList
}
from
'@/api/auth'
import
{
customData
,
customSearchForm
}
from
'@/types/api/user'
import
usePageList
from
'@/utils/hooks/usePageList'
import
{
useValue
}
from
'@/utils/hooks/useValue'
import
{
Delete
,
Search
}
from
'@element-plus/icons-vue'
import
type
{
FormRules
}
from
'element-plus'
import
{
reactive
,
ref
}
from
'vue'
const
[
searchForm
,
resetSearchForm
]
=
useValue
<
customSearchForm
>
({})
const
[
editForm
,
resetEditForm
]
=
useValue
<
customSearchForm
>
({
sku
:
''
,
userMark
:
''
,
id
:
''
,
})
const
{
currentPage
,
pageSize
,
total
,
data
:
tableData
,
refresh
:
search
,
onCurrentPageChange
:
handleCurrentChange
,
onPageSizeChange
:
handleSizeChange
,
}
=
usePageList
({
query
:
(
page
,
pageSize
)
=>
getRelList
(
searchForm
.
value
,
page
,
pageSize
).
then
((
res
)
=>
res
.
data
),
})
const
dialogVisible
=
ref
(
false
)
const
editFormRef
=
ref
()
// const selection = ref
<
customData
[]
>
([])
const
rules
=
reactive
<
FormRules
<
customSearchForm
>>
({
sku
:
[
{
required
:
true
,
message
:
'请输入客户识别码'
,
},
],
})
const
getSkuByInfo
=
async
()
=>
{
if
(
!
editForm
.
value
.
sku
)
{
return
ElMessage
({
message
:
'请输入sku'
,
type
:
'warning'
,
offset
:
window
.
innerHeight
/
2
,
})
}
try
{
const
res
=
await
getBySkuApi
(
editForm
.
value
.
sku
)
if
(
res
.
code
==
200
)
{
editForm
.
value
.
userMark
=
res
.
data
?.
userMark
||
''
editForm
.
value
.
id
=
res
.
data
?.
id
||
''
}
}
catch
(
e
)
{
// showError(e)
}
}
const
relId
=
ref
<
number
|
undefined
>
(
undefined
)
const
addUser
=
()
=>
{
relId
.
value
=
undefined
dialogVisible
.
value
=
true
resetEditForm
()
}
const
editUser
=
async
(
item
:
customData
)
=>
{
relId
.
value
=
item
.
relId
editForm
.
value
.
sku
=
item
.
sku
editForm
.
value
.
userMark
=
item
.
userMark
dialogVisible
.
value
=
true
}
const
save
=
async
()
=>
{
try
{
await
editFormRef
.
value
.
validate
()
}
catch
{
return
}
try
{
if
(
!
relId
.
value
)
{
if
(
!
editForm
.
value
.
id
)
{
return
ElMessage
({
message
:
'请根据SKU查询对应的客户标识'
,
type
:
'warning'
,
offset
:
window
.
innerHeight
/
2
,
})
}
await
addRelApi
(
editForm
.
value
.
id
)
}
else
{
await
removeRelApi
(
relId
.
value
)
}
ElMessage
({
message
:
'保存成功'
,
type
:
'success'
,
offset
:
window
.
innerHeight
/
2
,
})
dialogVisible
.
value
=
false
search
()
}
catch
(
e
)
{
return
}
}
const
onOpenedUserForm
=
async
()
=>
{
editFormRef
.
value
?.
clearValidate
()
}
// const handleSelectionChange = (s: customData[]) => {
// selection.value = s
// }
</
script
>
<
style
lang=
"scss"
scoped
>
.header-filter-form
{
margin-bottom
:
20px
;
:deep(.el-form-item)
{
margin-right
:
14px
;
margin-bottom
:
10px
;
}
}
.user-operate-btn
{
margin-bottom
:
10px
;
}
.dialog-footer
{
text-align
:
center
;
}
</
style
>
src/views/warehouse/position.vue
View file @
592e50b9
...
...
@@ -146,11 +146,16 @@ const handleConfirm = async () => {
ElMessage
.
success
(
'操作成功'
)
await
getData
()
}
const
locationLabelVisible
=
ref
(
false
)
const
locationRadio
=
ref
(
'PT001'
)
async
function
printLocationTag
()
{
if
(
!
selections
.
value
.
length
)
{
return
ElMessage
.
warning
(
'请选择数据'
)
}
locationLabelVisible
.
value
=
true
}
async
function
submitLocationTag
()
{
const
list
=
selections
.
value
.
map
((
item
)
=>
{
return
{
locationName
:
item
.
locationCode
,
...
...
@@ -159,11 +164,11 @@ async function printLocationTag() {
})
const
res
=
await
factoryWarehouseInfoPrint
({
list
,
code
:
'PT001'
,
code
:
locationRadio
.
value
,
})
window
.
open
(
filePath
+
res
.
message
,
'_blank'
)
locationLabelVisible
.
value
=
false
}
const
handleBatchDelete
=
async
(
row
:
positionInfo
|
null
)
=>
{
if
(
!
row
&&
!
selections
.
value
.
length
)
{
return
ElMessage
.
warning
(
'请选择要删除的数据'
)
...
...
@@ -508,6 +513,24 @@ getWarehouse()
</div>
</div>
</ElDialog>
<ElDialog
v-model=
"locationLabelVisible"
title=
"打印库位标签"
width=
"500px"
:close-on-click-modal=
"false"
>
<div
class=
"mb-2 ml-4 location-box"
>
<span
class=
"location-label"
>
打印库位标签格式:
</span>
<el-radio-group
v-model=
"locationRadio"
>
<el-radio
value=
"PT001"
size=
"large"
>
中文
</el-radio>
<el-radio
value=
"PT001_EN"
size=
"large"
>
英文
</el-radio>
</el-radio-group>
</div>
<
template
#
footer
>
<el-button
@
click=
"locationLabelVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"submitLocationTag"
>
确定
</el-button>
</
template
>
</ElDialog>
</template>
<
style
scoped
lang=
"scss"
>
...
...
@@ -516,6 +539,14 @@ getWarehouse()
height
:
100%
;
}
}
.location-box
{
display
:
flex
;
align-items
:
center
;
.location-label
{
color
:
#606266
;
margin
:
0
15px
;
}
}
.import-dialog
{
.import-header
{
display
:
flex
;
...
...
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