This commit is contained in:
44
src/components/business/OperationLogsDialog.vue
Normal file
44
src/components/business/OperationLogsDialog.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<ElDrawer
|
||||
v-model="dialogVisible"
|
||||
title="操作审计日志"
|
||||
direction="rtl"
|
||||
size="60%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<OperationLogsCard :asset-identifier="identifier" />
|
||||
</ElDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { ElDrawer } from 'element-plus'
|
||||
import OperationLogsCard from '@/views/asset-management/asset-information/components/OperationLogsCard.vue'
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
identifier?: string
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
}>()
|
||||
|
||||
const dialogVisible = ref(props.modelValue)
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
dialogVisible.value = val
|
||||
}
|
||||
)
|
||||
|
||||
watch(dialogVisible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
1
src/types/components.d.ts
vendored
1
src/types/components.d.ts
vendored
@@ -137,6 +137,7 @@ declare module 'vue' {
|
||||
LoginLeftView: typeof import('./../components/core/views/login/LoginLeftView.vue')['default']
|
||||
MenuLayoutSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/MenuLayoutSettings.vue')['default']
|
||||
MenuStyleSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/MenuStyleSettings.vue')['default']
|
||||
OperationLogsDialog: typeof import('./../components/business/OperationLogsDialog.vue')['default']
|
||||
OperatorSelect: typeof import('./../components/business/OperatorSelect.vue')['default']
|
||||
PackageSelector: typeof import('./../components/business/PackageSelector.vue')['default']
|
||||
PaymentVoucherDialog: typeof import('./../components/business/PaymentVoucherDialog.vue')['default']
|
||||
|
||||
@@ -107,7 +107,7 @@ export function useAssetInfo() {
|
||||
packageSeries: data.series_name || '-',
|
||||
packageTotalFlow: formatDataSize(data.package_total_mb || 0),
|
||||
usedFlow: formatDataSize(data.package_used_mb || 0),
|
||||
remainFlow: formatDataSize(data.package_remain_mb || 0),
|
||||
remainFlow: formatDataSize((data.package_total_mb || 0) - (data.package_used_mb || 0)),
|
||||
usedFlowPercentage:
|
||||
data.package_total_mb > 0
|
||||
? `${((data.package_used_mb / data.package_total_mb) * 100).toFixed(2)}%`
|
||||
|
||||
@@ -490,6 +490,12 @@
|
||||
:current-policy="currentRealnamePolicy"
|
||||
@confirm="handleConfirmRealnamePolicy"
|
||||
/>
|
||||
|
||||
<!-- 操作审计日志弹窗 -->
|
||||
<OperationLogsDialog
|
||||
v-model="operationLogsDialogVisible"
|
||||
:identifier="operationLogsIdentifier"
|
||||
/>
|
||||
</ElCard>
|
||||
</div>
|
||||
</ArtTableFullScreen>
|
||||
@@ -525,6 +531,7 @@
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import type { PackageSeriesResponse } from '@/types/api'
|
||||
import RealnamePolicyDialog from '@/components/device/RealnamePolicyDialog.vue'
|
||||
import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
|
||||
|
||||
defineOptions({ name: 'DeviceList' })
|
||||
|
||||
@@ -540,6 +547,8 @@
|
||||
const allocateDialogVisible = ref(false)
|
||||
const recallDialogVisible = ref(false)
|
||||
const selectedDevices = ref<Device[]>([])
|
||||
const operationLogsDialogVisible = ref(false)
|
||||
const operationLogsIdentifier = ref('')
|
||||
const shopCascadeOptions = ref<any[]>([])
|
||||
const shopCascadeProps = {
|
||||
lazy: true,
|
||||
@@ -1965,6 +1974,17 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (hasAuth('device:operation_logs')) {
|
||||
moreActions.push({
|
||||
label: '操作审计日志',
|
||||
handler: () => {
|
||||
operationLogsIdentifier.value = row.virtual_no
|
||||
operationLogsDialogVisible.value = true
|
||||
},
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
|
||||
// 如果有更多操作,添加到 actions 中
|
||||
if (moreActions.length > 0) {
|
||||
actions.push(...moreActions)
|
||||
|
||||
@@ -42,19 +42,7 @@
|
||||
>
|
||||
批量设置套餐系列
|
||||
</ElButton>
|
||||
<ElButton
|
||||
v-if="
|
||||
hasAuth('iot_card:batch_recharge') ||
|
||||
hasAuth('iot_card:network_distribution') ||
|
||||
hasAuth('iot_card:network_recycle') ||
|
||||
hasAuth('iot_card:change_package') ||
|
||||
hasAuth('iot_card:batch_download')
|
||||
"
|
||||
type="info"
|
||||
@click="showMoreMenuOnClick"
|
||||
>
|
||||
更多操作
|
||||
</ElButton>
|
||||
|
||||
</template>
|
||||
</ArtTableHeader>
|
||||
|
||||
@@ -508,92 +496,6 @@
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 流量使用查询对话框 -->
|
||||
<ElDialog v-model="flowUsageDialogVisible" title="流量使用查询" width="500px">
|
||||
<div v-if="flowUsageLoading" style="padding: 40px; text-align: center">
|
||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||
<div style="margin-top: 16px">查询中...</div>
|
||||
</div>
|
||||
|
||||
<ElDescriptions v-else-if="flowUsageData" :column="1" border>
|
||||
<ElDescriptionsItem label="套餐总流量"
|
||||
>{{ flowUsageData.totalFlow || 0 }} MB</ElDescriptionsItem
|
||||
>
|
||||
<ElDescriptionsItem label="已用流量"
|
||||
>{{ flowUsageData.usedFlow || 0 }} MB</ElDescriptionsItem
|
||||
>
|
||||
<ElDescriptionsItem label="剩余流量"
|
||||
>{{ flowUsageData.remainFlow || 0 }} MB</ElDescriptionsItem
|
||||
>
|
||||
<ElDescriptionsItem v-if="flowUsageData.extend" label="扩展信息">{{
|
||||
flowUsageData.extend
|
||||
}}</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton type="primary" @click="flowUsageDialogVisible = false">关闭</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 实名状态查询对话框 -->
|
||||
<ElDialog v-model="realnameStatusDialogVisible" title="实名认证状态" width="500px">
|
||||
<div v-if="realnameStatusLoading" style="padding: 40px; text-align: center">
|
||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||
<div style="margin-top: 16px">查询中...</div>
|
||||
</div>
|
||||
|
||||
<ElDescriptions v-else-if="realnameStatusData" :column="1" border>
|
||||
<ElDescriptionsItem label="实名状态">{{
|
||||
realnameStatusData.status || '未知'
|
||||
}}</ElDescriptionsItem>
|
||||
<ElDescriptionsItem v-if="realnameStatusData.extend" label="扩展信息">{{
|
||||
realnameStatusData.extend
|
||||
}}</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton type="primary" @click="realnameStatusDialogVisible = false">关闭</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 卡实时状态查询对话框 -->
|
||||
<ElDialog v-model="cardStatusDialogVisible" title="卡实时状态" width="500px">
|
||||
<div v-if="cardStatusLoading" style="padding: 40px; text-align: center">
|
||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||
<div style="margin-top: 16px">查询中...</div>
|
||||
</div>
|
||||
|
||||
<ElDescriptions v-else-if="cardStatusData" :column="1" border>
|
||||
<ElDescriptionsItem label="ICCID">{{
|
||||
cardStatusData.iccid || '--'
|
||||
}}</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="卡状态">{{
|
||||
cardStatusData.cardStatus || '未知'
|
||||
}}</ElDescriptionsItem>
|
||||
<ElDescriptionsItem v-if="cardStatusData.extend" label="扩展信息">{{
|
||||
cardStatusData.extend
|
||||
}}</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton type="primary" @click="cardStatusDialogVisible = false">关闭</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 更多操作右键菜单 -->
|
||||
<ArtMenuRight
|
||||
ref="moreMenuRef"
|
||||
:menu-items="moreMenuItems"
|
||||
:menu-width="180"
|
||||
@select="handleMoreMenuSelect"
|
||||
/>
|
||||
|
||||
<!-- 实名认证策略对话框 -->
|
||||
<RealnamePolicyDialog
|
||||
v-model="realnamePolicyDialogVisible"
|
||||
@@ -609,6 +511,12 @@
|
||||
:current-realname-status="currentUpdateRealnameStatus"
|
||||
@success="handleUpdateRealnameStatusSuccess"
|
||||
/>
|
||||
|
||||
<!-- 操作审计日志弹窗 -->
|
||||
<OperationLogsDialog
|
||||
v-model="operationLogsDialogVisible"
|
||||
:identifier="operationLogsIdentifier"
|
||||
/>
|
||||
</ElCard>
|
||||
</div>
|
||||
</ArtTableFullScreen>
|
||||
@@ -636,8 +544,6 @@
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
|
||||
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
|
||||
import type {
|
||||
StandaloneIotCard,
|
||||
StandaloneCardStatus,
|
||||
@@ -648,6 +554,7 @@
|
||||
} from '@/types/api/card'
|
||||
import { CardSelectionType } from '@/types/api/card'
|
||||
import type { PackageSeriesResponse } from '@/types/api'
|
||||
import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
|
||||
|
||||
defineOptions({ name: 'StandaloneCardList' })
|
||||
|
||||
@@ -675,6 +582,10 @@
|
||||
failed_items: null
|
||||
})
|
||||
|
||||
// 操作审计日志弹窗
|
||||
const operationLogsDialogVisible = ref(false)
|
||||
const operationLogsIdentifier = ref('')
|
||||
|
||||
// 套餐系列绑定相关
|
||||
const seriesBindingDialogVisible = ref(false)
|
||||
const seriesBindingLoading = ref(false)
|
||||
@@ -821,17 +732,6 @@
|
||||
const currentCardDetail = ref<any>(null)
|
||||
|
||||
// IoT卡操作相关对话框
|
||||
const flowUsageDialogVisible = ref(false)
|
||||
const flowUsageLoading = ref(false)
|
||||
const flowUsageData = ref<any>(null)
|
||||
|
||||
const realnameStatusDialogVisible = ref(false)
|
||||
const realnameStatusLoading = ref(false)
|
||||
const realnameStatusData = ref<any>(null)
|
||||
|
||||
const cardStatusDialogVisible = ref(false)
|
||||
const cardStatusLoading = ref(false)
|
||||
const cardStatusData = ref<any>(null)
|
||||
|
||||
// 实名认证策略对话框
|
||||
const realnamePolicyDialogVisible = ref(false)
|
||||
@@ -898,9 +798,6 @@
|
||||
await getTableData()
|
||||
}
|
||||
|
||||
// 更多操作右键菜单
|
||||
const moreMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
|
||||
|
||||
// 店铺相关
|
||||
const shopCascadeOptions = ref<any[]>([])
|
||||
const shopCascadeProps = {
|
||||
@@ -1556,6 +1453,17 @@
|
||||
})
|
||||
}
|
||||
|
||||
if (hasAuth('iot_card:operation_logs')) {
|
||||
actions.push({
|
||||
label: '操作审计日志',
|
||||
handler: () => {
|
||||
operationLogsIdentifier.value = row.iccid
|
||||
operationLogsDialogVisible.value = true
|
||||
},
|
||||
type: 'primary'
|
||||
})
|
||||
}
|
||||
|
||||
return actions
|
||||
}
|
||||
|
||||
@@ -1906,59 +1814,6 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 更多操作菜单项配置
|
||||
const moreMenuItems = computed((): MenuItemType[] => {
|
||||
const items: MenuItemType[] = []
|
||||
|
||||
if (hasAuth('iot_card:batch_download')) {
|
||||
items.push({
|
||||
key: 'download',
|
||||
label: '批量下载'
|
||||
})
|
||||
}
|
||||
|
||||
if (hasAuth('iot_card:change_package')) {
|
||||
items.push({
|
||||
key: 'changePackage',
|
||||
label: '其他功能暂定'
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
// 卡操作菜单项配置
|
||||
|
||||
// 显示更多操作菜单 (左键点击)
|
||||
const showMoreMenuOnClick = (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
moreMenuRef.value?.show(e)
|
||||
}
|
||||
|
||||
// 处理更多操作菜单选择
|
||||
const handleMoreMenuSelect = (item: MenuItemType) => {
|
||||
switch (item.key) {
|
||||
case 'distribution':
|
||||
cardDistribution()
|
||||
break
|
||||
case 'recharge':
|
||||
batchRecharge()
|
||||
break
|
||||
case 'recycle':
|
||||
cardRecycle()
|
||||
break
|
||||
case 'download':
|
||||
batchDownload()
|
||||
break
|
||||
case 'changePackage':
|
||||
changePackage()
|
||||
break
|
||||
case 'clearSeries':
|
||||
handleClearCardSeries()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 清除卡套餐系列绑定
|
||||
const handleClearCardSeries = async () => {
|
||||
if (selectedCards.value.length === 0) {
|
||||
@@ -1999,31 +1854,6 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 网卡分销 - 正在开发中
|
||||
const cardDistribution = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 批量充值 - 正在开发中
|
||||
const batchRecharge = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 网卡回收 - 正在开发中
|
||||
const cardRecycle = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 批量下载 - 正在开发中
|
||||
const batchDownload = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// 变更套餐 - 正在开发中
|
||||
const changePackage = () => {
|
||||
ElMessage.info('功能正在开发中')
|
||||
}
|
||||
|
||||
// IoT卡操作处理函数
|
||||
const handleCardOperation = (command: string, iccid: string, row?: any) => {
|
||||
switch (command) {
|
||||
|
||||
Reference in New Issue
Block a user