fix: update some files
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m7s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m7s
This commit is contained in:
@@ -72,19 +72,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog {
|
.el-dialog {
|
||||||
border-radius: 100px !important;
|
border-radius: 12px !important;
|
||||||
border-radius: calc(var(--custom-radius) / 1.2 + 2px) !important;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog__header {
|
.el-dialog__header {
|
||||||
|
padding: 20px 24px 16px !important;
|
||||||
|
margin-right: 0 !important;
|
||||||
|
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||||
|
|
||||||
.el-dialog__title {
|
.el-dialog__title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-dialog__body {
|
.el-dialog__body {
|
||||||
padding: 25px 0 !important;
|
padding: 20px 24px !important;
|
||||||
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative,不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
|
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative,不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
title="手动更新卡实名状态"
|
title="手动更新卡实名状态"
|
||||||
width="400px"
|
width="400px"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
@closed="handleDialogClosed"
|
@closed="handleDialogClosed"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="formData" :rules="formRules" label-width="100px">
|
<ElForm ref="formRef" :model="formData" :rules="formRules" label-width="100px">
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="设置实名认证策略" width="35%">
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="设置实名认证策略"
|
||||||
|
width="35%"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElFormItem label="资产标识">
|
<ElFormItem label="资产标识">
|
||||||
<span style="font-weight: bold; color: #409eff">{{ assetIdentifier }}</span>
|
<span style="font-weight: bold; color: #409eff">{{ assetIdentifier }}</span>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="切换SIM卡" width="600px" @close="handleClose">
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="切换SIM卡"
|
||||||
|
width="600px"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
<div v-if="loading" style="padding: 40px; text-align: center">
|
<div v-if="loading" style="padding: 40px; text-align: center">
|
||||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||||
<div style="margin-top: 16px">加载设备绑定的卡列表中...</div>
|
<div style="margin-top: 16px">加载设备绑定的卡列表中...</div>
|
||||||
|
|||||||
120
src/types/components.d.ts
vendored
120
src/types/components.d.ts
vendored
@@ -0,0 +1,120 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
AgentSelector: typeof import('./../components/business/AgentSelector.vue')['default']
|
||||||
|
ArtBackToTop: typeof import('./../components/core/base/ArtBackToTop.vue')['default']
|
||||||
|
ArtBarChart: typeof import('./../components/core/charts/ArtBarChart.vue')['default']
|
||||||
|
ArtBarChartCard: typeof import('./../components/core/cards/ArtBarChartCard.vue')['default']
|
||||||
|
ArtBasicBanner: typeof import('./../components/core/banners/ArtBasicBanner.vue')['default']
|
||||||
|
ArtBreadcrumb: typeof import('./../components/core/layouts/art-breadcrumb/index.vue')['default']
|
||||||
|
ArtButtonMore: typeof import('./../components/core/forms/ArtButtonMore.vue')['default']
|
||||||
|
ArtButtonTable: typeof import('./../components/core/forms/ArtButtonTable.vue')['default']
|
||||||
|
ArtChatWindow: typeof import('./../components/core/layouts/art-chat-window/index.vue')['default']
|
||||||
|
ArtCutterImg: typeof import('./../components/core/media/ArtCutterImg.vue')['default']
|
||||||
|
ArtDataListCard: typeof import('./../components/core/cards/ArtDataListCard.vue')['default']
|
||||||
|
ArtDataViewer: typeof import('./../components/core/views/ArtDataViewer.vue')['default']
|
||||||
|
ArtDonutChartCard: typeof import('./../components/core/cards/ArtDonutChartCard.vue')['default']
|
||||||
|
ArtDragVerify: typeof import('./../components/core/forms/ArtDragVerify.vue')['default']
|
||||||
|
ArtDualBarCompareChart: typeof import('./../components/core/charts/ArtDualBarCompareChart.vue')['default']
|
||||||
|
ArtExcelExport: typeof import('./../components/core/forms/ArtExcelExport.vue')['default']
|
||||||
|
ArtExcelImport: typeof import('./../components/core/forms/ArtExcelImport.vue')['default']
|
||||||
|
ArtException: typeof import('./../components/core/views/exception/ArtException.vue')['default']
|
||||||
|
ArtFastEnter: typeof import('./../components/core/layouts/art-fast-enter/index.vue')['default']
|
||||||
|
ArtFestivalTextScroll: typeof import('./../components/core/text-effect/ArtFestivalTextScroll.vue')['default']
|
||||||
|
ArtFireworksEffect: typeof import('./../components/core/layouts/art-fireworks-effect/index.vue')['default']
|
||||||
|
ArtGlobalSearch: typeof import('./../components/core/layouts/art-global-search/index.vue')['default']
|
||||||
|
ArtHBarChart: typeof import('./../components/core/charts/ArtHBarChart.vue')['default']
|
||||||
|
ArtHeaderBar: typeof import('./../components/core/layouts/art-header-bar/index.vue')['default']
|
||||||
|
ArtHorizontalMenu: typeof import('./../components/core/layouts/art-menus/art-horizontal-menu/index.vue')['default']
|
||||||
|
ArtIconSelector: typeof import('./../components/core/base/ArtIconSelector.vue')['default']
|
||||||
|
ArtImageCard: typeof import('./../components/core/cards/ArtImageCard.vue')['default']
|
||||||
|
ArtKLineChart: typeof import('./../components/core/charts/ArtKLineChart.vue')['default']
|
||||||
|
ArtLayouts: typeof import('./../components/core/layouts/art-layouts/index.vue')['default']
|
||||||
|
ArtLineChart: typeof import('./../components/core/charts/ArtLineChart.vue')['default']
|
||||||
|
ArtLineChartCard: typeof import('./../components/core/cards/ArtLineChartCard.vue')['default']
|
||||||
|
ArtLogo: typeof import('./../components/core/base/ArtLogo.vue')['default']
|
||||||
|
ArtMapChart: typeof import('./../components/core/charts/ArtMapChart.vue')['default']
|
||||||
|
ArtMenuRight: typeof import('./../components/core/others/ArtMenuRight.vue')['default']
|
||||||
|
ArtMixedMenu: typeof import('./../components/core/layouts/art-menus/art-mixed-menu/index.vue')['default']
|
||||||
|
ArtNotification: typeof import('./../components/core/layouts/art-notification/index.vue')['default']
|
||||||
|
ArtPageContent: typeof import('./../components/core/layouts/art-page-content/index.vue')['default']
|
||||||
|
ArtProgressCard: typeof import('./../components/core/cards/ArtProgressCard.vue')['default']
|
||||||
|
ArtRadarChart: typeof import('./../components/core/charts/ArtRadarChart.vue')['default']
|
||||||
|
ArtResultPage: typeof import('./../components/core/views/result/ArtResultPage.vue')['default']
|
||||||
|
ArtRingChart: typeof import('./../components/core/charts/ArtRingChart.vue')['default']
|
||||||
|
ArtScatterChart: typeof import('./../components/core/charts/ArtScatterChart.vue')['default']
|
||||||
|
ArtScreenLock: typeof import('./../components/core/layouts/art-screen-lock/index.vue')['default']
|
||||||
|
ArtSearchBar: typeof import('./../components/core/forms/art-search-bar/index.vue')['default']
|
||||||
|
ArtSearchDate: typeof import('./../components/core/forms/art-search-bar/widget/art-search-date/index.vue')['default']
|
||||||
|
ArtSearchInput: typeof import('./../components/core/forms/art-search-bar/widget/art-search-input/index.vue')['default']
|
||||||
|
ArtSearchRadio: typeof import('./../components/core/forms/art-search-bar/widget/art-search-radio/index.vue')['default']
|
||||||
|
ArtSearchSelect: typeof import('./../components/core/forms/art-search-bar/widget/art-search-select/index.vue')['default']
|
||||||
|
ArtSearchTreeSelect: typeof import('./../components/core/forms/art-search-bar/widget/art-search-tree-select/index.vue')['default']
|
||||||
|
ArtSettingsPanel: typeof import('./../components/core/layouts/art-settings-panel/index.vue')['default']
|
||||||
|
ArtSidebarMenu: typeof import('./../components/core/layouts/art-menus/art-sidebar-menu/index.vue')['default']
|
||||||
|
ArtStatsCard: typeof import('./../components/core/cards/ArtStatsCard.vue')['default']
|
||||||
|
ArtTable: typeof import('./../components/core/tables/ArtTable.vue')['default']
|
||||||
|
ArtTableFullScreen: typeof import('./../components/core/tables/ArtTableFullScreen.vue')['default']
|
||||||
|
ArtTableHeader: typeof import('./../components/core/tables/ArtTableHeader.vue')['default']
|
||||||
|
ArtTextScroll: typeof import('./../components/core/text-effect/ArtTextScroll.vue')['default']
|
||||||
|
ArtTimelineListCard: typeof import('./../components/core/cards/ArtTimelineListCard.vue')['default']
|
||||||
|
ArtVideoPlayer: typeof import('./../components/core/media/ArtVideoPlayer.vue')['default']
|
||||||
|
ArtWangEditor: typeof import('./../components/core/forms/ArtWangEditor.vue')['default']
|
||||||
|
ArtWatermark: typeof import('./../components/core/others/ArtWatermark.vue')['default']
|
||||||
|
ArtWorkTab: typeof import('./../components/core/layouts/art-work-tab/index.vue')['default']
|
||||||
|
AuditDistributionChart: typeof import('./../components/business/audit/AuditDistributionChart.vue')['default']
|
||||||
|
AuditEventTable: typeof import('./../components/business/audit/AuditEventTable.vue')['default']
|
||||||
|
AuditInvestigationDrawer: typeof import('./../components/business/audit/AuditInvestigationDrawer.vue')['default']
|
||||||
|
AuditInvestigationHost: typeof import('./../components/business/audit/AuditInvestigationHost.vue')['default']
|
||||||
|
AuditInvestigationLinks: typeof import('./../components/business/audit/AuditInvestigationLinks.vue')['default']
|
||||||
|
AuditResourceSearchDialog: typeof import('./../components/business/audit/AuditResourceSearchDialog.vue')['default']
|
||||||
|
BasicSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/BasicSettings.vue')['default']
|
||||||
|
BatchOperationDialog: typeof import('./../components/business/BatchOperationDialog.vue')['default']
|
||||||
|
BatchRealnamePolicyDialog: typeof import('./../components/business/BatchRealnamePolicyDialog.vue')['default']
|
||||||
|
BoxStyleSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/BoxStyleSettings.vue')['default']
|
||||||
|
CardOperationDialog: typeof import('./../components/business/CardOperationDialog.vue')['default']
|
||||||
|
CardStatusTag: typeof import('./../components/business/CardStatusTag.vue')['default']
|
||||||
|
ChunkErrorBoundary: typeof import('./../components/core/others/ChunkErrorBoundary.vue')['default']
|
||||||
|
CodeGeneratorButton: typeof import('./../components/business/CodeGeneratorButton.vue')['default']
|
||||||
|
ColorSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/ColorSettings.vue')['default']
|
||||||
|
CommentItem: typeof import('./../components/custom/comment-widget/widget/CommentItem.vue')['default']
|
||||||
|
CommentWidget: typeof import('./../components/custom/comment-widget/index.vue')['default']
|
||||||
|
CommissionDisplay: typeof import('./../components/business/CommissionDisplay.vue')['default']
|
||||||
|
ContainerSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/ContainerSettings.vue')['default']
|
||||||
|
CreateRefundDialog: typeof import('./../components/business/CreateRefundDialog.vue')['default']
|
||||||
|
CustomerAccountDialog: typeof import('./../components/business/CustomerAccountDialog.vue')['default']
|
||||||
|
DetailPage: typeof import('./../components/common/DetailPage.vue')['default']
|
||||||
|
ExportTaskCreateDialog: typeof import('./../components/business/ExportTaskCreateDialog.vue')['default']
|
||||||
|
HorizontalSubmenu: typeof import('./../components/core/layouts/art-menus/art-horizontal-menu/widget/HorizontalSubmenu.vue')['default']
|
||||||
|
ImportDialog: typeof import('./../components/business/ImportDialog.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']
|
||||||
|
MenuStyleSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/MenuStyleSettings.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']
|
||||||
|
RealnamePolicyDialog: typeof import('./../components/device/RealnamePolicyDialog.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
SectionTitle: typeof import('./../components/core/layouts/art-settings-panel/widget/SectionTitle.vue')['default']
|
||||||
|
SeriesGrantPackageDialog: typeof import('./../components/business/SeriesGrantPackageDialog.vue')['default']
|
||||||
|
SeriesGrantPackageTable: typeof import('./../components/business/SeriesGrantPackageTable.vue')['default']
|
||||||
|
SettingDrawer: typeof import('./../components/core/layouts/art-settings-panel/widget/SettingDrawer.vue')['default']
|
||||||
|
SettingHeader: typeof import('./../components/core/layouts/art-settings-panel/widget/SettingHeader.vue')['default']
|
||||||
|
SettingItem: typeof import('./../components/core/layouts/art-settings-panel/widget/SettingItem.vue')['default']
|
||||||
|
ShopCreditLimitDialog: typeof import('./../components/business/ShopCreditLimitDialog.vue')['default']
|
||||||
|
SidebarSubmenu: typeof import('./../components/core/layouts/art-menus/art-sidebar-menu/widget/SidebarSubmenu.vue')['default']
|
||||||
|
SpeedLimitDialog: typeof import('./../components/device/SpeedLimitDialog.vue')['default']
|
||||||
|
SwitchCardDialog: typeof import('./../components/device/SwitchCardDialog.vue')['default']
|
||||||
|
TableContextMenuHint: typeof import('./../components/core/others/TableContextMenuHint.vue')['default']
|
||||||
|
ThemeSettings: typeof import('./../components/core/layouts/art-settings-panel/widget/ThemeSettings.vue')['default']
|
||||||
|
UpdateRealnameStatusDialog: typeof import('./../components/business/UpdateRealnameStatusDialog.vue')['default']
|
||||||
|
VoucherUpload: typeof import('./../components/business/VoucherUpload.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -624,7 +624,8 @@
|
|||||||
{
|
{
|
||||||
prop: 'enterprise_name',
|
prop: 'enterprise_name',
|
||||||
label: '企业名称',
|
label: '企业名称',
|
||||||
minWidth: 150,
|
minWidth: 200,
|
||||||
|
showOverflowTooltip: true,
|
||||||
formatter: (row: any) => {
|
formatter: (row: any) => {
|
||||||
return row.enterprise_name || '-'
|
return row.enterprise_name || '-'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,7 +440,7 @@
|
|||||||
{
|
{
|
||||||
prop: 'contact_name',
|
prop: 'contact_name',
|
||||||
label: '联系人姓名',
|
label: '联系人姓名',
|
||||||
width: 120
|
width: 140
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'contact_phone',
|
prop: 'contact_phone',
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElCard shadow="never" class="search-card">
|
<div class="search-area">
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span>资产查询</span>
|
|
||||||
<ElButton type="danger" @click="handleGoBack">返回上次搜索</ElButton>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="iccid-search">
|
<div class="iccid-search">
|
||||||
<div class="iccid-input-wrapper">
|
<div class="iccid-input-wrapper">
|
||||||
<ElInput
|
<ElInput
|
||||||
v-model="searchIccid"
|
v-model="searchIccid"
|
||||||
placeholder="请输入虚拟号、ICCID、IMEI、SN或MSISDN"
|
placeholder="请输入虚拟号、ICCID、IMEI、SN或MSISDN"
|
||||||
clearable
|
clearable
|
||||||
|
:prefix-icon="Search"
|
||||||
class="asset-search-input"
|
class="asset-search-input"
|
||||||
@focus="iccidInputFocused = true"
|
@focus="iccidInputFocused = true"
|
||||||
@blur="iccidInputFocused = false"
|
@blur="iccidInputFocused = false"
|
||||||
@@ -42,16 +37,17 @@
|
|||||||
>
|
>
|
||||||
同步
|
同步
|
||||||
</ElButton>
|
</ElButton>
|
||||||
|
<ElButton type="default" plain :icon="Back" @click="handleGoBack"> 返回上次搜索 </ElButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ElCard>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ElCard, ElInput, ElButton } from 'element-plus'
|
import { ElInput, ElButton } from 'element-plus'
|
||||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
import { Back, Search, Refresh } from '@element-plus/icons-vue'
|
||||||
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
||||||
|
|
||||||
// Use formatters
|
// Use formatters
|
||||||
@@ -135,27 +131,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.search-card {
|
.search-area {
|
||||||
|
position: relative;
|
||||||
|
z-index: 20;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
background: var(--el-bg-color, #fff);
|
|
||||||
|
|
||||||
:deep(.el-card__header) {
|
|
||||||
padding: 16px 20px;
|
|
||||||
background: var(--el-fill-color-light);
|
|
||||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-card__body) {
|
|
||||||
padding: 16px 20px;
|
|
||||||
overflow: visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.iccid-search {
|
.iccid-search {
|
||||||
@@ -163,6 +143,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
.iccid-input-wrapper {
|
.iccid-input-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -171,44 +152,49 @@
|
|||||||
|
|
||||||
.asset-search-input {
|
.asset-search-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
:deep(.el-input__prefix) {
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.iccid-magnifier {
|
.iccid-magnifier {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% + 12px);
|
top: calc(100% + 12px);
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1000;
|
z-index: 2000;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
// 三角箭头 - 上边框样式
|
|
||||||
.magnifier-arrow {
|
.magnifier-arrow {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -9px;
|
top: -9px;
|
||||||
left: 80px;
|
left: 80px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
background-color: var(--el-bg-color, #fff);
|
background-color: var(--el-color-primary-light-9);
|
||||||
border-top: 2px solid var(--el-color-primary);
|
border-top: 2px solid var(--el-color-primary);
|
||||||
border-left: 2px solid var(--el-color-primary);
|
border-left: 2px solid var(--el-color-primary);
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 内容区域
|
|
||||||
.magnifier-content {
|
.magnifier-content {
|
||||||
|
display: inline-block;
|
||||||
|
width: fit-content;
|
||||||
max-width: min(720px, calc(100vw - 48px));
|
max-width: min(720px, calc(100vw - 48px));
|
||||||
padding: 16px 24px;
|
padding: 14px 22px;
|
||||||
font-family: 'Courier New', Consolas, monospace;
|
font-family: 'Courier New', Consolas, monospace;
|
||||||
font-size: 28px;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
color: var(--el-text-color-primary);
|
color: var(--el-color-primary);
|
||||||
letter-spacing: 3px;
|
text-align: center;
|
||||||
|
letter-spacing: 1.5px;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
background-color: var(--el-bg-color, #fff);
|
background-color: var(--el-color-primary-light-9);
|
||||||
border: 2px solid var(--el-color-primary);
|
border: 2px solid var(--el-color-primary);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
|
box-shadow: 0 8px 18px rgb(15 23 42 / 12%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,19 +205,13 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 放大效果的过渡动画
|
|
||||||
.zoom-fade-enter-active,
|
.zoom-fade-enter-active,
|
||||||
.zoom-fade-leave-active {
|
.zoom-fade-leave-active {
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoom-fade-enter-from {
|
.zoom-fade-enter-from,
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.8) translateY(-10px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.zoom-fade-leave-to {
|
.zoom-fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scale(0.8) translateY(-10px);
|
transform: scale(0.8) translateY(-10px);
|
||||||
@@ -244,26 +224,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 768px) {
|
@media (width <= 768px) {
|
||||||
.search-card {
|
.search-area {
|
||||||
top: 16px;
|
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
||||||
:deep(.el-card__header) {
|
|
||||||
padding: 12px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-card__body) {
|
|
||||||
padding: 12px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-card__header) .card-header {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.iccid-search {
|
.iccid-search {
|
||||||
@@ -306,5 +268,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<ElDescriptions :column="descriptionsColumn" border>
|
<ElDescriptions :column="descriptionsColumn" direction="vertical" border>
|
||||||
<!-- 卡专属字段 -->
|
<!-- 卡专属字段 -->
|
||||||
<template v-if="cardInfo?.asset_type === 'card'">
|
<template v-if="cardInfo?.asset_type === 'card'">
|
||||||
<ElDescriptionsItem label="ICCID">{{ cardInfo?.iccid || '-' }}</ElDescriptionsItem>
|
<ElDescriptionsItem label="ICCID">{{ cardInfo?.iccid || '-' }}</ElDescriptionsItem>
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
<ElDescriptions :column="descriptionsColumn" border>
|
<ElDescriptions :column="descriptionsColumn" border>
|
||||||
<ElDescriptionsItem v-if="previousExchangeAsset" label="前代资产">
|
<ElDescriptionsItem v-if="previousExchangeAsset" label="前代资产">
|
||||||
<div class="exchange-asset">
|
<div class="exchange-asset">
|
||||||
<ElTag type="success" size="small">换货新资产</ElTag>
|
<ElTag type="success" size="small">旧资产</ElTag>
|
||||||
<ElButton
|
<ElButton
|
||||||
v-if="previousExchangeAsset.can_view"
|
v-if="previousExchangeAsset.can_view"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -251,230 +251,118 @@
|
|||||||
|
|
||||||
<!-- 设备绑定卡列表 -->
|
<!-- 设备绑定卡列表 -->
|
||||||
<template v-if="cardInfo?.asset_type === 'device'">
|
<template v-if="cardInfo?.asset_type === 'device'">
|
||||||
<ElDivider content-position="left">绑定卡列表</ElDivider>
|
<ElDivider class="info-section-divider" content-position="left">
|
||||||
<ElTable
|
<span class="section-divider-title">绑定卡列表</span>
|
||||||
v-if="cardInfo.cards && cardInfo.cards.length > 0"
|
</ElDivider>
|
||||||
:data="sortedDeviceCards"
|
<div v-if="cardInfo.cards && cardInfo.cards.length > 0" class="binding-card-list">
|
||||||
border
|
<ElCard v-for="bindingCard in sortedDeviceCards" :key="bindingCard.iccid" shadow="never">
|
||||||
style="width: 100%; margin-top: 16px"
|
<div class="binding-card-header">
|
||||||
>
|
<div class="binding-card-identifier">
|
||||||
<ElTableColumn label="ICCID" width="220" show-overflow-tooltip>
|
<ElButton type="primary" link @click="handleNavigateToCardInfo(bindingCard.iccid)">
|
||||||
<template #default="scope">
|
{{ bindingCard.iccid }}
|
||||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
|
||||||
<ElButton type="primary" link @click="handleNavigateToCardInfo(scope.row.iccid)">
|
|
||||||
{{ scope.row.iccid }}
|
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<el-icon
|
<el-icon class="copy-icon" @click="handleCopyICCID(bindingCard.iccid)" title="复制">
|
||||||
class="copy-icon"
|
|
||||||
@click="handleCopyICCID(scope.row.iccid)"
|
|
||||||
style="color: var(--el-color-primary); cursor: pointer"
|
|
||||||
>
|
|
||||||
<CopyDocument />
|
<CopyDocument />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<ElTag v-if="bindingCard.is_current" type="primary" size="small">当前</ElTag>
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn prop="msisdn" label="MSISDN" min-width="150" showOverflowTooltip />
|
|
||||||
|
|
||||||
<ElTableColumn prop="carrier_name" label="运营商" min-width="120" showOverflowTooltip />
|
|
||||||
<ElTableColumn prop="slot_position" label="卡槽位置" width="130">
|
|
||||||
<template #default="scope">
|
|
||||||
<div style="display: flex; gap: 10px">
|
|
||||||
<span>SIM-{{ scope.row.slot_position }}</span>
|
|
||||||
<ElTag v-if="scope.row.is_current" type="primary" size="small">当前</ElTag>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
<div class="binding-card-details">
|
||||||
<ElTableColumn label="网络状态" width="100">
|
<ElDescriptions :column="bindingCardColumns" direction="vertical">
|
||||||
<template #default="scope">
|
<ElDescriptionsItem label="MSISDN">
|
||||||
<ElTag :type="scope.row.network_status === 1 ? 'success' : 'danger'" size="small">
|
{{ bindingCard.msisdn || '-' }}
|
||||||
{{ scope.row.network_status === 1 ? '正常' : '停机' }}
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="运营商">
|
||||||
|
{{ bindingCard.carrier_name || '-' }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="卡槽位置">
|
||||||
|
SIM-{{ bindingCard.slot_position ?? '-' }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="网络状态">
|
||||||
|
<ElTag :type="bindingCard.network_status === 1 ? 'success' : 'danger'" size="small">
|
||||||
|
{{ bindingCard.network_status === 1 ? '正常' : '停机' }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</template>
|
</ElDescriptionsItem>
|
||||||
</ElTableColumn>
|
<ElDescriptionsItem label="实名状态">
|
||||||
<ElTableColumn label="实名状态" width="100">
|
<ElTag :type="getRealNameStatusType(bindingCard.real_name_status)" size="small">
|
||||||
<template #default="scope">
|
{{ getRealNameStatusName(bindingCard.real_name_status) }}
|
||||||
<ElTag :type="getRealNameStatusType(scope.row.real_name_status)" size="small">
|
|
||||||
{{ getRealNameStatusName(scope.row.real_name_status) }}
|
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</template>
|
</ElDescriptionsItem>
|
||||||
</ElTableColumn>
|
<ElDescriptionsItem label="实名认证策略">
|
||||||
<ElTableColumn label="实名认证策略" width="120" showOverflowTooltip>
|
{{ getRealnamePolicyName(bindingCard.realname_policy) }}
|
||||||
<template #default="scope">
|
</ElDescriptionsItem>
|
||||||
{{ getRealnamePolicyName(scope.row.realname_policy) }}
|
<ElDescriptionsItem label="实名时间">
|
||||||
</template>
|
{{ bindingCard.real_name_at ? formatDateTime(bindingCard.real_name_at) : '-' }}
|
||||||
</ElTableColumn>
|
</ElDescriptionsItem>
|
||||||
<ElTableColumn label="实名时间" width="170">
|
<ElDescriptionsItem label="运营商停机原因">
|
||||||
<template #default="scope">
|
{{ bindingCard.gateway_extend || '-' }}
|
||||||
{{ scope.row.real_name_at ? formatDateTime(scope.row.real_name_at) : '-' }}
|
</ElDescriptionsItem>
|
||||||
</template>
|
</ElDescriptions>
|
||||||
</ElTableColumn>
|
</div>
|
||||||
<ElTableColumn label="运营商停机原因" min-width="220" showOverflowTooltip>
|
|
||||||
<template #default="scope">
|
<div class="binding-card-actions">
|
||||||
{{ scope.row.gateway_extend || '-' }}
|
|
||||||
</template>
|
|
||||||
</ElTableColumn>
|
|
||||||
<ElTableColumn label="操作" width="260" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<!-- 根据网络状态显示启用或停用按钮 -->
|
|
||||||
<ElButton
|
<ElButton
|
||||||
v-if="scope.row.network_status === 0"
|
v-if="bindingCard.network_status === 0"
|
||||||
type="success"
|
type="success"
|
||||||
size="small"
|
size="small"
|
||||||
link
|
link
|
||||||
:disabled="isBindingStartDisabled(scope.row)"
|
:disabled="isBindingStartDisabled(bindingCard)"
|
||||||
@click="handleEnableBindingCard(scope.row)"
|
@click="handleEnableBindingCard(bindingCard)"
|
||||||
v-permission="'iot_info:start'"
|
v-permission="'iot_info:start'"
|
||||||
>
|
>
|
||||||
{{ getBindingStartButtonText(scope.row) }}
|
{{ getBindingStartButtonText(bindingCard) }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton
|
<ElButton
|
||||||
v-if="scope.row.network_status === 1"
|
v-if="bindingCard.network_status === 1"
|
||||||
type="warning"
|
type="warning"
|
||||||
size="small"
|
size="small"
|
||||||
link
|
link
|
||||||
:disabled="isBindingStopDisabled(scope.row)"
|
:disabled="isBindingStopDisabled(bindingCard)"
|
||||||
@click="handleDisableBindingCard(scope.row)"
|
@click="handleDisableBindingCard(bindingCard)"
|
||||||
v-permission="'iot_info:stop'"
|
v-permission="'iot_info:stop'"
|
||||||
>
|
>
|
||||||
{{ getBindingStopButtonText(scope.row) }}
|
{{ getBindingStopButtonText(bindingCard) }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton
|
<ElButton
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
link
|
link
|
||||||
@click="handleUpdateBindingCardRealnameStatus(scope.row)"
|
@click="handleUpdateBindingCardRealnameStatus(bindingCard)"
|
||||||
v-permission="'bound_card:update_realname_status'"
|
v-permission="'bound_card:update_realname_status'"
|
||||||
>
|
>
|
||||||
更新实名状态
|
更新实名状态
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton
|
<ElButton
|
||||||
v-if="getBindingCardAuditTarget(scope.row)"
|
v-if="getBindingCardAuditTarget(bindingCard)"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
link
|
link
|
||||||
@click="openBindingCardAudit(scope.row)"
|
@click="openBindingCardAudit(bindingCard)"
|
||||||
>
|
>
|
||||||
卡审计
|
卡审计
|
||||||
</ElButton>
|
</ElButton>
|
||||||
</template>
|
</div>
|
||||||
</ElTableColumn>
|
</ElCard>
|
||||||
</ElTable>
|
</div>
|
||||||
<ElEmpty v-else description="暂无绑定卡" :image-size="80" style="margin-top: 16px" />
|
<ElEmpty v-else description="暂无绑定卡" :image-size="80" style="margin-top: 16px" />
|
||||||
|
|
||||||
<!-- 设备实时信息 -->
|
<!-- 设备实时信息 -->
|
||||||
<ElDivider content-position="left">设备实时信息</ElDivider>
|
<ElDivider class="info-section-divider" content-position="left">
|
||||||
<div v-if="hasDeviceRealtimeSection" v-loading="realtimeLoading" style="margin-top: 16px">
|
<span class="section-divider-title">设备实时信息</span>
|
||||||
<ElDescriptions :column="descriptionsColumn" border>
|
</ElDivider>
|
||||||
<!-- 基本状态 -->
|
<div v-if="hasDeviceRealtimeSection" v-loading="realtimeLoading" class="realtime-section">
|
||||||
<ElDescriptionsItem label="在线状态">
|
<ElDescriptions :column="descriptionsColumn" direction="vertical" border>
|
||||||
<ElTag :type="getOnlineStatusType(deviceRealtime?.online_status)" size="small">
|
<ElDescriptionsItem
|
||||||
{{ getOnlineStatusName(deviceRealtime?.online_status) }}
|
v-for="item in realtimeDescriptionItems"
|
||||||
|
:key="item.key"
|
||||||
|
:label="item.label"
|
||||||
|
:span="item.span ?? 1"
|
||||||
|
>
|
||||||
|
<ElTag v-if="item.tagType" :type="item.tagType" size="small">
|
||||||
|
{{ item.value }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</ElDescriptionsItem>
|
<span v-else>{{ item.value }}</span>
|
||||||
<ElDescriptionsItem label="电量">
|
|
||||||
{{
|
|
||||||
deviceRealtime?.battery_level !== null && deviceRealtime?.battery_level !== undefined
|
|
||||||
? `${deviceRealtime?.battery_level}%`
|
|
||||||
: '-'
|
|
||||||
}}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<!-- 时间信息 -->
|
|
||||||
<ElDescriptionsItem label="本次开机时长">
|
|
||||||
{{ formatDuration(deviceRealtime?.run_time) }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="本次联网时长">
|
|
||||||
{{ formatDuration(deviceRealtime?.connect_time) }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="最后在线时间">
|
|
||||||
{{ formatDateTime(deviceRealtime?.last_online_time) || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="实名同步时间">
|
|
||||||
{{ formatDateTime(cardInfo?.last_real_name_check_at) || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="卡状态同步时间">
|
|
||||||
{{ formatDateTime(cardInfo?.last_card_status_check_at) || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="流量同步时间">
|
|
||||||
{{ formatDateTime(cardInfo?.last_data_check_at) || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<!-- 信号信息 -->
|
|
||||||
<ElDescriptionsItem label="信号综合判断">
|
|
||||||
<ElTag :type="getSignalQualityType(deviceRealtime?.signal_quality)" size="small">
|
|
||||||
{{ getSignalQualityText(deviceRealtime?.signal_quality) }}
|
|
||||||
</ElTag>
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="信号较弱原因" :span="3">
|
|
||||||
{{ getSignalBadReasonText(deviceRealtime?.signal_bad_reason) }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="已连接设备数">
|
|
||||||
{{ deviceRealtime?.client_number ?? '-' }} / {{ deviceRealtime?.max_clients ?? '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<!-- WiFi 信息 -->
|
|
||||||
<ElDescriptionsItem label="WiFi 状态">
|
|
||||||
<ElTag :type="deviceRealtime?.wifi_enabled ? 'success' : 'info'" size="small">
|
|
||||||
{{
|
|
||||||
deviceRealtime?.wifi_enabled === undefined
|
|
||||||
? '-'
|
|
||||||
: deviceRealtime.wifi_enabled
|
|
||||||
? '已开启'
|
|
||||||
: '已关闭'
|
|
||||||
}}
|
|
||||||
</ElTag>
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="WiFi 名称">
|
|
||||||
{{ deviceRealtime?.ssid || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="WiFi 密码">
|
|
||||||
{{ deviceRealtime?.wifi_password || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<!-- 网络信息 -->
|
|
||||||
<ElDescriptionsItem label="WAN IP">
|
|
||||||
{{ deviceRealtime?.wan_ip || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="LAN IP">
|
|
||||||
{{ deviceRealtime?.lan_ip || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<ElDescriptionsItem label="MAC 地址">
|
|
||||||
{{ deviceRealtime?.mac_address || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="IMSI">
|
|
||||||
{{ deviceRealtime?.imsi || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<!-- 设备配置 -->
|
|
||||||
<ElDescriptionsItem label="限速">
|
|
||||||
{{
|
|
||||||
deviceRealtime?.limit_speed === undefined
|
|
||||||
? '-'
|
|
||||||
: deviceRealtime.limit_speed
|
|
||||||
? `${deviceRealtime.limit_speed} KB/s`
|
|
||||||
: '不限速'
|
|
||||||
}}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="固件版本">
|
|
||||||
{{ deviceRealtime?.software_version || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="切卡模式">
|
|
||||||
{{
|
|
||||||
deviceRealtime?.switch_mode === '0'
|
|
||||||
? '自动'
|
|
||||||
: deviceRealtime?.switch_mode === '1'
|
|
||||||
? '手动'
|
|
||||||
: '-'
|
|
||||||
}}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
|
|
||||||
<ElDescriptionsItem label="上报周期">
|
|
||||||
{{ deviceRealtime?.sync_interval ? `${deviceRealtime.sync_interval} 秒` : '-' }}
|
|
||||||
</ElDescriptionsItem>
|
|
||||||
<ElDescriptionsItem label="信息更新时间">
|
|
||||||
{{ formatDateTime(deviceRealtime?.last_update_time) || '-' }}
|
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
</ElDescriptions>
|
</ElDescriptions>
|
||||||
</div>
|
</div>
|
||||||
@@ -577,8 +465,6 @@
|
|||||||
ElTooltip,
|
ElTooltip,
|
||||||
ElSwitch,
|
ElSwitch,
|
||||||
ElDivider,
|
ElDivider,
|
||||||
ElTable,
|
|
||||||
ElTableColumn,
|
|
||||||
ElButton,
|
ElButton,
|
||||||
ElAlert,
|
ElAlert,
|
||||||
ElEmpty,
|
ElEmpty,
|
||||||
@@ -825,9 +711,11 @@
|
|||||||
const descriptionsColumn = computed(() => {
|
const descriptionsColumn = computed(() => {
|
||||||
if (width.value <= 640) return 1
|
if (width.value <= 640) return 1
|
||||||
if (width.value <= 1024) return 2
|
if (width.value <= 1024) return 2
|
||||||
return 4
|
return 5
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const bindingCardColumns = computed(() => (width.value <= 640 ? 1 : 2))
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
interface Emits {
|
interface Emits {
|
||||||
(e: 'update:pollingEnabled', value: boolean): void
|
(e: 'update:pollingEnabled', value: boolean): void
|
||||||
@@ -871,6 +759,127 @@
|
|||||||
} = useAssetFormatters()
|
} = useAssetFormatters()
|
||||||
|
|
||||||
// 排序后的设备卡列表(按卡槽位置排序,当前卡排在最前面)
|
// 排序后的设备卡列表(按卡槽位置排序,当前卡排在最前面)
|
||||||
|
const realtimeDescriptionItems = computed(() => {
|
||||||
|
const realtime = props.deviceRealtime
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'status',
|
||||||
|
label: '在线状态',
|
||||||
|
value: getOnlineStatusName(realtime?.online_status),
|
||||||
|
tagType: getOnlineStatusType(realtime?.online_status)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'battery',
|
||||||
|
label: '电量',
|
||||||
|
value:
|
||||||
|
realtime?.battery_level !== null && realtime?.battery_level !== undefined
|
||||||
|
? `${realtime.battery_level}%`
|
||||||
|
: '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'boot',
|
||||||
|
label: '本次开机时长',
|
||||||
|
value: formatDuration(realtime?.run_time)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'connect',
|
||||||
|
label: '本次联网时长',
|
||||||
|
value: formatDuration(realtime?.connect_time)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'online',
|
||||||
|
label: '最后在线时间',
|
||||||
|
value: formatDateTime(realtime?.last_online_time) || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'realname',
|
||||||
|
label: '实名同步时间',
|
||||||
|
value: formatDateTime(props.cardInfo?.last_real_name_check_at) || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'cardSync',
|
||||||
|
label: '卡状态同步时间',
|
||||||
|
value: formatDateTime(props.cardInfo?.last_card_status_check_at) || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'trafficSync',
|
||||||
|
label: '流量同步时间',
|
||||||
|
value: formatDateTime(props.cardInfo?.last_data_check_at) || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'signal',
|
||||||
|
label: '信号综合判断',
|
||||||
|
value: getSignalQualityText(realtime?.signal_quality),
|
||||||
|
tagType: getSignalQualityType(realtime?.signal_quality)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'signalReason',
|
||||||
|
label: '信号较弱原因',
|
||||||
|
value: getSignalBadReasonText(realtime?.signal_bad_reason)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'clients',
|
||||||
|
label: '已连接设备数',
|
||||||
|
value: `${realtime?.client_number ?? '-'} / ${realtime?.max_clients ?? '-'}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wifi',
|
||||||
|
label: 'WiFi 状态',
|
||||||
|
value:
|
||||||
|
realtime?.wifi_enabled === undefined ? '-' : realtime.wifi_enabled ? '已开启' : '已关闭',
|
||||||
|
tagType: realtime?.wifi_enabled ? 'success' : 'info'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wifiName',
|
||||||
|
label: 'WiFi 名称',
|
||||||
|
value: realtime?.ssid || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wifiPassword',
|
||||||
|
label: 'WiFi 密码',
|
||||||
|
value: realtime?.wifi_password || '-'
|
||||||
|
},
|
||||||
|
{ key: 'wan', label: 'WAN IP', value: realtime?.wan_ip || '-' },
|
||||||
|
{ key: 'lan', label: 'LAN IP', value: realtime?.lan_ip || '-' },
|
||||||
|
{
|
||||||
|
key: 'mac',
|
||||||
|
label: 'MAC 地址',
|
||||||
|
value: realtime?.mac_address || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'limit',
|
||||||
|
label: '限速',
|
||||||
|
value:
|
||||||
|
realtime?.limit_speed === undefined
|
||||||
|
? '-'
|
||||||
|
: realtime.limit_speed
|
||||||
|
? `${realtime.limit_speed} KB/s`
|
||||||
|
: '不限速'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'switchMode',
|
||||||
|
label: '切卡模式',
|
||||||
|
value: realtime?.switch_mode === '0' ? '自动' : realtime?.switch_mode === '1' ? '手动' : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'interval',
|
||||||
|
label: '上报周期',
|
||||||
|
value: realtime?.sync_interval ? `${realtime.sync_interval} 秒` : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'firmware',
|
||||||
|
label: '固件版本',
|
||||||
|
value: realtime?.software_version || '-',
|
||||||
|
span: descriptionsColumn.value >= 5 ? 2 : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'updated',
|
||||||
|
label: '信息更新时间',
|
||||||
|
value: formatDateTime(realtime?.last_update_time) || '-'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
const sortedDeviceCards = computed(() => {
|
const sortedDeviceCards = computed(() => {
|
||||||
if (!props.cardInfo?.cards || props.cardInfo.cards.length === 0) {
|
if (!props.cardInfo?.cards || props.cardInfo.cards.length === 0) {
|
||||||
return []
|
return []
|
||||||
@@ -1084,16 +1093,96 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-descriptions__body) {
|
.info-section-divider {
|
||||||
overflow-x: auto;
|
display: flex;
|
||||||
|
height: 20px;
|
||||||
|
align-items: center;
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
:deep(.el-divider__text) {
|
||||||
|
position: static;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 20px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
background-color: transparent;
|
||||||
|
transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-descriptions__cell) {
|
.section-divider-title {
|
||||||
word-break: break-word;
|
display: inline-flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
width: 3px;
|
||||||
|
height: 16px;
|
||||||
|
content: '';
|
||||||
|
background-color: var(--el-color-primary);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-table) {
|
.binding-card-list {
|
||||||
min-width: 760px;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.binding-card-header,
|
||||||
|
.binding-card-identifier,
|
||||||
|
.binding-card-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.binding-card-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.binding-card-details {
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.binding-card-identifier {
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-left: 6px;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.binding-card-actions {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
padding-top: 12px;
|
||||||
|
margin-top: 12px;
|
||||||
|
border-top: 1px solid var(--el-border-color-lighter);
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width <= 1200px) {
|
||||||
|
.binding-card-list {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-operations,
|
.card-operations,
|
||||||
@@ -1120,6 +1209,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 768px) {
|
@media (width <= 768px) {
|
||||||
|
.binding-card-list {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|||||||
@@ -186,7 +186,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 套餐详情表格 -->
|
<!-- 套餐详情表格 -->
|
||||||
<ElDescriptions :column="descriptionsColumn" border class="package-info-table">
|
<ElDescriptions :column="descriptionsColumn" direction="vertical" border>
|
||||||
<ElDescriptionsItem label="订单号">
|
<ElDescriptionsItem label="订单号">
|
||||||
{{ currentPackage.order_no || '-' }}
|
{{ currentPackage.order_no || '-' }}
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
@@ -296,7 +296,7 @@
|
|||||||
const descriptionsColumn = computed(() => {
|
const descriptionsColumn = computed(() => {
|
||||||
if (width.value <= 640) return 1
|
if (width.value <= 640) return 1
|
||||||
if (width.value <= 1024) return 2
|
if (width.value <= 1024) return 2
|
||||||
return 3
|
return 5
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -450,18 +450,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-info-table {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-descriptions__body) {
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-descriptions__cell) {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (width <= 992px) {
|
@media (width <= 992px) {
|
||||||
.flow-progress-card {
|
.flow-progress-card {
|
||||||
.flow-stats-container {
|
.flow-stats-container {
|
||||||
|
|||||||
@@ -12,21 +12,21 @@
|
|||||||
<!-- 钱包余额展示 -->
|
<!-- 钱包余额展示 -->
|
||||||
<div class="wallet-balance-cards">
|
<div class="wallet-balance-cards">
|
||||||
<div class="balance-card total">
|
<div class="balance-card total">
|
||||||
<div class="balance-icon">💰</div>
|
<div class="balance-icon"><Money /></div>
|
||||||
<div class="balance-info">
|
<div class="balance-info">
|
||||||
<div class="balance-label">总余额</div>
|
<div class="balance-label">总余额</div>
|
||||||
<div class="balance-value">{{ formatAmount(walletInfo.balance) }}</div>
|
<div class="balance-value">{{ formatAmount(walletInfo.balance) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="balance-card available">
|
<div class="balance-card available">
|
||||||
<div class="balance-icon">✅</div>
|
<div class="balance-icon"><CircleCheck /></div>
|
||||||
<div class="balance-info">
|
<div class="balance-info">
|
||||||
<div class="balance-label">可用余额</div>
|
<div class="balance-label">可用余额</div>
|
||||||
<div class="balance-value">{{ formatAmount(walletInfo.available_balance) }}</div>
|
<div class="balance-value">{{ formatAmount(walletInfo.available_balance) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="balance-card frozen">
|
<div class="balance-card frozen">
|
||||||
<div class="balance-icon">🔒</div>
|
<div class="balance-icon"><Lock /></div>
|
||||||
<div class="balance-info">
|
<div class="balance-info">
|
||||||
<div class="balance-label">冻结余额</div>
|
<div class="balance-label">冻结余额</div>
|
||||||
<div class="balance-value">{{ formatAmount(walletInfo.frozen_balance) }}</div>
|
<div class="balance-value">{{ formatAmount(walletInfo.frozen_balance) }}</div>
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ElCard, ElTag, ElEmpty } from 'element-plus'
|
import { ElCard, ElTag, ElEmpty } from 'element-plus'
|
||||||
|
import { CircleCheck, Lock, Money } from '@element-plus/icons-vue'
|
||||||
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
import { useAssetFormatters } from '../composables/useAssetFormatters'
|
||||||
|
|
||||||
// Use formatters
|
// Use formatters
|
||||||
@@ -91,6 +92,11 @@
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
|
:deep(svg) {
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-info {
|
.balance-info {
|
||||||
|
|||||||
@@ -10,15 +10,15 @@
|
|||||||
<template v-if="walletInfo">
|
<template v-if="walletInfo">
|
||||||
<ElDivider class="wallet-divider" direction="vertical" />
|
<ElDivider class="wallet-divider" direction="vertical" />
|
||||||
<span class="balance-item"
|
<span class="balance-item"
|
||||||
>💰 总余额 <strong>{{ formatAmount(walletInfo.balance) }}</strong></span
|
>总余额 <strong>{{ formatAmount(walletInfo.balance) }}</strong></span
|
||||||
>
|
>
|
||||||
<ElDivider class="wallet-divider" direction="vertical" />
|
<ElDivider class="wallet-divider" direction="vertical" />
|
||||||
<span class="balance-item"
|
<span class="balance-item"
|
||||||
>✅ 可用 <strong>{{ formatAmount(walletInfo.available_balance) }}</strong></span
|
>可用 <strong>{{ formatAmount(walletInfo.available_balance) }}</strong></span
|
||||||
>
|
>
|
||||||
<ElDivider class="wallet-divider" direction="vertical" />
|
<ElDivider class="wallet-divider" direction="vertical" />
|
||||||
<span class="balance-item"
|
<span class="balance-item"
|
||||||
>🔒 冻结 <strong>{{ formatAmount(walletInfo.frozen_balance) }}</strong></span
|
>冻结 <strong>{{ formatAmount(walletInfo.frozen_balance) }}</strong></span
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="套餐流量详单" width="900px" destroy-on-close>
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="套餐流量详单"
|
||||||
|
width="900px"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
<div v-if="data">
|
<div v-if="data">
|
||||||
<!-- 套餐信息摘要 -->
|
<!-- 套餐信息摘要 -->
|
||||||
<ElDescriptions :column="2" border style="margin-bottom: 20px">
|
<ElDescriptions :column="2" border style="margin-bottom: 20px">
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="往期订单" width="60%" destroy-on-close>
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="往期订单"
|
||||||
|
width="60%"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
<div v-if="loading" style="padding: 40px 0; text-align: center">
|
<div v-if="loading" style="padding: 40px 0; text-align: center">
|
||||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,8 +138,7 @@
|
|||||||
ElPagination,
|
ElPagination,
|
||||||
ElAlert,
|
ElAlert,
|
||||||
ElEmpty,
|
ElEmpty,
|
||||||
ElIcon,
|
ElIcon
|
||||||
ElMessage
|
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
import { Loading } from '@element-plus/icons-vue'
|
import { Loading } from '@element-plus/icons-vue'
|
||||||
import { AssetService } from '@/api/modules'
|
import { AssetService } from '@/api/modules'
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="套餐充值" width="30%" @closed="handleDialogClosed">
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="套餐充值"
|
||||||
|
width="30%"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
@closed="handleDialogClosed"
|
||||||
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px">
|
||||||
<ElFormItem label="资产信息">
|
<ElFormItem label="资产信息">
|
||||||
<span style="font-weight: bold; color: #409eff">
|
<span style="font-weight: bold; color: #409eff">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
width="500px"
|
width="500px"
|
||||||
:lock-scroll="true"
|
:lock-scroll="true"
|
||||||
:z-index="4000"
|
:z-index="4000"
|
||||||
modal-class="speed-limit-modal"
|
modal-class="asset-information-dialog speed-limit-modal"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElFormItem label="固定档位" prop="code">
|
<ElFormItem label="固定档位" prop="code">
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="设置切卡模式" width="500px">
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="设置切卡模式"
|
||||||
|
width="500px"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="96px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="96px">
|
||||||
<ElFormItem label="设备标识">
|
<ElFormItem label="设备标识">
|
||||||
<span class="device-identifier">{{ deviceIdentifier || '-' }}</span>
|
<span class="device-identifier">{{ deviceIdentifier || '-' }}</span>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<ElDialog v-model="visible" title="设置WiFi" width="30%" :append-to-body="true">
|
<ElDialog
|
||||||
|
v-model="visible"
|
||||||
|
title="设置WiFi"
|
||||||
|
width="30%"
|
||||||
|
modal-class="asset-information-dialog"
|
||||||
|
:append-to-body="true"
|
||||||
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px" autocomplete="off">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px" autocomplete="off">
|
||||||
<ElFormItem label="WiFi状态" prop="enabled">
|
<ElFormItem label="WiFi状态" prop="enabled">
|
||||||
<ElRadioGroup v-model="form.enabled">
|
<ElRadioGroup v-model="form.enabled">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="single-card-page">
|
<div class="single-card-page asset-information-page">
|
||||||
<!-- 资产查询区域 -->
|
<!-- 资产查询区域 -->
|
||||||
<AssetSearchCard
|
<AssetSearchCard
|
||||||
ref="assetSearchCardRef"
|
ref="assetSearchCardRef"
|
||||||
@@ -12,8 +12,9 @@
|
|||||||
<!-- 卡片内容区域 -->
|
<!-- 卡片内容区域 -->
|
||||||
<div v-if="cardInfo" class="card-content-area slide-in">
|
<div v-if="cardInfo" class="card-content-area slide-in">
|
||||||
<div class="main-content-layout">
|
<div class="main-content-layout">
|
||||||
<!-- 第一行:基本信息 -->
|
<div class="overview-grid">
|
||||||
<div class="row full-width">
|
<!-- 第一层:资产概览与当前生效套餐,按信息高度纵向展开 -->
|
||||||
|
<div class="row overview-primary">
|
||||||
<BasicInfoCard
|
<BasicInfoCard
|
||||||
:card-info="cardInfo"
|
:card-info="cardInfo"
|
||||||
:device-realtime="deviceRealtime"
|
:device-realtime="deviceRealtime"
|
||||||
@@ -48,8 +49,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 第二行:当前生效套餐 -->
|
<div class="row overview-secondary">
|
||||||
<div class="row full-width">
|
|
||||||
<CurrentPackageCard
|
<CurrentPackageCard
|
||||||
:current-package="currentPackage"
|
:current-package="currentPackage"
|
||||||
:loading="currentPackageLoading"
|
:loading="currentPackageLoading"
|
||||||
@@ -61,6 +61,7 @@
|
|||||||
@navigate-to-device="handleNavigateToDevice"
|
@navigate-to-device="handleNavigateToDevice"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 第三行:套餐列表 -->
|
<!-- 第三行:套餐列表 -->
|
||||||
<div class="row full-width">
|
<div class="row full-width">
|
||||||
@@ -989,6 +990,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 主内容布局
|
// 主内容布局
|
||||||
|
.overview-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.main-content-layout {
|
.main-content-layout {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1057,6 +1064,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 768px) {
|
@media (width <= 768px) {
|
||||||
|
.overview-grid {
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
@@ -1636,3 +1647,118 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.asset-information-page {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* Dialogs are teleported to body, so their surface needs a page-level hook. */
|
||||||
|
.asset-information-dialog.el-dialog {
|
||||||
|
max-width: calc(100vw - 32px);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #e5eaf1;
|
||||||
|
border-radius: 14px;
|
||||||
|
box-shadow: 0 18px 50px rgb(15 23 42 / 18%);
|
||||||
|
|
||||||
|
.el-dialog__header {
|
||||||
|
padding: 20px 24px 16px;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid #e5eaf1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 650;
|
||||||
|
color: #172033;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 22px 24px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__footer {
|
||||||
|
padding: 14px 24px 20px;
|
||||||
|
border-top: 1px solid #eef2f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item__label {
|
||||||
|
color: #526078;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
min-height: 34px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table {
|
||||||
|
--el-table-header-bg-color: #f8fafc;
|
||||||
|
--el-table-row-hover-bg-color: #f5f8ff;
|
||||||
|
--el-table-border-color: #e5eaf1;
|
||||||
|
border-radius: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-descriptions__label.el-descriptions__cell.is-bordered-label {
|
||||||
|
color: #526078;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width <= 768px) {
|
||||||
|
.asset-information-dialog.el-dialog {
|
||||||
|
width: calc(100vw - 20px) !important;
|
||||||
|
|
||||||
|
.el-dialog__header {
|
||||||
|
padding: 16px 18px 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__body {
|
||||||
|
max-height: calc(100vh - 150px);
|
||||||
|
padding: 18px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__footer {
|
||||||
|
padding: 12px 18px 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .asset-information-dialog.el-dialog {
|
||||||
|
border-color: #2b3a52;
|
||||||
|
|
||||||
|
.el-dialog__header,
|
||||||
|
.el-dialog__footer {
|
||||||
|
border-color: #2b3a52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__title,
|
||||||
|
.el-form-item__label {
|
||||||
|
color: #e5edf8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-table {
|
||||||
|
--el-table-header-bg-color: #202d42;
|
||||||
|
--el-table-row-hover-bg-color: #223451;
|
||||||
|
--el-table-border-color: #2b3a52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-descriptions__label.el-descriptions__cell.is-bordered-label {
|
||||||
|
color: #afbdd0;
|
||||||
|
background: #202d42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -264,7 +264,8 @@
|
|||||||
{
|
{
|
||||||
prop: 'enterprise_name',
|
prop: 'enterprise_name',
|
||||||
label: '企业名称',
|
label: '企业名称',
|
||||||
minWidth: 150
|
minWidth: 200,
|
||||||
|
showOverflowTooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'authorizer_name',
|
prop: 'authorizer_name',
|
||||||
|
|||||||
@@ -69,7 +69,6 @@
|
|||||||
tip="仅支持 UTF-8 单列 CSV,每行一个订单号,最多 1000 行,最大 10MB"
|
tip="仅支持 UTF-8 单列 CSV,每行一个订单号,最多 1000 行,最大 10MB"
|
||||||
@uploading-change="csvUploading = $event"
|
@uploading-change="csvUploading = $event"
|
||||||
@files-change="handleCsvFilesChange"
|
@files-change="handleCsvFilesChange"
|
||||||
@change="createFormRef?.validateField('file')"
|
|
||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="凭证附件">
|
<ElFormItem label="凭证附件">
|
||||||
|
|||||||
@@ -530,7 +530,7 @@
|
|||||||
{
|
{
|
||||||
prop: 'role_desc',
|
prop: 'role_desc',
|
||||||
label: '角色描述',
|
label: '角色描述',
|
||||||
width: 240,
|
minWidth: 240,
|
||||||
showOverflowTooltip: true
|
showOverflowTooltip: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user