Toggle navigation
Toggle navigation
This project
Loading...
Sign in
zhouhui.jiang
/
test_cursor
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
zhouhui.jiang
2025-09-29 17:50:05 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
9d5c9aea2825662021d59feb842c02affec3057d
9d5c9aea
1 parent
81c6bb8a
update
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
245 additions
and
17 deletions
backend/src/main/java/com/apple/erp/service/impl/DeliveryMainServiceImpl.java
frontend/components.d.ts
frontend/src/api/dealer.ts
frontend/src/api/dict.ts
frontend/src/views/dealer/index.vue
backend/src/main/java/com/apple/erp/service/impl/DeliveryMainServiceImpl.java
View file @
9d5c9ae
...
...
@@ -2,7 +2,9 @@ package com.apple.erp.service.impl;
import
com.apple.erp.dto.*
;
import
com.apple.erp.entity.DeliveryItem
;
import
com.apple.erp.entity.OrderMain
;
import
com.apple.erp.mapper.DeliveryItemMapper
;
import
com.apple.erp.mapper.OrderMainMapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.toolkit.Wrappers
;
...
...
@@ -36,6 +38,9 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
@Autowired
private
DeliveryItemMapper
deliveryItemMapper
;
@Autowired
private
OrderMainMapper
orderMainMapper
;
private
static
final
DateTimeFormatter
DATE_TIME_FORMATTER
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
@Override
...
...
@@ -107,6 +112,11 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
throw
new
IllegalArgumentException
(
"出库单编号已存在"
);
}
// 验证关联的订单号是否在订单管理中存在
if
(!
isOrderNoExist
(
addReq
.
getOrderNo
()))
{
throw
new
IllegalArgumentException
(
"关联的订单编号不存在"
);
}
DeliveryMain
deliveryMain
=
new
DeliveryMain
();
BeanUtils
.
copyProperties
(
addReq
,
deliveryMain
);
deliveryMain
.
setCreateTime
(
LocalDateTime
.
now
());
...
...
@@ -141,6 +151,11 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
throw
new
IllegalArgumentException
(
"出库单编号已存在"
);
}
// 验证关联的订单号是否在订单管理中存在
if
(!
isOrderNoExist
(
updateReq
.
getOrderNo
()))
{
throw
new
IllegalArgumentException
(
"关联的订单编号不存在"
);
}
DeliveryMain
deliveryMain
=
new
DeliveryMain
();
BeanUtils
.
copyProperties
(
updateReq
,
deliveryMain
);
deliveryMain
.
setUpdateTime
(
LocalDateTime
.
now
());
...
...
@@ -216,6 +231,18 @@ public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, Del
return
baseMapper
.
selectCount
(
queryWrapper
)
>
0
;
}
/**
* 检查订单编号是否在订单管理中存在
* @param orderNo 订单编号
* @return 是否存在
*/
private
boolean
isOrderNoExist
(
String
orderNo
)
{
LambdaQueryWrapper
<
OrderMain
>
queryWrapper
=
Wrappers
.
lambdaQuery
(
OrderMain
.
class
)
.
eq
(
OrderMain:
:
getOrderNo
,
orderNo
)
.
eq
(
OrderMain:
:
getDelFlag
,
"0"
);
return
orderMainMapper
.
selectCount
(
queryWrapper
)
>
0
;
}
private
LocalDateTime
parseDateTime
(
String
dateTimeStr
)
{
if
(!
StringUtils
.
hasText
(
dateTimeStr
))
{
return
null
;
...
...
frontend/components.d.ts
View file @
9d5c9ae
...
...
@@ -9,18 +9,29 @@ declare module 'vue' {
export
interface
GlobalComponents
{
ElButton
:
typeof
import
(
'element-plus/es'
)[
'ElButton'
]
ElDatePicker
:
typeof
import
(
'element-plus/es'
)[
'ElDatePicker'
]
ElDescriptions
:
typeof
import
(
'element-plus/es'
)[
'ElDescriptions'
]
ElDescriptionsItem
:
typeof
import
(
'element-plus/es'
)[
'ElDescriptionsItem'
]
ElDialog
:
typeof
import
(
'element-plus/es'
)[
'ElDialog'
]
ElForm
:
typeof
import
(
'element-plus/es'
)[
'ElForm'
]
ElFormItem
:
typeof
import
(
'element-plus/es'
)[
'ElFormItem'
]
ElIcon
:
typeof
import
(
'element-plus/es'
)[
'ElIcon'
]
ElInput
:
typeof
import
(
'element-plus/es'
)[
'ElInput'
]
ElInputNumber
:
typeof
import
(
'element-plus/es'
)[
'ElInputNumber'
]
ElOption
:
typeof
import
(
'element-plus/es'
)[
'ElOption'
]
ElPagination
:
typeof
import
(
'element-plus/es'
)[
'ElPagination'
]
ElRadio
:
typeof
import
(
'element-plus/es'
)[
'ElRadio'
]
ElRadioGroup
:
typeof
import
(
'element-plus/es'
)[
'ElRadioGroup'
]
ElSelect
:
typeof
import
(
'element-plus/es'
)[
'ElSelect'
]
ElTable
:
typeof
import
(
'element-plus/es'
)[
'ElTable'
]
ElTableColumn
:
typeof
import
(
'element-plus/es'
)[
'ElTableColumn'
]
ElTag
:
typeof
import
(
'element-plus/es'
)[
'ElTag'
]
Header
:
typeof
import
(
'./src/components/layout/Header.vue'
)[
'default'
]
RouterLink
:
typeof
import
(
'vue-router'
)[
'RouterLink'
]
RouterView
:
typeof
import
(
'vue-router'
)[
'RouterView'
]
Sidebar
:
typeof
import
(
'./src/components/layout/Sidebar.vue'
)[
'default'
]
SidebarItem
:
typeof
import
(
'./src/components/layout/SidebarItem.vue'
)[
'default'
]
}
export
interface
ComponentCustomProperties
{
vLoading
:
typeof
import
(
'element-plus/es'
)[
'ElLoadingDirective'
]
}
}
...
...
frontend/src/api/dealer.ts
View file @
9d5c9ae
...
...
@@ -51,6 +51,10 @@ export interface DealerInfo {
cooperationAgreementUrl
:
string
qualificationAuditStatus
:
number
auditOpinion
:
string
totalRebateAmount
?:
number
usedRebateAmount
?:
number
pendingRebateAmount
?:
number
lastRebateUpdateTime
?:
string
createTime
:
string
updateTime
:
string
}
...
...
frontend/src/api/dict.ts
View file @
9d5c9ae
import
request
from
'@/utils/request
'
import
axios
from
'axios
'
/**
* 字典管理API
*/
const
API_BASE_URL
=
import
.
meta
.
env
.
VITE_API_BASE_URL
||
'http://localhost:8083'
// 获取字典项
export
const
getDictItems
=
(
dictType
:
string
)
=>
{
return
request
.
get
(
`/api/dict/
${
dictType
}
`
)
const
api
=
axios
.
create
({
baseURL
:
API_BASE_URL
,
timeout
:
10000
,
headers
:
{
'Content-Type'
:
'application/json'
}
})
api
.
interceptors
.
request
.
use
(
(
config
)
=>
{
const
token
=
localStorage
.
getItem
(
'token'
)
if
(
token
)
{
config
.
headers
.
Authorization
=
`Bearer
${
token
}
`
}
return
config
},
(
error
)
=>
{
return
Promise
.
reject
(
error
)
}
)
api
.
interceptors
.
response
.
use
(
(
response
)
=>
{
return
response
.
data
},
(
error
)
=>
{
console
.
error
(
'API请求错误:'
,
error
)
return
Promise
.
reject
(
error
)
}
)
export
interface
DictType
{
dictTypeId
:
number
dictType
:
string
dictName
:
string
status
:
number
statusText
:
string
remark
?:
string
createBy
?:
string
createTime
:
string
updateBy
?:
string
updateTime
:
string
}
export
interface
DictItem
{
dictItemId
:
number
dictTypeId
:
number
dictType
:
string
dictLabel
:
string
dictValue
:
string
sort
:
number
remark
?:
string
createBy
?:
string
createTime
:
string
updateBy
?:
string
updateTime
:
string
}
export
interface
DictTypeSearchParams
{
dictType
?:
string
dictName
?:
string
status
?:
number
pageNum
?:
number
pageSize
?:
number
}
export
interface
DictItemSearchParams
{
dictTypeId
?:
number
dictLabel
?:
string
dictValue
?:
string
pageNum
?:
number
pageSize
?:
number
}
export
interface
DictTypeAddReq
{
dictType
:
string
dictName
:
string
status
:
number
remark
?:
string
}
export
interface
DictTypeUpdateReq
extends
DictTypeAddReq
{
dictTypeId
:
number
}
export
interface
DictItemAddReq
{
dictTypeId
:
number
dictLabel
:
string
dictValue
:
string
sort
?:
number
remark
?:
string
}
// 获取所有字典项
export
const
getAllDictItems
=
()
=>
{
return
request
.
get
(
'/api/dict/all'
)
export
interface
DictItemUpdateReq
extends
DictItemAddReq
{
dictItemId
:
number
}
// 刷新字典缓存
export
const
refreshDictCache
=
()
=>
{
return
request
.
post
(
'/api/dict/refresh'
)
export
interface
ApiResponse
<
T
=
any
>
{
code
:
number
message
:
string
data
:
T
}
export
interface
PageResponse
<
T
>
{
records
:
T
[]
total
:
number
size
:
number
current
:
number
orders
:
any
[]
optimizeCountSql
:
boolean
searchCount
:
boolean
maxLimit
:
any
countId
:
any
pages
:
number
}
export
const
dictApi
=
{
// 字典类型管理
// 获取字典类型列表
getDictTypes
:
(
params
:
DictTypeSearchParams
):
Promise
<
ApiResponse
<
PageResponse
<
DictType
>>>
=>
{
return
api
.
get
(
'/api/system/dict/type/list'
,
{
params
})
},
// 获取字典类型详情
getDictTypeById
:
(
dictTypeId
:
number
):
Promise
<
ApiResponse
<
DictType
>>
=>
{
return
api
.
get
(
`/api/system/dict/type/
${
dictTypeId
}
`
)
},
// 新增字典类型
createDictType
:
(
dictTypeData
:
DictTypeAddReq
):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
post
(
'/api/system/dict/type'
,
dictTypeData
)
},
// 修改字典类型
updateDictType
:
(
dictTypeData
:
DictTypeUpdateReq
):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
put
(
'/api/system/dict/type'
,
dictTypeData
)
},
// 删除字典类型
deleteDictTypes
:
(
dictTypeIds
:
number
[]):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
delete
(
`/api/system/dict/type/
${
dictTypeIds
.
join
(
','
)}
`
)
},
// 获取字典类型选择框列表
getDictTypeOptions
:
():
Promise
<
ApiResponse
<
DictType
[]
>>
=>
{
return
api
.
get
(
'/api/system/dict/type/optionselect'
)
},
// 刷新字典缓存
refreshDictCache
:
():
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
delete
(
'/api/system/dict/type/refreshCache'
)
},
// 字典项管理
// 获取字典项列表
getDictItems
:
(
params
:
DictItemSearchParams
):
Promise
<
ApiResponse
<
PageResponse
<
DictItem
>>>
=>
{
return
api
.
get
(
'/api/system/dict/item/list'
,
{
params
})
},
// 根据字典类型获取字典项列表
getDictItemsByType
:
(
dictType
:
string
):
Promise
<
ApiResponse
<
DictItem
[]
>>
=>
{
return
api
.
get
(
`/api/system/dict/item/type/
${
dictType
}
`
)
},
// 获取字典项详情
getDictItemById
:
(
dictItemId
:
number
):
Promise
<
ApiResponse
<
DictItem
>>
=>
{
return
api
.
get
(
`/api/system/dict/item/
${
dictItemId
}
`
)
},
// 新增字典项
createDictItem
:
(
dictItemData
:
DictItemAddReq
):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
post
(
'/api/system/dict/item'
,
dictItemData
)
},
// 修改字典项
updateDictItem
:
(
dictItemData
:
DictItemUpdateReq
):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
put
(
'/api/system/dict/item'
,
dictItemData
)
},
// 删除字典项
deleteDictItems
:
(
dictItemIds
:
number
[]):
Promise
<
ApiResponse
<
any
>>
=>
{
return
api
.
delete
(
`/api/system/dict/item/
${
dictItemIds
.
join
(
','
)}
`
)
},
}
\ No newline at end of file
...
...
frontend/src/views/dealer/index.vue
View file @
9d5c9ae
...
...
@@ -84,10 +84,11 @@
<th>统一社会信用代码</th>
<th>经销商等级</th>
<th>所在区域</th>
<th>联系人</th>
<th>联系电话</th>
<th>合作起始日期</th>
<th>合作状态</th>
<th>累计应返金额</th>
<th>累计已返金额</th>
<th>待返利总金额</th>
<th>操作</th>
</tr>
</thead>
...
...
@@ -105,14 +106,15 @@
<td>{{ dealer.creditCode }}</td>
<td>{{ getDealerLevelText(dealer.dealerLevel) }}</td>
<td>{{ dealer.region }}</td>
<td>{{ dealer.contactPerson }}</td>
<td>{{ dealer.contactPhone }}</td>
<td>{{ dealer.cooperateStartDate }}</td>
<td>
<span :class="getCooperateStatusClass(dealer.cooperateStatus)">
{{ getCooperateStatusText(dealer.cooperateStatus) }}
</span>
</td>
<td class="amount-cell">{{ formatAmount(dealer.totalRebateAmount) }}</td>
<td class="amount-cell">{{ formatAmount(dealer.usedRebateAmount) }}</td>
<td class="amount-cell">{{ formatAmount(dealer.pendingRebateAmount) }}</td>
<td>
<button @click="handleEdit(dealer)" class="table-btn edit">✏️ 编辑</button>
<button @click="handleDelete(dealer)" class="table-btn delete">🗑️ 删除</button>
...
...
@@ -445,6 +447,14 @@ const getCooperateStatusClass = (status: number) => {
return classMap[status] || ''
}
// 格式化金额显示
const formatAmount = (amount: number | undefined) => {
if (amount === undefined || amount === null) {
return '¥0.00'
}
return `¥${amount.toFixed(2)}`
}
// 获取分页页码数组
const getPageNumbers = () => {
...
...
@@ -1283,4 +1293,12 @@ onMounted(() => {
color: #67c23a;
font-weight: 500;
}
/* 金额单元格样式 */
.amount-cell {
text-align: right;
font-weight: 500;
color: #1890ff;
font-family: 'Courier New', monospace;
}
</style>
\ No newline at end of file
...
...
Please
register
or
login
to post a comment