Commit 96b0e396 by renyizhao

算力资源改造完成

parent 21fe1bfc
......@@ -54,12 +54,30 @@ export function delOrder (id) {
}
// 取消订单-订单管理
export function cancelOrder (data) {
return request({
url: '/api/v1/orderCancel',
method: 'post',
data: data
})
// 阶段 F:旧的 /api/v1/orderCancel 端点(ApiControllerUnuse)整段被注释,调它会 404
// 改为调新的 /compute/order/cancel(AppResourceOrderController 已实现)
export function cancelOrder (data){
return request({
url: '/compute/order/cancel',
method: 'put',
params: data
})
}
/**
* 阶段 F:获取订单发货信息(IP / 用户名 / 密码)
* 独立的接口,避免在主订单接口下发敏感字段。
* 后端:AppResourceOrderController.getUserResourceOrderDeliveryInfo
* 响应:AppResourceOrderDeliveryInfoRespVO
* - 非 DELIVERED 状态:发货字段为 null
* - 订单必须属于当前用户
*/
export function getOrderDeliveryInfo (orderId) {
return request({
url: '/compute/order/get-delivery-info',
method: 'get',
params: { id: orderId }
})
}
......
......@@ -3,7 +3,10 @@ import { getDicts } from '@/api/system/dict/data'
import request from "@/utils/request.js";
export const DICT_TYPE = {
TRADE_INVOICE_STATUS: 'trade_invoice_status'
TRADE_INVOICE_STATUS: 'trade_invoice_status',
// ========== 阶段 F 客户端字典 ==========
COMPUTE_RESOURCE_ORDER_STATUS: 'compute_resource_order_status',
COMPUTE_RESOURCE_REFUND_STATUS: 'compute_resource_refund_status'
}
/**
......
<template>
<div class="app-container order-result">
<img src="@/assets/images/order-success.png" alt="">
<div class="text">申请成功</div>
<div class="sub-text">如有需要可返回产品页继续选购</div>
<!-- 阶段 F:支付成功 → 商家备货中(不再"立即生效",因为阶段 A 后发货才计费) -->
<div class="text">申请成功,商家备货中</div>
<div class="sub-text">支付完成后商家将为您准备资源,预计 24 小时内完成发货并通过短信通知您</div>
<!-- 规格展示(仅当路由 state 传入 specMap 时显示) -->
<div v-if="specEntries.length > 0" class="spec-block">
......@@ -14,7 +15,7 @@
</div>
<div>
<el-button type="primary" @click="$router.replace('/computingResource/resourceList')">继续选购</el-button>
<el-button type="primary" @click="$router.replace('/console/myOrder')">查看我的订单</el-button>
</div>
<div>
<el-button type="default" @click="$router.replace('/')">返回首页</el-button>
......
......@@ -7,14 +7,6 @@
v-show="showSearch"
label-width="68px"
>
<!-- <el-form-item label="订单编号" prop="orderNo">-->
<!-- <el-input-->
<!-- v-model="queryParams.orderNo"-->
<!-- placeholder="请输入订单编号"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="资源类型" prop="category">
<el-select
v-model="queryParams.categoryId"
......@@ -31,62 +23,6 @@
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="型号" prop="model">-->
<!-- <el-select-->
<!-- v-model="queryParams.model"-->
<!-- placeholder="请选择型号"-->
<!-- clearable-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="dict in model"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="CPU" prop="cpu">-->
<!-- <el-select v-model="queryParams.cpu" placeholder="请选择CPU" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in cpu_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="GPU" prop="gpu">-->
<!-- <el-select v-model="queryParams.gpu" placeholder="请选择GPU" clearable>-->
<!-- <el-option-->
<!-- v-for="dict in gpu_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="内存" prop="memory">-->
<!-- <el-select-->
<!-- v-model="queryParams.memory"-->
<!-- placeholder="请选择内存"-->
<!-- clearable-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="dict in memory_type"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="算力金额" prop="price">-->
<!-- <el-input-->
<!-- v-model="queryParams.price"-->
<!-- placeholder="请输入算力金额"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索
......@@ -101,11 +37,8 @@
:data="orderList"
:max-height="620"
>
<!--<el-table-column type="selection" width="45" align="center"/>-->
<!--<el-table-column label="序号" align="center" prop="id"/>-->
<el-table-column label="商品名称" align="center" prop="spuName"/>
<el-table-column label="订单编号" align="center" prop="orderNo"/>
<!--<el-table-column label="商品数量" align="center" prop="productCount"/>-->
<el-table-column label="费用" align="center" prop="paymentPrice">
<template #default="scope">
{{ scope.row.paymentPrice / 100 }}
......@@ -123,12 +56,11 @@
</template>
</el-table-column>
<el-table-column label="所在地" align="center" prop="location"/>
<el-table-column label="订单状态" align="center" prop="status">
<el-table-column label="订单状态" align="center" prop="status" width="100">
<template #default="scope">
<dict-tag :options="compute_resource_order_status" :value="scope.row.status" />
</template>
</el-table-column>
<!-- <el-table-column label="发票链接" align="center" prop="invoiceUrl"/>-->
<el-table-column label="开票状态" align="center" prop="invoiceStatus">
<template #default="scope">
<dict-tag :options="trade_invoice_status" :value="scope.row.invoiceStatus" />
......@@ -143,10 +75,25 @@
label="操作"
align="center"
fixed="right"
min-width="280"
class-name="small-padding fixed-width">
<template #default="scope">
<!-- 阶段 F:详情按钮(所有状态可见) -->
<el-button link type="primary" @click="handleDetails(scope.row)">详情</el-button>
<!-- 阶段 F:取消订单 / 申请退款(仅 UNPAID=0 PENDING_DELIVERY=5 可取消) -->
<el-button
v-if="scope.row.invoiceStatus === InvoiceRequestEnum.UNINVOICED.type"
v-if="scope.row.status === 0 || scope.row.status === 5"
link
type="warning"
@click="handleCancelOrder(scope.row)"
>
{{ scope.row.status === 5 ? '申请退款' : '取消订单' }}
</el-button>
<!-- 阶段 F:申请开票条件改为 status===6DELIVERED+ 仍未开票 -->
<el-button
v-if="scope.row.status === 6 && scope.row.invoiceStatus === InvoiceRequestEnum.UNINVOICED.type"
link
type="primary"
@click="invoiceRequest(scope.row)"
......@@ -167,6 +114,16 @@
</el-table>
<!-- 阶段 F:列表底部 PENDING_REFUND 状态统一提示(可改为按行展示) -->
<div v-if="hasPendingRefund" class="refund-banner">
<el-alert
:title="`您有 ${pendingRefundCount} 个订单处于「待退款」状态,款项将由客服人工处理(1-3 个工作日)`"
type="warning"
:closable="false"
show-icon
/>
</div>
<pagination
v-show="total > 0"
:total="total"
......@@ -191,27 +148,76 @@
<!-- 添加或修改订单管理-需求单管理对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<div>
<div class="info-block">
<div class="info-item flex-align-center flex-space-between">
<div class="label">商品名称</div>
<div class="value">{{ form.spuName }}</div>
</div>
<el-dialog :title="title" v-model="open" width="640px" append-to-body>
<div v-loading="detailLoading">
<!-- 阶段 F:状态卡片顶部 el-alert 提示(按 status 分支) -->
<el-alert
v-if="form.status === 0"
type="info"
:closable="false"
show-icon
title="订单待支付,请尽快完成支付"
/>
<el-alert
v-else-if="form.status === 5"
type="warning"
:closable="false"
show-icon
title="商家备货中,预计 24 小时内发货"
/>
<el-alert
v-else-if="form.status === 6"
type="success"
:closable="false"
show-icon
:title="`资源使用中,租赁结束时间:${parseTime(form.rentEndTime, '{y}-{m}-{d} {h}:{i}:{s}')}`"
/>
<el-alert
v-else-if="form.status === 7"
type="warning"
:closable="false"
show-icon
title="订单已取消,正在等待客服处理退款(1-3 个工作日)"
/>
<el-alert
v-else-if="form.status === 4"
type="success"
:closable="false"
show-icon
title="订单已退款完成"
/>
<el-alert
v-else-if="form.status === 2"
type="info"
:closable="false"
show-icon
title="订单已结束"
/>
<el-alert
v-else-if="form.status === 3"
type="info"
:closable="false"
show-icon
title="订单已取消"
/>
<div class="info-block" style="margin-top: 12px;">
<div class="info-item flex-align-center flex-space-between">
<div class="label">订单编号</div>
<div class="value">{{ form.orderNo }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">商品名称</div>
<div class="value">{{ form.spuName }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">费用</div>
<div class="value">{{ form.paymentPrice ? (form.paymentPrice / 100) : '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="info-item flex-align-center flex-space-between">
<div class="label">资源类型</div>
<div class="value">{{ form.categoryName }}</div>
</div>
</div>
<div class="info-block">
......@@ -224,18 +230,49 @@
<div class="value">-</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器IP</div>
<div class="value">{{ form.ip || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器所在地</div>
<div class="value">{{ form.location || '-' }}</div>
</div>
</div>
<!-- 阶段 F:发货信息区(仅 DELIVERED 状态显示),字段从 getDeliveryInfo -->
<div v-if="form.status === 6" class="info-block">
<div class="info-block-title">发货信息</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器 IP</div>
<div class="value">{{ form.deliveryIp || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">初始用户名</div>
<div class="value">{{ form.deliveryUsername || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">初始密码</div>
<div class="value">
<span v-if="showPassword">{{ form.deliveryPassword || '-' }}</span>
<el-button v-else link type="primary" @click="showPassword = true">显示密码</el-button>
</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">发货时间</div>
<div class="value">{{ parseTime(form.deliveredTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</div>
</div>
</div>
<!-- 阶段 F:退款信息(仅 PENDING_REFUND=7 REFUNDED=4 -->
<div v-if="form.status === 7 || form.status === 4" class="info-block">
<div class="info-block-title">退款信息</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">退款时间</div>
<div class="value">{{ parseTime(form.refundTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</div>
</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">订单状态</div>
<div class="value">{{ form.statusName }}</div>
<div class="value">
<dict-tag :options="compute_resource_order_status" :value="form.status" />
</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">下单时间</div>
......@@ -244,6 +281,14 @@
</div>
<template #footer>
<div class="dialog-footer">
<!-- 阶段 F:详情页底部操作按钮 -->
<el-button
v-if="form.status === 0 || form.status === 5"
type="warning"
@click="handleCancelOrder(form)"
>
{{ form.status === 5 ? '申请退款' : '取消订单' }}
</el-button>
<el-button @click="cancel">关闭</el-button>
</div>
</template>
......@@ -254,23 +299,26 @@
<script setup name="MyOrder">
import {
listOrder
listOrder,
cancelOrder,
orderInvoiceRequest,
getCategories,
getOrderDeliveryInfo
} from '@/api/computility/order'
import {orderInvoiceRequest, getCategories} from '@/api/computility/order'
import {parseTime} from "../../utils/ruoyi.js";
import {getResources} from "@/api/computility/resources.js";
import {ElMessage} from "element-plus";
import {InvoiceRequestEnum} from "@/utils/constants.js";
const {proxy} = getCurrentInstance()
const {trade_invoice_status, compute_resource_order_status} = proxy.useDict('trade_invoice_status', 'compute_resource_order_status')
const orderList = ref([])
const open = ref(false)
const sOpen = ref(false)
const loading = ref(true)
const detailLoading = ref(false)
const showSearch = ref(true)
const total = ref(0)
const title = ref('')
const showPassword = ref(false) // 阶段 F:详情页密码默认隐藏
const data = reactive({
form: {},
......@@ -278,50 +326,15 @@ const data = reactive({
pageNum: 1,
pageSize: 10,
orderNo: null,
categoryId: null,
model: null,
cpu: null,
gpu: null,
memory: null,
storage: null,
price: null,
orderStatus: null,
networkId: null,
ipNum: null,
vmStorage: null,
submitTime: null,
applyUser: null,
useTime: null
},
rules: {
category: [
{required: true, message: '商品类别不能为空', trigger: 'change'}
],
model: [{required: true, message: '型号不能为空', trigger: 'change'}],
cpu: [{required: true, message: 'CPU不能为空', trigger: 'change'}],
gpu: [{required: true, message: 'GPU不能为空', trigger: 'change'}],
memory: [{required: true, message: '内存不能为空', trigger: 'change'}],
storage: [
{required: true, message: '存储硬盘不能为空', trigger: 'change'}
],
orderStatus: [
{required: true, message: '状态不能为空', trigger: 'change'}
],
networkId: [
{required: true, message: '网络带宽不能为空', trigger: 'blur'}
],
submitTime: [
{required: true, message: '下单时间不能为空', trigger: 'blur'}
],
applyUser: [{required: true, message: '应用人不能为空', trigger: 'blur'}],
useTime: [{required: true, message: '使用期限不能为空', trigger: 'blur'}],
createTime: [
{required: true, message: '创建时间不能为空', trigger: 'blur'}
]
categoryId: null
}
})
const {queryParams, form, rules} = toRefs(data)
const {queryParams, form} = toRefs(data)
/** 阶段 F:列表中待退款订单数(底部统一提示) */
const pendingRefundCount = computed(() => orderList.value.filter(o => o.status === 7).length)
const hasPendingRefund = computed(() => pendingRefundCount.value > 0)
/** 查询订单管理-需求单管理列表 */
function getList() {
......@@ -350,30 +363,8 @@ function cancel() {
// 表单重置
function reset() {
form.value = {
id: null,
orderNo: null,
categoryId: null,
model: null,
cpu: null,
gpu: null,
memory: null,
storage: null,
price: null,
orderStatus: null,
networkId: null,
ipNum: null,
vmStorage: null,
submitTime: null,
applyUser: null,
useTime: null,
createTime: null,
createBy: null,
updateBy: null,
updateTime: null,
remark: null,
delFlag: null
}
form.value = {}
showPassword.value = false
proxy.resetForm('orderRef')
}
......@@ -389,13 +380,36 @@ function resetQuery() {
handleQuery()
}
function handleDetails(row) {
const _id = row.id || ids.value
// getResources({id: _id}).then(response => {
// form.value = response.data
/**
* 阶段 F:实装详情弹窗
* 1. 调 /compute/order/get 拿主订单数据
* 2. 调 /compute/order/get-delivery-info 拿发货字段(仅 DELIVERED 状态有值)
*/
async function handleDetails(row) {
open.value = true
title.value = '查看订单'
// })
detailLoading.value = true
showPassword.value = false
try {
// 主订单
const mainRes = await getResources({ id: row.id })
form.value = mainRes.data || {}
// 阶段 F:独立拿发货信息(IP/用户名/密码)
try {
const delRes = await getOrderDeliveryInfo(row.id)
const info = delRes.data || {}
form.value.deliveryIp = info.deliveryIp
form.value.deliveryUsername = info.deliveryUsername
form.value.deliveryPassword = info.deliveryPassword
form.value.deliveredTime = info.deliveredTime
form.value.deliverOperatorName = info.deliverOperatorName
} catch (e) {
// 发货信息拿不到不阻塞主流程(订单可能非本人或非 DELIVERED)
console.warn('[getDeliveryInfo] failed', e)
}
} finally {
detailLoading.value = false
}
}
function invoiceRequest(row) {
......@@ -407,6 +421,38 @@ function invoiceRequest(row) {
)
}
/**
* 阶段 F:取消订单 / 申请退款
* - status=0(UNPAID) → 显示"取消订单",文案"确认取消该订单?"
* - status=5(PENDING_DELIVERY) → 显示"申请退款",文案"取消后商家将停止备货,款项将由客服人工退款(1-3 个工作日)"
* 调 PUT /compute/order/cancel?orderId=xxx
*/
async function handleCancelOrder(row) {
if (!row || !row.id) return
const isPendingDelivery = row.status === 5
const confirmText = isPendingDelivery
? '确认取消该订单?取消后商家将停止备货,款项将由客服人工退款(1-3 个工作日)'
: '确认取消该订单?'
try {
// 阶段 F:使用 proxy.$modal.confirm 与项目风格保持一致
await proxy.$modal.confirm(confirmText, isPendingDelivery ? '申请退款' : '取消订单')
} catch {
return
}
try {
await cancelOrder({ orderId: row.id })
proxy.$modal.msgSuccess(isPendingDelivery ? '已取消,等待客服退款' : '已取消')
// 刷新列表
getList()
// 如果详情弹窗打开着,刷新详情
if (open.value && form.value && form.value.id === row.id) {
await handleDetails(row)
}
} catch (e) {
console.error('[cancelOrder] failed', e)
}
}
const pdfDialogVisible = ref(false)
const invoiceUrl = ref('')
......@@ -437,7 +483,18 @@ loadCategories()
.info-block {
background-color: #ffffff;
padding: 4px 0;
//margin-bottom: 14px;
}
.info-block-title {
padding: 8px 20px 4px;
font-weight: 600;
font-size: 14px;
color: #303233;
background-color: #F7F8F9;
}
.refund-banner {
margin: 12px 0;
}
.info-item {
......
......@@ -18,11 +18,20 @@
<span>{{ scope.row.skuName }}</span>
</template>
</el-table-column>
<el-table-column label="订单状态" align="center" prop="status">
<el-table-column label="订单状态" align="center" prop="status" width="100">
<template #default="scope">
<dict-tag :options="compute_resource_order_status" :value="scope.row.status" />
</template>
</el-table-column>
<!-- 阶段 F:倒计时(仅 DELIVERED 显示),剩余 ≤3 天橙色警示 -->
<el-table-column label="剩余时间" align="center" width="140">
<template #default="scope">
<span v-if="scope.row.status === 6" :class="{ 'warn-text': remainingDays(scope.row) <= 3 && remainingDays(scope.row) >= 0 }">
剩余 {{ formatRemaining(scope.row.rentEndTime) }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="申请时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
......@@ -35,7 +44,7 @@
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleUpdate(scope.row,scope.$index)">详情</el-button>
<el-button link type="primary" @click="handleUpdate(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
......@@ -50,8 +59,45 @@
<!-- 添加或修改订单管理-用户资源管理对话框 -->
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
<div>
<div class="info-block">
<div v-loading="detailLoading">
<!-- 阶段 F:状态顶部 el-alert 提示(按 status 分支) -->
<el-alert
v-if="form.status === 6"
type="success"
:closable="false"
show-icon
:title="`资源使用中,租赁结束时间:${parseTime(form.rentEndTime, '{y}-{m}-{d}')}`"
/>
<el-alert
v-else-if="form.status === 4"
type="info"
:closable="false"
show-icon
title="已退款完成"
/>
<el-alert
v-else-if="form.status === 2"
type="info"
:closable="false"
show-icon
title="订单已结束"
/>
<el-alert
v-else-if="form.status === 5"
type="warning"
:closable="false"
show-icon
title="商家备货中,预计 24 小时内发货"
/>
<el-alert
v-else-if="form.status === 7"
type="warning"
:closable="false"
show-icon
title="订单已取消,正在等待客服处理退款"
/>
<div class="info-block" style="margin-top: 12px;">
<div class="info-item flex-align-center flex-space-between">
<div class="label">订单编号</div>
<div class="value">{{ form.orderNo }}</div>
......@@ -71,22 +117,46 @@
<div class="value">-</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器IP</div>
<div class="value">{{ form.ip || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器所在地</div>
<div class="value">{{ form.location || '-' }}</div>
</div>
</div>
<!-- 阶段 F:发货信息区(仅 DELIVERED 状态显示),字段从 getDeliveryInfo -->
<div v-if="form.status === 6" class="info-block">
<div class="info-block-title">发货信息</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器 IP</div>
<div class="value">{{ form.deliveryIp || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器用户名</div>
<div class="value">{{ form.initUsername || '-' }}</div>
<div class="value">{{ form.deliveryUsername || '-' }}</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">服务器密码</div>
<div class="value">{{ form.initPassword || '-' }}</div>
<div class="value">
<span v-if="showPassword">{{ form.deliveryPassword || '-' }}</span>
<el-button v-else link type="primary" @click="showPassword = true">显示密码</el-button>
</div>
</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">发货时间</div>
<div class="value">{{ parseTime(form.deliveredTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</div>
</div>
</div>
<!-- 阶段 F:退款信息(仅 PENDING_REFUND=7 REFUNDED=4 -->
<div v-if="form.status === 7 || form.status === 4" class="info-block">
<div class="info-block-title">退款信息</div>
<div class="info-item flex-align-center flex-space-between">
<div class="label">退款时间</div>
<div class="value">{{ parseTime(form.refundTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</div>
</div>
</div>
<div class="info-block">
<div class="info-item flex-align-center flex-space-between">
<div class="label">租期</div>
<div class="value">{{ form.skuName }}</div>
</div>
......@@ -122,6 +192,7 @@
<script setup name="NaturalResources">
import {listResources, getResources} from '@/api/computility/resources'
import {getOrderDeliveryInfo} from '@/api/computility/order'
import {parseTime} from "../../utils/ruoyi.js";
const {proxy} = getCurrentInstance()
......@@ -130,9 +201,11 @@ const {compute_resource_order_status} = proxy.useDict('compute_resource_order_st
const resourcesList = ref([])
const open = ref(false)
const loading = ref(true)
const detailLoading = ref(false)
const ids = ref([])
const total = ref(0)
const title = ref('')
const showPassword = ref(false) // 阶段 F:密码默认隐藏
const data = reactive({
form: {},
......@@ -159,14 +232,62 @@ function cancel() {
open.value = false
}
/** 修改按钮操作 */
function handleUpdate(row) {
const _id = row.id || ids.value
getResources({id: _id}).then(response => {
form.value = response.data
open.value = true
title.value = '查看详情'
})
/**
* 阶段 F:计算剩余天数(仅 DELIVERED 用到)
* @returns 剩余天数(已过期返回负数;无 rentEndTime 返回 NaN)
*/
function remainingDays(row) {
if (!row || !row.rentEndTime) return NaN
const end = new Date(row.rentEndTime).getTime()
if (isNaN(end)) return NaN
const now = Date.now()
return Math.floor((end - now) / (1000 * 60 * 60 * 24))
}
/**
* 阶段 F:格式化剩余时间为 "X 天 Y 小时"
*/
function formatRemaining(endTime) {
if (!endTime) return '-'
const end = new Date(endTime).getTime()
if (isNaN(end)) return '-'
const diffMs = end - Date.now()
if (diffMs <= 0) return '已到期'
const totalHours = Math.floor(diffMs / (1000 * 60 * 60))
const days = Math.floor(totalHours / 24)
const hours = totalHours % 24
if (days > 0) return `${days} 天 ${hours} 小时`
return `${hours} 小时`
}
/**
* 阶段 F:实装详情弹窗
* 1. 调 /compute/order/get 拿主订单数据
* 2. 调 /compute/order/get-delivery-info 拿发货字段(仅 DELIVERED 状态有值)
*/
async function handleUpdate(row) {
open.value = true
title.value = '查看详情'
showPassword.value = false
detailLoading.value = true
try {
const mainRes = await getResources({ id: row.id })
form.value = mainRes.data || {}
// 阶段 F:独立拿发货信息(IP/用户名/密码)
try {
const delRes = await getOrderDeliveryInfo(row.id)
const info = delRes.data || {}
form.value.deliveryIp = info.deliveryIp
form.value.deliveryUsername = info.deliveryUsername
form.value.deliveryPassword = info.deliveryPassword
form.value.deliveredTime = info.deliveredTime
form.value.deliverOperatorName = info.deliverOperatorName
} catch (e) {
console.warn('[getDeliveryInfo] failed', e)
}
} finally {
detailLoading.value = false
}
}
getList()
......@@ -191,7 +312,14 @@ getList()
.info-block {
background-color: #ffffff;
padding: 4px 0;
//margin-bottom: 14px;
}
.info-block-title {
padding: 8px 20px 4px;
font-weight: 600;
font-size: 14px;
color: #303233;
background-color: #F7F8F9;
}
.info-item {
......@@ -225,4 +353,10 @@ getList()
color: #303233;
font-weight: 500;
}
/* 阶段 F:剩余时间 ≤ 3 天橙色警示 */
.warn-text {
color: #E6A23C;
font-weight: 600;
}
</style>
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 sign in to comment