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']
|
LoginLeftView: typeof import('./../components/core/views/login/LoginLeftView.vue')['default']
|
||||||
MenuLayoutSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/MenuLayoutSettings.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']
|
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']
|
OperatorSelect: typeof import('./../components/business/OperatorSelect.vue')['default']
|
||||||
PackageSelector: typeof import('./../components/business/PackageSelector.vue')['default']
|
PackageSelector: typeof import('./../components/business/PackageSelector.vue')['default']
|
||||||
PaymentVoucherDialog: typeof import('./../components/business/PaymentVoucherDialog.vue')['default']
|
PaymentVoucherDialog: typeof import('./../components/business/PaymentVoucherDialog.vue')['default']
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export function useAssetInfo() {
|
|||||||
packageSeries: data.series_name || '-',
|
packageSeries: data.series_name || '-',
|
||||||
packageTotalFlow: formatDataSize(data.package_total_mb || 0),
|
packageTotalFlow: formatDataSize(data.package_total_mb || 0),
|
||||||
usedFlow: formatDataSize(data.package_used_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:
|
usedFlowPercentage:
|
||||||
data.package_total_mb > 0
|
data.package_total_mb > 0
|
||||||
? `${((data.package_used_mb / data.package_total_mb) * 100).toFixed(2)}%`
|
? `${((data.package_used_mb / data.package_total_mb) * 100).toFixed(2)}%`
|
||||||
|
|||||||
@@ -490,6 +490,12 @@
|
|||||||
:current-policy="currentRealnamePolicy"
|
:current-policy="currentRealnamePolicy"
|
||||||
@confirm="handleConfirmRealnamePolicy"
|
@confirm="handleConfirmRealnamePolicy"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 操作审计日志弹窗 -->
|
||||||
|
<OperationLogsDialog
|
||||||
|
v-model="operationLogsDialogVisible"
|
||||||
|
:identifier="operationLogsIdentifier"
|
||||||
|
/>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
</div>
|
</div>
|
||||||
</ArtTableFullScreen>
|
</ArtTableFullScreen>
|
||||||
@@ -525,6 +531,7 @@
|
|||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import type { PackageSeriesResponse } from '@/types/api'
|
import type { PackageSeriesResponse } from '@/types/api'
|
||||||
import RealnamePolicyDialog from '@/components/device/RealnamePolicyDialog.vue'
|
import RealnamePolicyDialog from '@/components/device/RealnamePolicyDialog.vue'
|
||||||
|
import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'DeviceList' })
|
defineOptions({ name: 'DeviceList' })
|
||||||
|
|
||||||
@@ -540,6 +547,8 @@
|
|||||||
const allocateDialogVisible = ref(false)
|
const allocateDialogVisible = ref(false)
|
||||||
const recallDialogVisible = ref(false)
|
const recallDialogVisible = ref(false)
|
||||||
const selectedDevices = ref<Device[]>([])
|
const selectedDevices = ref<Device[]>([])
|
||||||
|
const operationLogsDialogVisible = ref(false)
|
||||||
|
const operationLogsIdentifier = ref('')
|
||||||
const shopCascadeOptions = ref<any[]>([])
|
const shopCascadeOptions = ref<any[]>([])
|
||||||
const shopCascadeProps = {
|
const shopCascadeProps = {
|
||||||
lazy: true,
|
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 中
|
// 如果有更多操作,添加到 actions 中
|
||||||
if (moreActions.length > 0) {
|
if (moreActions.length > 0) {
|
||||||
actions.push(...moreActions)
|
actions.push(...moreActions)
|
||||||
|
|||||||
@@ -42,19 +42,7 @@
|
|||||||
>
|
>
|
||||||
批量设置套餐系列
|
批量设置套餐系列
|
||||||
</ElButton>
|
</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>
|
</template>
|
||||||
</ArtTableHeader>
|
</ArtTableHeader>
|
||||||
|
|
||||||
@@ -508,92 +496,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</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
|
<RealnamePolicyDialog
|
||||||
v-model="realnamePolicyDialogVisible"
|
v-model="realnamePolicyDialogVisible"
|
||||||
@@ -609,6 +511,12 @@
|
|||||||
:current-realname-status="currentUpdateRealnameStatus"
|
:current-realname-status="currentUpdateRealnameStatus"
|
||||||
@success="handleUpdateRealnameStatusSuccess"
|
@success="handleUpdateRealnameStatusSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 操作审计日志弹窗 -->
|
||||||
|
<OperationLogsDialog
|
||||||
|
v-model="operationLogsDialogVisible"
|
||||||
|
:identifier="operationLogsIdentifier"
|
||||||
|
/>
|
||||||
</ElCard>
|
</ElCard>
|
||||||
</div>
|
</div>
|
||||||
</ArtTableFullScreen>
|
</ArtTableFullScreen>
|
||||||
@@ -636,8 +544,6 @@
|
|||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
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 {
|
import type {
|
||||||
StandaloneIotCard,
|
StandaloneIotCard,
|
||||||
StandaloneCardStatus,
|
StandaloneCardStatus,
|
||||||
@@ -648,6 +554,7 @@
|
|||||||
} from '@/types/api/card'
|
} from '@/types/api/card'
|
||||||
import { CardSelectionType } from '@/types/api/card'
|
import { CardSelectionType } from '@/types/api/card'
|
||||||
import type { PackageSeriesResponse } from '@/types/api'
|
import type { PackageSeriesResponse } from '@/types/api'
|
||||||
|
import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'StandaloneCardList' })
|
defineOptions({ name: 'StandaloneCardList' })
|
||||||
|
|
||||||
@@ -675,6 +582,10 @@
|
|||||||
failed_items: null
|
failed_items: null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 操作审计日志弹窗
|
||||||
|
const operationLogsDialogVisible = ref(false)
|
||||||
|
const operationLogsIdentifier = ref('')
|
||||||
|
|
||||||
// 套餐系列绑定相关
|
// 套餐系列绑定相关
|
||||||
const seriesBindingDialogVisible = ref(false)
|
const seriesBindingDialogVisible = ref(false)
|
||||||
const seriesBindingLoading = ref(false)
|
const seriesBindingLoading = ref(false)
|
||||||
@@ -821,17 +732,6 @@
|
|||||||
const currentCardDetail = ref<any>(null)
|
const currentCardDetail = ref<any>(null)
|
||||||
|
|
||||||
// IoT卡操作相关对话框
|
// 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)
|
const realnamePolicyDialogVisible = ref(false)
|
||||||
@@ -898,9 +798,6 @@
|
|||||||
await getTableData()
|
await getTableData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更多操作右键菜单
|
|
||||||
const moreMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
|
|
||||||
|
|
||||||
// 店铺相关
|
// 店铺相关
|
||||||
const shopCascadeOptions = ref<any[]>([])
|
const shopCascadeOptions = ref<any[]>([])
|
||||||
const shopCascadeProps = {
|
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
|
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 () => {
|
const handleClearCardSeries = async () => {
|
||||||
if (selectedCards.value.length === 0) {
|
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卡操作处理函数
|
// IoT卡操作处理函数
|
||||||
const handleCardOperation = (command: string, iccid: string, row?: any) => {
|
const handleCardOperation = (command: string, iccid: string, row?: any) => {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|||||||
Reference in New Issue
Block a user