修改订单管理
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 2m28s

This commit is contained in:
sexygoat
2026-02-28 16:49:28 +08:00
parent ce1032c7f9
commit 7b459b5c8d
6 changed files with 219 additions and 21 deletions

View File

@@ -4,7 +4,13 @@
<Transition name="context-menu" @before-enter="onBeforeEnter" @after-leave="onAfterLeave">
<div v-show="visible" :style="menuStyle" class="context-menu">
<ul class="menu-list" :style="menuListStyle">
<template v-for="item in menuItems" :key="item.key">
<!-- 无权限提示 -->
<li v-if="menuItems.length === 0" class="menu-item no-permission" :style="menuItemStyle">
<span class="menu-label">您暂无更多权限</span>
</li>
<!-- 菜单项 -->
<template v-else v-for="item in menuItems" :key="item.key">
<!-- 普通菜单项 -->
<li
v-if="!item.children"
@@ -249,10 +255,23 @@
user-select: none;
transition: background-color 0.15s ease;
&:hover:not(.is-disabled) {
&:hover:not(.is-disabled):not(.no-permission) {
background-color: rgba(var(--art-gray-200-rgb), 0.7);
}
&.no-permission {
justify-content: center;
color: var(--el-text-color-secondary);
cursor: default;
.menu-label {
color: var(--el-text-color-secondary);
text-align: center;
white-space: normal;
word-break: break-all;
}
}
&.has-line {
margin-bottom: 10px;

View File

@@ -36,11 +36,18 @@
@refresh="handleRefresh"
>
<template #left>
<ElButton type="primary" @click="showAllocateDialog">授权卡</ElButton>
<ElButton
type="primary"
@click="showAllocateDialog"
v-permission="'enterprise_cards:allocate'"
>
授权卡
</ElButton>
<ElButton
type="warning"
:disabled="selectedCards.length === 0"
@click="showRecallDialog"
v-permission="'enterprise_cards:batch_recall'"
>
批量回收
</ElButton>
@@ -215,6 +222,7 @@
import type { FormInstance, FormRules } from 'element-plus'
import type { SearchFormItem } from '@/types'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { formatDateTime } from '@/utils/business/format'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
import { BgColorEnum } from '@/enums/appEnum'
@@ -228,6 +236,8 @@
defineOptions({ name: 'EnterpriseCards' })
const { hasAuth } = useAuth()
const route = useRoute()
const router = useRouter()
const loading = ref(false)
@@ -537,19 +547,33 @@
width: 100,
fixed: 'right',
formatter: (row: EnterpriseCardItem) => {
return h('div', { style: 'display: flex; gap: 8px;' }, [
row.network_status === 0
? h(ArtButtonTable, {
const buttons = []
if (row.network_status === 0) {
// 停机状态,显示复机按钮
if (hasAuth('enterprise_cards:resume')) {
buttons.push(
h(ArtButtonTable, {
text: '复机',
iconClass: BgColorEnum.SUCCESS,
onClick: () => handleResume(row)
})
: h(ArtButtonTable, {
)
}
} else {
// 开机状态,显示停机按钮
if (hasAuth('enterprise_cards:suspend')) {
buttons.push(
h(ArtButtonTable, {
text: '停机',
iconClass: BgColorEnum.ERROR,
onClick: () => handleSuspend(row)
})
])
)
}
}
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
}
}
])

View File

@@ -67,8 +67,14 @@
<p>1. 请先下载 Excel 模板文件按照模板格式填写设备信息</p>
<p>2. 仅支持 Excel 格式.xlsx单次最多导入 1000 </p>
<p>3. 列格式请设置为文本格式避免长数字被转为科学计数法</p>
<p>4. 必填列device_no设备号device_name设备名称device_model设备型号device_type设备类型</p>
<p>5. 可选列manufacturer制造商max_sim_slots最大插槽数默认4iccid_1 ~ iccid_4绑定的卡ICCID</p>
<p
>4.
必填列device_no设备号device_name设备名称device_model设备型号device_type设备类型</p
>
<p
>5. 可选列manufacturer制造商max_sim_slots最大插槽数默认4iccid_1 ~
iccid_4绑定的卡ICCID</p
>
</div>
</template>
</ElAlert>
@@ -106,7 +112,6 @@
</ElButton>
</template>
</ElDialog>
</ArtTableFullScreen>
</template>
@@ -353,7 +358,6 @@
}
} catch (error) {
console.error(error)
ElMessage.error('获取设备任务列表失败')
} finally {
loading.value = false
}
@@ -437,7 +441,7 @@
{ wch: 22 }, // iccid_1
{ wch: 22 }, // iccid_2
{ wch: 22 }, // iccid_3
{ wch: 22 } // iccid_4
{ wch: 22 } // iccid_4
]
// 将所有单元格设置为文本格式
@@ -520,7 +524,11 @@
const { upload_url, file_key } = uploadUrlRes.data
ElMessage.info('正在上传文件...')
await StorageService.uploadFile(upload_url, file, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
await StorageService.uploadFile(
upload_url,
file,
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
ElMessage.info('正在创建导入任务...')
const importRes = await DeviceService.importDevices({

View File

@@ -399,7 +399,6 @@
}
} catch (error) {
console.error(error)
ElMessage.error('获取IoT卡任务列表失败')
} finally {
loading.value = false
}

View File

@@ -106,6 +106,17 @@
return statusMap[status] || '-'
}
// 获取订单角色文本
const getPurchaseRoleText = (role: string): string => {
const roleMap: Record<string, string> = {
self_purchase: '自己购买',
purchased_by_parent: '上级代理购买',
purchased_by_platform: '平台代购',
purchase_for_subordinate: '给下级购买'
}
return roleMap[role] || role
}
// 详情页配置
const detailSections: DetailSection[] = [
{
@@ -125,6 +136,11 @@
prop: 'total_amount',
formatter: (value) => formatCurrency(value)
},
{
label: '实付金额',
prop: 'actual_paid_amount',
formatter: (value) => (value !== undefined && value !== null ? formatCurrency(value) : '-')
},
{
label: 'IoT卡ID',
prop: 'iot_card_id',
@@ -132,7 +148,7 @@
},
{
label: t('orderManagement.table.buyerType'),
formatter: (_, data) => data.buyer_type ? getBuyerTypeText(data.buyer_type) : '-'
formatter: (_, data) => (data.buyer_type ? getBuyerTypeText(data.buyer_type) : '-')
},
{
label: '买家ID',
@@ -140,8 +156,32 @@
formatter: (value) => value || '-'
},
{
label: '代付订单',
formatter: (_, data) => data.is_purchase_on_behalf ? '是' : '否'
label: '订单角色',
formatter: (_, data) => (data.purchase_role ? getPurchaseRoleText(data.purchase_role) : '-')
},
{
label: '购买备注',
prop: 'purchase_remark',
formatter: (value) => value || '-'
},
{
label: '是否上级代购',
formatter: (_, data) => (data.is_purchased_by_parent ? '是' : '否')
},
{
label: '操作者ID',
prop: 'operator_id',
formatter: (value) => value || '-'
},
{
label: '操作者类型',
prop: 'operator_type',
formatter: (value) => value || '-'
},
{
label: '操作者名称',
prop: 'operator_name',
formatter: (value) => value || '-'
},
{
label: t('orderManagement.table.commissionStatus'),

View File

@@ -164,6 +164,24 @@
</ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem label="支付方式" prop="payment_method">
<ElSelect
v-model="createForm.payment_method"
placeholder="请选择支付方式"
style="width: 100%"
>
<ElOption label="钱包支付" value="wallet" />
<ElOption label="线下支付" value="offline" />
</ElSelect>
<div style="margin-top: 8px; font-size: 12px; color: var(--el-text-color-secondary)">
<template v-if="createForm.payment_method === 'wallet'">
提示: 使用钱包支付时,订单将直接完成
</template>
<template v-else-if="createForm.payment_method === 'offline'">
提示: 线下支付订单需要手动确认支付
</template>
</div>
</ElFormItem>
</ElForm>
<template #footer>
<div class="dialog-footer">
@@ -319,6 +337,7 @@
order_no: '',
payment_status: undefined,
order_type: undefined,
purchase_role: undefined,
start_time: '',
end_time: ''
}
@@ -326,6 +345,17 @@
// 搜索表单
const searchForm = reactive<OrderQueryParams>({ ...initialSearchState })
// 获取订单角色文本
const getPurchaseRoleText = (role: string): string => {
const roleMap: Record<string, string> = {
self_purchase: '自己购买',
purchased_by_parent: '上级代理购买',
purchased_by_platform: '平台代购',
purchase_for_subordinate: '给下级购买'
}
return roleMap[role] || role
}
// 搜索表单配置
const searchFormItems: SearchFormItem[] = [
{
@@ -365,6 +395,21 @@
clearable: true
}
},
{
label: '订单角色',
prop: 'purchase_role',
type: 'select',
placeholder: '请选择订单角色',
options: [
{ label: '自己购买', value: 'self_purchase' },
{ label: '上级代理购买', value: 'purchased_by_parent' },
{ label: '平台代购', value: 'purchased_by_platform' },
{ label: '给下级购买', value: 'purchase_for_subordinate' }
],
config: {
clearable: true
}
},
{
label: t('orderManagement.searchForm.dateRange'),
prop: 'dateRange',
@@ -391,8 +436,12 @@
{ label: t('orderManagement.table.orderNo'), prop: 'order_no' },
{ label: t('orderManagement.table.orderType'), prop: 'order_type' },
{ label: t('orderManagement.table.buyerType'), prop: 'buyer_type' },
{ label: '订单角色', prop: 'purchase_role' },
{ label: '购买备注', prop: 'purchase_remark' },
{ label: '操作者', prop: 'operator_name' },
{ label: t('orderManagement.table.paymentStatus'), prop: 'payment_status' },
{ label: t('orderManagement.table.totalAmount'), prop: 'total_amount' },
{ label: '实付金额', prop: 'actual_paid_amount' },
{ label: t('orderManagement.table.paymentMethod'), prop: 'payment_method' },
{ label: t('orderManagement.table.paidAt'), prop: 'paid_at' },
{ label: t('orderManagement.table.createdAt'), prop: 'created_at' }
@@ -414,6 +463,13 @@
message: t('orderManagement.validation.packageIdsRequired'),
trigger: 'change'
}
],
payment_method: [
{
required: true,
message: '请选择支付方式',
trigger: 'change'
}
]
})
@@ -421,7 +477,8 @@
order_type: 'single_card',
package_ids: [],
iot_card_id: null,
device_id: null
device_id: null,
payment_method: 'wallet' // 默认使用钱包支付
})
const orderList = ref<Order[]>([])
@@ -604,6 +661,38 @@
)
}
},
{
prop: 'purchase_role',
label: '订单角色',
width: 140,
formatter: (row: Order) => {
if (!row.purchase_role) return '-'
const roleTypeMap: Record<string, 'success' | 'info' | 'warning' | 'danger'> = {
self_purchase: 'success',
purchased_by_parent: 'warning',
purchased_by_platform: 'danger',
purchase_for_subordinate: 'info'
}
return h(
ElTag,
{ type: roleTypeMap[row.purchase_role] || 'info', size: 'small' },
() => getPurchaseRoleText(row.purchase_role)
)
}
},
{
prop: 'purchase_remark',
label: '购买备注',
minWidth: 180,
showOverflowTooltip: true,
formatter: (row: Order) => row.purchase_remark || '-'
},
{
prop: 'operator_name',
label: '操作者',
width: 120,
formatter: (row: Order) => row.operator_name || '-'
},
{
prop: 'payment_status',
label: t('orderManagement.table.paymentStatus'),
@@ -622,6 +711,15 @@
width: 120,
formatter: (row: Order) => formatCurrency(row.total_amount)
},
{
prop: 'actual_paid_amount',
label: '实付金额',
width: 120,
formatter: (row: Order) => {
if (row.actual_paid_amount === undefined || row.actual_paid_amount === null) return '-'
return formatCurrency(row.actual_paid_amount)
}
},
{
prop: 'payment_method',
label: t('orderManagement.table.paymentMethod'),
@@ -692,6 +790,7 @@
order_no: searchForm.order_no || undefined,
payment_status: searchForm.payment_status,
order_type: searchForm.order_type,
purchase_role: searchForm.purchase_role,
start_time: searchForm.start_time || undefined,
end_time: searchForm.end_time || undefined
}
@@ -821,6 +920,7 @@
createForm.package_ids = []
createForm.iot_card_id = null
createForm.device_id = null
createForm.payment_method = 'wallet'
// 清空套餐、IoT卡和设备搜索结果
packageOptions.value = []
@@ -840,11 +940,19 @@
order_type: createForm.order_type,
package_ids: createForm.package_ids,
iot_card_id: createForm.order_type === 'single_card' ? createForm.iot_card_id : null,
device_id: createForm.order_type === 'device' ? createForm.device_id : null
device_id: createForm.order_type === 'device' ? createForm.device_id : null,
payment_method: createForm.payment_method // 必填字段
}
await OrderService.createOrder(data)
ElMessage.success(t('orderManagement.messages.createSuccess'))
// 根据支付方式显示不同的成功消息
if (createForm.payment_method === 'wallet') {
ElMessage.success('订单创建成功,已自动完成支付')
} else {
ElMessage.success(t('orderManagement.messages.createSuccess'))
}
createDialogVisible.value = false
formEl.resetFields()
await getTableData()