This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
@@ -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(最大插槽数,默认4)、iccid_1 ~ iccid_4(绑定的卡ICCID)</p>
|
||||
<p
|
||||
>4.
|
||||
必填列:device_no(设备号)、device_name(设备名称)、device_model(设备型号)、device_type(设备类型)</p
|
||||
>
|
||||
<p
|
||||
>5. 可选列:manufacturer(制造商)、max_sim_slots(最大插槽数,默认4)、iccid_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
|
||||
}
|
||||
@@ -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({
|
||||
|
||||
@@ -399,7 +399,6 @@
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
ElMessage.error('获取IoT卡任务列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
// 根据支付方式显示不同的成功消息
|
||||
if (createForm.payment_method === 'wallet') {
|
||||
ElMessage.success('订单创建成功,已自动完成支付')
|
||||
} else {
|
||||
ElMessage.success(t('orderManagement.messages.createSuccess'))
|
||||
}
|
||||
|
||||
createDialogVisible.value = false
|
||||
formEl.resetFields()
|
||||
await getTableData()
|
||||
|
||||
Reference in New Issue
Block a user