Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c03775b8
authored
Aug 13, 2026
by
renyizhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
算力资源改造完成
parent
f3883e76
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
682 additions
and
23 deletions
+682
-23
src/api/compute/resourceorder/index.ts
+48
-1
src/views/compute/resourceorder/ResourceOrderDetail.vue
+131
-16
src/views/compute/resourceorder/form/ResourceOrderAdminCancelForm.vue
+124
-0
src/views/compute/resourceorder/form/ResourceOrderDeliverForm.vue
+134
-0
src/views/compute/resourceorder/form/ResourceOrderMarkRefundedForm.vue
+172
-0
src/views/compute/resourceorder/index.vue
+73
-6
No files found.
src/api/compute/resourceorder/index.ts
View file @
c03775b8
...
@@ -6,10 +6,11 @@ export interface ResourceOrder {
...
@@ -6,10 +6,11 @@ export interface ResourceOrder {
id
:
number
;
// 订单ID
id
:
number
;
// 订单ID
userId
?:
number
;
// 下单用户ID
userId
?:
number
;
// 下单用户ID
mobile
?:
string
;
// 下单用户手机号
mobile
?:
string
;
// 下单用户手机号
nickname
?:
string
;
// 下单用户昵称
skuId
?:
number
;
// 算力资源SKU ID
skuId
?:
number
;
// 算力资源SKU ID
spuName
?:
string
;
// 算力资源名称(下单时快照)
spuName
?:
string
;
// 算力资源名称(下单时快照)
orderNo
?:
string
;
// 订单编号
orderNo
?:
string
;
// 订单编号
status
:
number
;
// 订单状态:0=待支付,
1=已支付,2=已取消
status
:
number
;
// 订单状态:0=待支付,
5=待发货,6=已发货,2=已结束,3=已取消,7=待退款,4=已退款
marketPrice
:
number
;
// 市场价格(分)
marketPrice
:
number
;
// 市场价格(分)
paymentPrice
?:
number
;
// 实付金额(分)
paymentPrice
?:
number
;
// 实付金额(分)
payOrderId
:
number
;
// 支付订单编号
payOrderId
:
number
;
// 支付订单编号
...
@@ -22,10 +23,40 @@ export interface ResourceOrder {
...
@@ -22,10 +23,40 @@ export interface ResourceOrder {
resourceStatus
:
number
;
// 算力资源状态:[0]未启用,[1]使用中,[2]已释放
resourceStatus
:
number
;
// 算力资源状态:[0]未启用,[1]使用中,[2]已释放
refundStatus
:
number
;
// 退款状态
refundStatus
:
number
;
// 退款状态
refundPrice
:
string
;
// 退款金额
refundPrice
:
string
;
// 退款金额
refundTime
?:
string
|
Dayjs
;
// 退款时间(阶段 D 新增,客服标已退款时填写)
deliveryIp
?:
string
;
// 发货 IP(阶段 C 新增)
deliveryUsername
?:
string
;
// 发货初始用户名(阶段 C 新增)
deliveryPassword
?:
string
;
// 发货初始密码(阶段 C 新增)
deliveredTime
?:
string
|
Dayjs
;
// 发货时间(阶段 C 新增)
deliverOperatorId
?:
number
;
// 发货操作人 ID(阶段 C 新增)
deliverOperatorName
?:
string
;
// 发货操作人姓名(阶段 C 新增)
invoiceStatus
:
number
;
// 开票状态:[0]未开 [1]开票中 [2]已开票
invoiceStatus
:
number
;
// 开票状态:[0]未开 [1]开票中 [2]已开票
invoiceUrl
:
string
;
// 发票链接
invoiceUrl
:
string
;
// 发票链接
createTime
:
string
|
Dayjs
;
// 创建时间
}
}
/** 商家发货 Request VO */
export
interface
ResourceOrderDeliverReqVO
{
orderId
:
number
;
deliveryIp
:
string
;
deliveryUsername
:
string
;
deliveryPassword
:
string
;
deliverRemark
?:
string
;
}
/** 客服取消订单 Request VO */
export
interface
ResourceOrderAdminCancelReqVO
{
orderId
:
number
;
reason
:
string
;
}
/** 客服标记已退款 Request VO */
export
interface
ResourceOrderMarkRefundedReqVO
{
orderId
:
number
;
refundPrice
?:
number
;
// 可选;null / 0 视为全额
refundRemark
?:
string
;
}
// 算力资源订单 API
// 算力资源订单 API
export
const
ResourceOrderApi
=
{
export
const
ResourceOrderApi
=
{
// 查询算力资源订单分页
// 查询算力资源订单分页
...
@@ -66,5 +97,20 @@ export const ResourceOrderApi = {
...
@@ -66,5 +97,20 @@ export const ResourceOrderApi = {
// 开具发票
// 开具发票
issueInvoice
:
async
(
data
:
any
)
=>
{
issueInvoice
:
async
(
data
:
any
)
=>
{
return
await
request
.
put
({
url
:
`/compute/resource-order/issue-invoice`
,
data
})
return
await
request
.
put
({
url
:
`/compute/resource-order/issue-invoice`
,
data
})
},
// 商家发货(阶段 C)
deliverResourceOrder
:
async
(
data
:
ResourceOrderDeliverReqVO
)
=>
{
return
await
request
.
post
({
url
:
`/compute/resource-order/deliver`
,
data
})
},
// 客服取消待发货订单(阶段 D)
adminCancelResourceOrder
:
async
(
data
:
ResourceOrderAdminCancelReqVO
)
=>
{
return
await
request
.
post
({
url
:
`/compute/resource-order/admin-cancel`
,
data
})
},
// 客服标记已退款(阶段 D)
markRefundedResourceOrder
:
async
(
data
:
ResourceOrderMarkRefundedReqVO
)
=>
{
return
await
request
.
post
({
url
:
`/compute/resource-order/mark-refunded`
,
data
})
}
}
}
}
\ No newline at end of file
src/views/compute/resourceorder/ResourceOrderDetail.vue
View file @
c03775b8
<
template
>
<
template
>
<Dialog
title=
"订单详情"
v-model=
"dialogVisible"
width=
"
7
20px"
>
<Dialog
title=
"订单详情"
v-model=
"dialogVisible"
width=
"
8
20px"
>
<el-descriptions
:column=
"2"
border
v-loading=
"loading"
label-width=
"130px"
>
<el-descriptions
:column=
"2"
border
v-loading=
"loading"
label-width=
"130px"
>
<el-descriptions-item
label=
"订单编号"
:span=
"2"
>
<el-descriptions-item
label=
"订单编号"
:span=
"2"
>
{{
detail
.
orderNo
}}
{{
detail
.
orderNo
}}
...
@@ -17,32 +17,60 @@
...
@@ -17,32 +17,60 @@
<dict-tag
:type=
"DICT_TYPE.COMPUTE_RESOURCE_ORDER_STATUS"
:value=
"detail.status"
/>
<dict-tag
:type=
"DICT_TYPE.COMPUTE_RESOURCE_ORDER_STATUS"
:value=
"detail.status"
/>
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"市场价格"
>
<el-descriptions-item
label=
"市场价格"
>
¥
{{
fenToYuan
(
detail
.
marketPrice
)
}}
¥
{{
fenToYuan
(
detail
.
marketPrice
??
0
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"实付金额"
>
<el-descriptions-item
label=
"实付金额"
>
¥
{{
fenToYuan
(
detail
.
paymentPrice
)
}}
¥
{{
fenToYuan
(
detail
.
paymentPrice
??
0
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"支付渠道"
>
<el-descriptions-item
label=
"支付渠道"
>
{{
detail
.
payChannelCode
}}
{{
detail
.
payChannelCode
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"支付时间"
>
<el-descriptions-item
label=
"支付时间"
>
{{
detail
.
payTime
?
formatDate
(
detail
.
payTime
)
:
'-'
}}
{{
formatDateTime
(
detail
.
payTime
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"租赁开始时间"
>
<el-descriptions-item
label=
"租赁开始时间"
>
{{
detail
.
rentStartTime
?
formatDate
(
detail
.
rentStartTime
)
:
'-'
}}
{{
formatDateTime
(
detail
.
rentStartTime
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"租赁结束时间"
>
<el-descriptions-item
label=
"租赁结束时间"
>
{{
detail
.
rentEndTime
?
formatDate
(
detail
.
rentEndTime
)
:
'-'
}}
{{
formatDateTime
(
detail
.
rentEndTime
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"取消时间"
>
<el-descriptions-item
label=
"取消时间"
>
{{
detail
.
cancelTime
?
formatDate
(
detail
.
cancelTime
)
:
'-'
}}
{{
formatDateTime
(
detail
.
cancelTime
)
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"退款状态"
>
<!-- 阶段 C:发货信息区(仅 DELIVERED 状态显示) -->
<dict-tag
:type=
"DICT_TYPE.COMPUTE_RESOURCE_REFUND_STATUS"
:value=
"detail.refundStatus"
/>
<template
v-if=
"detail.status === 6"
>
</el-descriptions-item>
<el-descriptions-item
label=
"服务器 IP"
:span=
"2"
>
<el-descriptions-item
label=
"退款金额"
>
{{
detail
.
deliveryIp
||
'-'
}}
{{
detail
.
refundPrice
?
'¥'
+
fenToYuan
(
Number
(
detail
.
refundPrice
))
:
'-'
}}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"初始用户名"
:span=
"2"
>
{{
detail
.
deliveryUsername
||
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"初始密码"
:span=
"2"
>
<span
v-if=
"showPassword"
>
{{
detail
.
deliveryPassword
||
'-'
}}
</span>
<el-button
v-else
link
type=
"primary"
@
click=
"showPassword = true"
>
显示密码
</el-button>
</el-descriptions-item>
<el-descriptions-item
label=
"发货时间"
>
{{
formatDateTime
(
detail
.
deliveredTime
)
}}
</el-descriptions-item>
<el-descriptions-item
label=
"发货人"
>
{{
detail
.
deliverOperatorName
||
'-'
}}
</el-descriptions-item>
</
template
>
<!-- 阶段 D:退款信息(仅 PENDING_REFUND 或 REFUNDED 显示) -->
<
template
v-if=
"detail.status === 7 || detail.status === 4"
>
<el-descriptions-item
label=
"退款状态"
>
<dict-tag
:type=
"DICT_TYPE.COMPUTE_RESOURCE_REFUND_STATUS"
:value=
"detail.refundStatus"
/>
</el-descriptions-item>
<el-descriptions-item
label=
"退款金额"
>
{{
detail
.
refundPrice
?
'¥'
+
fenToYuan
(
Number
(
detail
.
refundPrice
))
:
'-'
}}
</el-descriptions-item>
<el-descriptions-item
label=
"退款时间"
:span=
"2"
>
{{
formatDateTime
(
detail
.
refundTime
)
}}
</el-descriptions-item>
</
template
>
<el-descriptions-item
label=
"开票状态"
>
<el-descriptions-item
label=
"开票状态"
>
<dict-tag
:type=
"DICT_TYPE.TRADE_INVOICE_STATUS"
:value=
"detail.invoiceStatus"
/>
<dict-tag
:type=
"DICT_TYPE.TRADE_INVOICE_STATUS"
:value=
"detail.invoiceStatus"
/>
</el-descriptions-item>
</el-descriptions-item>
...
@@ -56,13 +84,49 @@
...
@@ -56,13 +84,49 @@
{{ detail.remark || '-' }}
{{ detail.remark || '-' }}
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item
label=
"创建时间"
>
<el-descriptions-item
label=
"创建时间"
>
{{
detail
.
createTime
?
formatDate
(
detail
.
createTime
)
:
'-'
}}
{{
formatDateTime(detail.createTime)
}}
</el-descriptions-item>
</el-descriptions-item>
</el-descriptions>
</el-descriptions>
<
template
#
footer
>
<
template
#
footer
>
<!-- 阶段 C:商家发货(仅 PENDING_DELIVERY) -->
<el-button
v-if=
"detail.status === 5"
v-hasPermi=
"['compute:resource-order:deliver']"
type=
"primary"
@
click=
"handleDeliver"
>
去发货
</el-button>
<!-- 阶段 D:客服取消(仅 PENDING_DELIVERY) -->
<el-button
v-if=
"detail.status === 5"
v-hasPermi=
"['compute:resource-order:admin-cancel']"
type=
"warning"
@
click=
"handleAdminCancel"
>
客服取消
</el-button>
<!-- 阶段 D:标记已退款(仅 PENDING_REFUND) -->
<el-button
v-if=
"detail.status === 7"
v-hasPermi=
"['compute:resource-order:mark-refunded']"
type=
"success"
@
click=
"handleMarkRefunded"
>
标记已退款
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
关 闭
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
关 闭
</el-button>
</
template
>
</
template
>
</Dialog>
</Dialog>
<!-- 阶段 C:商家发货弹窗 -->
<ResourceOrderDeliverForm
ref=
"deliverFormRef"
@
success=
"reloadDetail"
/>
<!-- 阶段 D:客服取消弹窗 -->
<ResourceOrderAdminCancelForm
ref=
"adminCancelFormRef"
@
success=
"reloadDetail"
/>
<!-- 阶段 D:标记已退款弹窗 -->
<ResourceOrderMarkRefundedForm
ref=
"markRefundedFormRef"
@
success=
"reloadDetail"
/>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
...
@@ -70,18 +134,43 @@ import { ResourceOrderApi, ResourceOrder } from '@/api/compute/resourceorder'
...
@@ -70,18 +134,43 @@ import { ResourceOrderApi, ResourceOrder } from '@/api/compute/resourceorder'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
DICT_TYPE
}
from
'@/utils/dict'
import
{
fenToYuan
}
from
'@/utils'
import
{
fenToYuan
}
from
'@/utils'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
formatDate
}
from
'@/utils/formatTime'
import
ResourceOrderDeliverForm
from
'./form/ResourceOrderDeliverForm.vue'
import
ResourceOrderAdminCancelForm
from
'./form/ResourceOrderAdminCancelForm.vue'
import
ResourceOrderMarkRefundedForm
from
'./form/ResourceOrderMarkRefundedForm.vue'
/** 算力资源订单详情 */
/** 算力资源订单详情 */
defineOptions
({
name
:
'ResourceOrderDetail'
})
defineOptions
({
name
:
'ResourceOrderDetail'
})
const
dialogVisible
=
ref
(
false
)
const
dialogVisible
=
ref
(
false
)
const
loading
=
ref
(
false
)
const
loading
=
ref
(
false
)
const
detail
=
ref
<
Partial
<
ResourceOrder
>>
({})
const
detail
=
ref
<
any
>
({})
// 后端返回完整订单对象,用 any 避免 Partial 严格推断
const
showPassword
=
ref
(
false
)
// 密码默认隐藏
const
deliverFormRef
=
ref
()
// 发货弹窗
const
adminCancelFormRef
=
ref
()
// 客服取消弹窗
const
markRefundedFormRef
=
ref
()
// 标记已退款弹窗
let
currentOrderId
:
number
|
undefined
=
undefined
/**
* 格式化日期(兼容 string / Dayjs / Date / undefined / null)
*/
const
formatDateTime
=
(
val
:
any
):
string
=>
{
if
(
!
val
)
return
'-'
if
(
val
instanceof
Date
)
return
formatDate
(
val
)
if
(
typeof
val
===
'string'
)
return
formatDate
(
new
Date
(
val
))
if
(
typeof
val
===
'number'
)
return
formatDate
(
new
Date
(
val
))
// Dayjs 对象
if
(
typeof
val
.
format
===
'function'
)
return
formatDate
(
val
.
toDate
())
return
'-'
}
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
id
:
number
)
=>
{
const
open
=
async
(
id
:
number
)
=>
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
loading
.
value
=
true
loading
.
value
=
true
showPassword
.
value
=
false
currentOrderId
=
id
try
{
try
{
detail
.
value
=
await
ResourceOrderApi
.
getResourceOrder
(
id
)
detail
.
value
=
await
ResourceOrderApi
.
getResourceOrder
(
id
)
}
finally
{
}
finally
{
...
@@ -89,5 +178,31 @@ const open = async (id: number) => {
...
@@ -89,5 +178,31 @@ const open = async (id: number) => {
}
}
}
}
/** 操作后重新拉详情 */
const
reloadDetail
=
async
()
=>
{
if
(
!
currentOrderId
)
return
loading
.
value
=
true
try
{
detail
.
value
=
await
ResourceOrderApi
.
getResourceOrder
(
currentOrderId
)
}
finally
{
loading
.
value
=
false
}
}
/** 阶段 C:打开发货弹窗 */
const
handleDeliver
=
()
=>
{
deliverFormRef
.
value
?.
open
(
detail
.
value
as
ResourceOrder
)
}
/** 阶段 D:打开客服取消弹窗 */
const
handleAdminCancel
=
()
=>
{
adminCancelFormRef
.
value
?.
open
(
detail
.
value
as
ResourceOrder
)
}
/** 阶段 D:打开标记已退款弹窗 */
const
handleMarkRefunded
=
()
=>
{
markRefundedFormRef
.
value
?.
open
(
detail
.
value
as
ResourceOrder
)
}
defineExpose
({
open
})
defineExpose
({
open
})
</
script
>
</
script
>
src/views/compute/resourceorder/form/ResourceOrderAdminCancelForm.vue
0 → 100644
View file @
c03775b8
<
template
>
<Dialog
title=
"客服取消订单"
v-model=
"dialogVisible"
width=
"500px"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"rules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"订单编号"
>
<span>
{{
formData
.
orderNo
}}
</span>
</el-form-item>
<el-form-item
label=
"商品名称"
>
<span>
{{
formData
.
spuName
}}
</span>
</el-form-item>
<el-alert
type=
"warning"
:closable=
"false"
show-icon
title=
"取消后客户将进入待退款状态,需客服人工退款"
/>
<el-form-item
label=
"取消原因"
prop=
"reason"
style=
"margin-top: 12px"
>
<el-input
v-model=
"formData.reason"
type=
"textarea"
:rows=
"3"
placeholder=
"请输入取消原因(5-200 字)"
maxlength=
"200"
show-word-limit
/>
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"warning"
@
click=
"submitForm"
>
确认取消
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ResourceOrderApi
,
ResourceOrder
}
from
'@/api/compute/resourceorder'
defineOptions
({
name
:
'ResourceOrderAdminCancelForm'
})
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗是否展示
const
formRef
=
ref
()
// 表单 Ref
const
formLoading
=
ref
(
false
)
// 表单的加载中
interface
AdminCancelFormData
{
orderId
?:
number
orderNo
:
string
spuName
:
string
reason
:
string
}
const
formData
=
reactive
<
AdminCancelFormData
>
({
orderId
:
undefined
,
orderNo
:
''
,
spuName
:
''
,
reason
:
''
})
const
rules
=
{
reason
:
[
{
required
:
true
,
message
:
'取消原因不能为空'
,
trigger
:
'blur'
},
{
min
:
5
,
max
:
200
,
message
:
'原因长度 5-200 字'
,
trigger
:
'blur'
}
]
}
const
emit
=
defineEmits
([
'success'
])
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
orderId
=
undefined
formData
.
orderNo
=
''
formData
.
spuName
=
''
formData
.
reason
=
''
formRef
.
value
?.
resetFields
()
}
/** 打开弹窗 */
const
open
=
(
row
:
ResourceOrder
)
=>
{
resetForm
()
formData
.
orderId
=
row
.
id
formData
.
orderNo
=
row
.
orderNo
??
''
formData
.
spuName
=
row
.
spuName
??
''
dialogVisible
.
value
=
true
}
/** 提交表单 */
const
submitForm
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
}
catch
{
return
}
if
(
!
formData
.
orderId
)
return
// 二次确认
try
{
await
message
.
confirm
(
'确认取消该订单?取消后客户将进入待退款状态'
)
}
catch
{
return
}
formLoading
.
value
=
true
try
{
await
ResourceOrderApi
.
adminCancelResourceOrder
({
orderId
:
formData
.
orderId
,
reason
:
formData
.
reason
})
message
.
success
(
'已取消,等待退款'
)
dialogVisible
.
value
=
false
emit
(
'success'
,
true
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
formLoading
.
value
=
false
}
}
defineExpose
({
open
})
</
script
>
src/views/compute/resourceorder/form/ResourceOrderDeliverForm.vue
0 → 100644
View file @
c03775b8
<
template
>
<Dialog
title=
"商家发货"
v-model=
"dialogVisible"
width=
"500px"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"rules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"订单编号"
>
<span>
{{
formData
.
orderNo
}}
</span>
</el-form-item>
<el-form-item
label=
"商品名称"
>
<span>
{{
formData
.
spuName
}}
</span>
</el-form-item>
<el-form-item
label=
"服务器 IP"
prop=
"deliveryIp"
>
<el-input
v-model=
"formData.deliveryIp"
placeholder=
"请输入服务器 IP"
/>
</el-form-item>
<el-form-item
label=
"初始用户名"
prop=
"deliveryUsername"
>
<el-input
v-model=
"formData.deliveryUsername"
placeholder=
"请输入初始用户名"
/>
</el-form-item>
<el-form-item
label=
"初始密码"
prop=
"deliveryPassword"
>
<el-input
v-model=
"formData.deliveryPassword"
placeholder=
"请输入初始密码"
show-password
/>
</el-form-item>
<el-form-item
label=
"发货备注"
>
<el-input
v-model=
"formData.deliverRemark"
type=
"textarea"
:rows=
"2"
placeholder=
"选填,如:已预装 CentOS 7.9"
/>
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"primary"
@
click=
"submitForm"
>
确认发货
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ResourceOrderApi
,
ResourceOrder
}
from
'@/api/compute/resourceorder'
defineOptions
({
name
:
'ResourceOrderDeliverForm'
})
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗是否展示
const
formRef
=
ref
()
// 表单 Ref
const
formLoading
=
ref
(
false
)
// 表单的加载中
interface
DeliverFormData
{
orderId
?:
number
orderNo
:
string
spuName
:
string
deliveryIp
:
string
deliveryUsername
:
string
deliveryPassword
:
string
deliverRemark
:
string
}
const
formData
=
reactive
<
DeliverFormData
>
({
orderId
:
undefined
,
orderNo
:
''
,
spuName
:
''
,
deliveryIp
:
''
,
deliveryUsername
:
''
,
deliveryPassword
:
''
,
deliverRemark
:
''
})
const
rules
=
{
deliveryIp
:
[{
required
:
true
,
message
:
'服务器 IP 不能为空'
,
trigger
:
'blur'
}],
deliveryUsername
:
[{
required
:
true
,
message
:
'初始用户名不能为空'
,
trigger
:
'blur'
}],
deliveryPassword
:
[{
required
:
true
,
message
:
'初始密码不能为空'
,
trigger
:
'blur'
}]
}
const
emit
=
defineEmits
([
'success'
])
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
orderId
=
undefined
formData
.
orderNo
=
''
formData
.
spuName
=
''
formData
.
deliveryIp
=
''
formData
.
deliveryUsername
=
''
formData
.
deliveryPassword
=
''
formData
.
deliverRemark
=
''
formRef
.
value
?.
resetFields
()
}
/** 打开弹窗 */
const
open
=
(
row
:
ResourceOrder
)
=>
{
resetForm
()
formData
.
orderId
=
row
.
id
formData
.
orderNo
=
row
.
orderNo
??
''
formData
.
spuName
=
row
.
spuName
??
''
dialogVisible
.
value
=
true
}
/** 提交表单 */
const
submitForm
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
}
catch
{
return
}
if
(
!
formData
.
orderId
)
return
formLoading
.
value
=
true
try
{
await
ResourceOrderApi
.
deliverResourceOrder
({
orderId
:
formData
.
orderId
,
deliveryIp
:
formData
.
deliveryIp
,
deliveryUsername
:
formData
.
deliveryUsername
,
deliveryPassword
:
formData
.
deliveryPassword
,
deliverRemark
:
formData
.
deliverRemark
||
undefined
})
message
.
success
(
'发货成功'
)
dialogVisible
.
value
=
false
emit
(
'success'
,
true
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
formLoading
.
value
=
false
}
}
defineExpose
({
open
})
</
script
>
src/views/compute/resourceorder/form/ResourceOrderMarkRefundedForm.vue
0 → 100644
View file @
c03775b8
<
template
>
<Dialog
title=
"标记已退款"
v-model=
"dialogVisible"
width=
"500px"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"rules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"订单编号"
>
<span>
{{
formData
.
orderNo
}}
</span>
</el-form-item>
<el-form-item
label=
"商品名称"
>
<span>
{{
formData
.
spuName
}}
</span>
</el-form-item>
<el-form-item
label=
"支付金额"
>
<span>
¥
{{
paymentPriceYuanText
}}
</span>
</el-form-item>
<el-form-item
label=
"退款金额"
prop=
"refundPrice"
>
<el-input-number
v-model=
"formData.refundPrice"
:precision=
"2"
:min=
"0"
:max=
"paymentPriceYuanNumber"
:step=
"0.01"
placeholder=
"0 表示全额"
class=
"!w-200px"
/>
<el-button
link
type=
"primary"
@
click=
"fillFullRefund"
class=
"ml-8px"
>
全额退款
</el-button>
</el-form-item>
<el-form-item
label=
"退款备注"
>
<el-input
v-model=
"formData.refundRemark"
type=
"textarea"
:rows=
"2"
placeholder=
"选填,如:已通过 WPGJ 对账退款"
/>
</el-form-item>
<el-alert
type=
"warning"
:closable=
"false"
show-icon
title=
"此操作不可撤销,请确认已通过线下渠道(银行 / WPGJ)完成退款后再操作"
/>
</el-form>
<template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"success"
@
click=
"submitForm"
>
确认已退款
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
ResourceOrderApi
,
ResourceOrder
}
from
'@/api/compute/resourceorder'
import
{
fenToYuan
}
from
'@/utils'
defineOptions
({
name
:
'ResourceOrderMarkRefundedForm'
})
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗是否展示
const
formRef
=
ref
()
// 表单 Ref
const
formLoading
=
ref
(
false
)
// 表单的加载中
interface
MarkRefundedFormData
{
orderId
?:
number
orderNo
:
string
spuName
:
string
refundPrice
:
number
refundRemark
:
string
}
const
formData
=
reactive
<
MarkRefundedFormData
>
({
orderId
:
undefined
,
orderNo
:
''
,
spuName
:
''
,
refundPrice
:
0
,
refundRemark
:
''
})
/** 后端 paymentPrice 是分,UI 用元,提交时再换算回分 */
const
paymentPriceFen
=
ref
(
0
)
/** 展示用文本(保留 2 位小数) */
const
paymentPriceYuanText
=
computed
(()
=>
fenToYuan
(
paymentPriceFen
.
value
))
/** 用于 el-input-number max / 规则校验(number) */
const
paymentPriceYuanNumber
=
computed
(()
=>
Number
(
fenToYuan
(
paymentPriceFen
.
value
)))
const
rules
=
{
refundPrice
:
[
{
validator
:
(
_rule
:
unknown
,
value
:
number
,
callback
:
(
err
?:
Error
)
=>
void
)
=>
{
if
(
value
<
0
)
{
callback
(
new
Error
(
'退款金额不能为负数'
))
}
else
if
(
value
>
paymentPriceYuanNumber
.
value
)
{
callback
(
new
Error
(
'退款金额不能超过支付金额'
))
}
else
{
callback
()
}
},
trigger
:
'blur'
}
]
}
const
emit
=
defineEmits
([
'success'
])
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
orderId
=
undefined
formData
.
orderNo
=
''
formData
.
spuName
=
''
formData
.
refundPrice
=
0
formData
.
refundRemark
=
''
paymentPriceFen
.
value
=
0
formRef
.
value
?.
resetFields
()
}
/** 打开弹窗 */
const
open
=
(
row
:
ResourceOrder
)
=>
{
resetForm
()
formData
.
orderId
=
row
.
id
formData
.
orderNo
=
row
.
orderNo
??
''
formData
.
spuName
=
row
.
spuName
??
''
paymentPriceFen
.
value
=
row
.
paymentPrice
??
0
formData
.
refundPrice
=
paymentPriceYuanNumber
.
value
dialogVisible
.
value
=
true
}
/** 全额退款快捷按钮 */
const
fillFullRefund
=
()
=>
{
formData
.
refundPrice
=
paymentPriceYuanNumber
.
value
}
/** 提交表单 */
const
submitForm
=
async
()
=>
{
if
(
!
formRef
.
value
)
return
try
{
await
formRef
.
value
.
validate
()
}
catch
{
return
}
if
(
!
formData
.
orderId
)
return
// 二次确认
try
{
await
message
.
confirm
(
'确认该订单已退款?此操作不可撤销'
)
}
catch
{
return
}
formLoading
.
value
=
true
try
{
// 元 → 分(保留整数,向下取整)
const
refundPriceFen
=
formData
.
refundPrice
&&
formData
.
refundPrice
>
0
?
Math
.
floor
(
formData
.
refundPrice
*
100
)
:
undefined
await
ResourceOrderApi
.
markRefundedResourceOrder
({
orderId
:
formData
.
orderId
,
refundPrice
:
refundPriceFen
,
refundRemark
:
formData
.
refundRemark
||
undefined
})
message
.
success
(
'已标记为已退款'
)
dialogVisible
.
value
=
false
emit
(
'success'
,
true
)
}
catch
(
error
)
{
console
.
error
(
error
)
}
finally
{
formLoading
.
value
=
false
}
}
defineExpose
({
open
})
</
script
>
src/views/compute/resourceorder/index.vue
View file @
c03775b8
...
@@ -308,6 +308,14 @@
...
@@ -308,6 +308,14 @@
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
<el-table-column
label=
"发货时间"
align=
"center"
prop=
"deliveredTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"发货人"
align=
"center"
prop=
"deliverOperatorName"
min-width=
"100"
/>
<el-table-column
label=
"取消时间"
label=
"取消时间"
align=
"center"
align=
"center"
prop=
"cancelTime"
prop=
"cancelTime"
...
@@ -331,6 +339,13 @@
...
@@ -331,6 +339,13 @@
<el-table-column
label=
"退款金额"
align=
"center"
prop=
"refundPrice"
>
<el-table-column
label=
"退款金额"
align=
"center"
prop=
"refundPrice"
>
<
template
#
default=
"{ row }"
>
¥
{{
fenToYuan
(
row
.
refundPrice
)
}}
</
template
>
<
template
#
default=
"{ row }"
>
¥
{{
fenToYuan
(
row
.
refundPrice
)
}}
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"退款时间"
align=
"center"
prop=
"refundTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"开票状态"
align=
"center"
prop=
"invoiceStatus"
width=
"90"
>
<el-table-column
label=
"开票状态"
align=
"center"
prop=
"invoiceStatus"
width=
"90"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.TRADE_INVOICE_STATUS"
:value=
"scope.row.invoiceStatus"
/>
<dict-tag
:type=
"DICT_TYPE.TRADE_INVOICE_STATUS"
:value=
"scope.row.invoiceStatus"
/>
...
@@ -344,7 +359,7 @@
...
@@ -344,7 +359,7 @@
:formatter=
"dateFormatter"
:formatter=
"dateFormatter"
width=
"180px"
width=
"180px"
/>
/>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"
19
0px"
fixed=
"right"
>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"
30
0px"
fixed=
"right"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<el-button
<el-button
link
link
...
@@ -354,14 +369,36 @@
...
@@ -354,14 +369,36 @@
>
>
详情
详情
</el-button>
</el-button>
<!--
<el-button
<!-- 阶段 C:商家发货(仅 PENDING_DELIVERY 显示) -->
<el-button
v-if=
"scope.row.status === 5"
link
link
type=
"primary"
type=
"primary"
@
click=
"
openForm('update', scope.row.id
)"
@
click=
"
handleDeliver(scope.row
)"
v-hasPermi=
"['compute:resource-order:
update
']"
v-hasPermi=
"['compute:resource-order:
deliver
']"
>
>
编辑
发货
</el-button>
-->
</el-button>
<!-- 阶段 D:客服取消(仅 PENDING_DELIVERY 显示) -->
<el-button
v-if=
"scope.row.status === 5"
link
type=
"warning"
@
click=
"handleAdminCancel(scope.row)"
v-hasPermi=
"['compute:resource-order:admin-cancel']"
>
客服取消
</el-button>
<!-- 阶段 D:标记已退款(仅 PENDING_REFUND 显示) -->
<el-button
v-if=
"scope.row.status === 7"
link
type=
"success"
@
click=
"handleMarkRefunded(scope.row)"
v-hasPermi=
"['compute:resource-order:mark-refunded']"
>
标记已退款
</el-button>
<!-- 如果订单开票状态为【未开票】【开票中】,则展示【开票】按钮-->
<!-- 如果订单开票状态为【未开票】【开票中】,则展示【开票】按钮-->
<el-button
<el-button
v-if=
"
v-if=
"
...
@@ -421,6 +458,15 @@
...
@@ -421,6 +458,15 @@
<!-- 开票表单弹窗 -->
<!-- 开票表单弹窗 -->
<ResourceOrderIssueInvoiceForm
ref=
"issueInvoiceFormRef"
@
success=
"getList"
/>
<ResourceOrderIssueInvoiceForm
ref=
"issueInvoiceFormRef"
@
success=
"getList"
/>
<!-- 阶段 C:商家发货弹窗 -->
<ResourceOrderDeliverForm
ref=
"deliverFormRef"
@
success=
"getList"
/>
<!-- 阶段 D:客服取消弹窗 -->
<ResourceOrderAdminCancelForm
ref=
"adminCancelFormRef"
@
success=
"getList"
/>
<!-- 阶段 D:标记已退款弹窗 -->
<ResourceOrderMarkRefundedForm
ref=
"markRefundedFormRef"
@
success=
"getList"
/>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
...
@@ -434,6 +480,9 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
...
@@ -434,6 +480,9 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import
{
fenToYuan
}
from
'@/utils'
import
{
fenToYuan
}
from
'@/utils'
import
{
InvoiceRequestEnum
}
from
'@/utils/constants'
import
{
InvoiceRequestEnum
}
from
'@/utils/constants'
import
ResourceOrderIssueInvoiceForm
from
'./form/ResourceOrderIssueInvoiceForm.vue'
import
ResourceOrderIssueInvoiceForm
from
'./form/ResourceOrderIssueInvoiceForm.vue'
import
ResourceOrderDeliverForm
from
'./form/ResourceOrderDeliverForm.vue'
import
ResourceOrderAdminCancelForm
from
'./form/ResourceOrderAdminCancelForm.vue'
import
ResourceOrderMarkRefundedForm
from
'./form/ResourceOrderMarkRefundedForm.vue'
/** 算力资源订单 列表 */
/** 算力资源订单 列表 */
defineOptions
({
name
:
'ResourceOrder'
})
defineOptions
({
name
:
'ResourceOrder'
})
...
@@ -471,6 +520,9 @@ const queryParams = reactive({
...
@@ -471,6 +520,9 @@ const queryParams = reactive({
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
exportLoading
=
ref
(
false
)
// 导出的加载中
const
issueInvoiceFormRef
=
ref
()
// 开票表单ref
const
issueInvoiceFormRef
=
ref
()
// 开票表单ref
const
deliverFormRef
=
ref
()
// 发货表单ref(阶段 C)
const
adminCancelFormRef
=
ref
()
// 客服取消表单ref(阶段 D)
const
markRefundedFormRef
=
ref
()
// 标记已退款表单ref(阶段 D)
const
detailRef
=
ref
()
// 详情弹窗ref
const
detailRef
=
ref
()
// 详情弹窗ref
const
pdfDialogVisible
=
ref
(
false
)
// 发票预览弹窗
const
pdfDialogVisible
=
ref
(
false
)
// 发票预览弹窗
const
invoiceUrl
=
ref
(
''
)
// 发票地址
const
invoiceUrl
=
ref
(
''
)
// 发票地址
...
@@ -554,6 +606,21 @@ const handleIssueInvoice = (row: ResourceOrder) => {
...
@@ -554,6 +606,21 @@ const handleIssueInvoice = (row: ResourceOrder) => {
issueInvoiceFormRef
.
value
?.
open
(
row
)
issueInvoiceFormRef
.
value
?.
open
(
row
)
}
}
/** 阶段 C:商家发货 */
const
handleDeliver
=
(
row
:
ResourceOrder
)
=>
{
deliverFormRef
.
value
?.
open
(
row
)
}
/** 阶段 D:客服取消 */
const
handleAdminCancel
=
(
row
:
ResourceOrder
)
=>
{
adminCancelFormRef
.
value
?.
open
(
row
)
}
/** 阶段 D:标记已退款 */
const
handleMarkRefunded
=
(
row
:
ResourceOrder
)
=>
{
markRefundedFormRef
.
value
?.
open
(
row
)
}
/** 查看详情 */
/** 查看详情 */
const
handleDetail
=
(
id
:
number
)
=>
{
const
handleDetail
=
(
id
:
number
)
=>
{
detailRef
.
value
?.
open
(
id
)
detailRef
.
value
?.
open
(
id
)
...
...
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