This commit is contained in:
@@ -194,8 +194,6 @@
|
|||||||
import { mittBus } from '@/utils/sys'
|
import { mittBus } from '@/utils/sys'
|
||||||
import { useMenuStore } from '@/store/modules/menu'
|
import { useMenuStore } from '@/store/modules/menu'
|
||||||
import { useNotificationStore } from '@/store/modules/notification'
|
import { useNotificationStore } from '@/store/modules/notification'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
|
||||||
import { NOTIFICATION_PERMISSIONS } from '@/config/constants/notification'
|
|
||||||
import AppConfig from '@/config'
|
import AppConfig from '@/config'
|
||||||
const isWindows = navigator.userAgent.includes('Windows')
|
const isWindows = navigator.userAgent.includes('Windows')
|
||||||
const { locale } = useI18n()
|
const { locale } = useI18n()
|
||||||
@@ -203,7 +201,6 @@
|
|||||||
const settingStore = useSettingStore()
|
const settingStore = useSettingStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const notificationStore = useNotificationStore()
|
const notificationStore = useNotificationStore()
|
||||||
const { hasAuth } = useAuth()
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -262,12 +259,10 @@
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initLanguage()
|
initLanguage()
|
||||||
if (hasAuth(NOTIFICATION_PERMISSIONS.page)) {
|
|
||||||
void notificationStore.refreshUnreadCount().catch(() => undefined)
|
void notificationStore.refreshUnreadCount().catch(() => undefined)
|
||||||
unreadTimer = window.setInterval(() => {
|
unreadTimer = window.setInterval(() => {
|
||||||
void notificationStore.refreshUnreadCount().catch(() => undefined)
|
void notificationStore.refreshUnreadCount().catch(() => undefined)
|
||||||
}, 30_000)
|
}, 30_000)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let unreadTimer: number | undefined
|
let unreadTimer: number | undefined
|
||||||
|
|||||||
@@ -3,12 +3,7 @@
|
|||||||
<div class="notice" @click.stop>
|
<div class="notice" @click.stop>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<span class="text">通知</span>
|
<span class="text">通知</span>
|
||||||
<button
|
<button class="read-all" type="button" @click="handleMarkAllRead">
|
||||||
v-if="hasAuth(NOTIFICATION_PERMISSIONS.readAll)"
|
|
||||||
class="read-all"
|
|
||||||
type="button"
|
|
||||||
@click="handleMarkAllRead"
|
|
||||||
>
|
|
||||||
全部已读
|
全部已读
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,8 +57,6 @@
|
|||||||
import { NotificationService } from '@/api/modules'
|
import { NotificationService } from '@/api/modules'
|
||||||
import type { NotificationCategory, NotificationItem } from '@/types/api'
|
import type { NotificationCategory, NotificationItem } from '@/types/api'
|
||||||
import { useNotificationStore } from '@/store/modules/notification'
|
import { useNotificationStore } from '@/store/modules/notification'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
|
||||||
import { NOTIFICATION_PERMISSIONS } from '@/config/constants/notification'
|
|
||||||
import { navigateNotificationTarget } from '@/utils/business/notificationNavigation'
|
import { navigateNotificationTarget } from '@/utils/business/notificationNavigation'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
|
|
||||||
@@ -72,7 +65,6 @@
|
|||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const notificationStore = useNotificationStore()
|
const notificationStore = useNotificationStore()
|
||||||
const { hasAuth } = useAuth()
|
|
||||||
const activeCategory = ref<'all' | NotificationCategory>('all')
|
const activeCategory = ref<'all' | NotificationCategory>('all')
|
||||||
const visible = computed(() => props.modelValue)
|
const visible = computed(() => props.modelValue)
|
||||||
|
|
||||||
@@ -116,10 +108,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleNotificationClick = async (item: NotificationItem) => {
|
const handleNotificationClick = async (item: NotificationItem) => {
|
||||||
if (!hasAuth(NOTIFICATION_PERMISSIONS.read)) {
|
|
||||||
ElMessage.warning('您没有标记通知已读的权限')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const targetResponse = await NotificationService.getTarget(item.id)
|
const targetResponse = await NotificationService.getTarget(item.id)
|
||||||
const readResponse = await notificationStore.markRead(item.id)
|
const readResponse = await notificationStore.markRead(item.id)
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
export const NOTIFICATION_PERMISSIONS = {
|
|
||||||
page: 'notifications:view',
|
|
||||||
read: 'notifications:read',
|
|
||||||
readAll: 'notifications:read_all'
|
|
||||||
} as const
|
|
||||||
@@ -33,8 +33,6 @@
|
|||||||
:pageSize="pagination.pageSize"
|
:pageSize="pagination.pageSize"
|
||||||
:total="pagination.total"
|
:total="pagination.total"
|
||||||
:marginTop="10"
|
:marginTop="10"
|
||||||
:actions="getActions"
|
|
||||||
:actionsWidth="140"
|
|
||||||
@size-change="handleSizeChange"
|
@size-change="handleSizeChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
>
|
>
|
||||||
@@ -50,7 +48,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { h, onMounted, reactive, ref, computed } from 'vue'
|
import { h, onMounted, reactive, ref, computed } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ElMessage, ElTag } from 'element-plus'
|
import { ElButton, ElMessage, ElTag } from 'element-plus'
|
||||||
import { AssetService, PackageManageService, ShopService } from '@/api/modules'
|
import { AssetService, PackageManageService, ShopService } from '@/api/modules'
|
||||||
import type {
|
import type {
|
||||||
ExpiringAssetItem,
|
ExpiringAssetItem,
|
||||||
@@ -187,8 +185,7 @@
|
|||||||
{ label: '店铺', prop: 'shop_name' },
|
{ label: '店铺', prop: 'shop_name' },
|
||||||
{ label: '当前套餐', prop: 'package_name' },
|
{ label: '当前套餐', prop: 'package_name' },
|
||||||
{ label: '预计最终到期', prop: 'estimated_final_expires_at' },
|
{ label: '预计最终到期', prop: 'estimated_final_expires_at' },
|
||||||
{ label: '剩余天数', prop: 'days_until_final_expiry' },
|
{ label: '剩余天数', prop: 'days_until_final_expiry' }
|
||||||
{ label: '临期等级', prop: 'expiry_level_name' }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const getExpiryClass = (level?: string | null) => {
|
const getExpiryClass = (level?: string | null) => {
|
||||||
@@ -244,7 +241,16 @@
|
|||||||
label: '资产标识',
|
label: '资产标识',
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
showOverflowTooltip: true,
|
showOverflowTooltip: true,
|
||||||
formatter: (row: ExpiringAssetItem) => row.identifier || '-'
|
formatter: (row: ExpiringAssetItem) =>
|
||||||
|
h(
|
||||||
|
ElButton,
|
||||||
|
{
|
||||||
|
type: 'primary',
|
||||||
|
link: true,
|
||||||
|
onClick: () => goToAsset(row)
|
||||||
|
},
|
||||||
|
() => row.identifier || '-'
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: 'shop_name',
|
prop: 'shop_name',
|
||||||
@@ -279,12 +285,6 @@
|
|||||||
h(ElTag, { type: getExpiryTagType(row.expiry_level), size: 'small' }, () =>
|
h(ElTag, { type: getExpiryTagType(row.expiry_level), size: 'small' }, () =>
|
||||||
row.days_until_final_expiry == null ? '-' : `${row.days_until_final_expiry}天`
|
row.days_until_final_expiry == null ? '-' : `${row.days_until_final_expiry}天`
|
||||||
)
|
)
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'expiry_level_name',
|
|
||||||
label: '临期等级',
|
|
||||||
width: 120,
|
|
||||||
formatter: (row: ExpiringAssetItem) => row.expiry_level_name || '-'
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -371,10 +371,6 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActions = (row: ExpiringAssetItem) => [
|
|
||||||
{ label: '查看资产', type: 'primary' as const, handler: () => goToAsset(row) }
|
|
||||||
]
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const assetType = route.query.asset_type
|
const assetType = route.query.asset_type
|
||||||
if (assetType === 'card' || assetType === 'iot_card' || assetType === 'device') {
|
if (assetType === 'card' || assetType === 'iot_card' || assetType === 'device') {
|
||||||
|
|||||||
@@ -54,7 +54,24 @@
|
|||||||
>
|
>
|
||||||
<span class="package-option">{{ pkg.package_name }}</span>
|
<span class="package-option">{{ pkg.package_name }}</span>
|
||||||
</ElOption>
|
</ElOption>
|
||||||
|
<template #empty>
|
||||||
|
<div class="package-empty">
|
||||||
|
{{
|
||||||
|
packageLoading
|
||||||
|
? '正在加载套餐...'
|
||||||
|
: form.series_id
|
||||||
|
? '该套餐系列下暂无可用套餐'
|
||||||
|
: '请先选择套餐系列'
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</ElSelect>
|
</ElSelect>
|
||||||
|
<div
|
||||||
|
v-if="form.series_id && !packageLoading && packageOptions.length === 0"
|
||||||
|
class="package-empty-tip"
|
||||||
|
>
|
||||||
|
该套餐系列下暂无可用套餐
|
||||||
|
</div>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem label="支付方式" prop="payment_method">
|
<ElFormItem label="支付方式" prop="payment_method">
|
||||||
@@ -547,6 +564,19 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.package-empty {
|
||||||
|
padding: 8px 0;
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-empty-tip {
|
||||||
|
margin-top: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
.create-form {
|
.create-form {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</ElSelect>
|
</ElSelect>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
|
|
||||||
<ElFormItem v-if="requiresTargetId" label="目标 ID" prop="target_id">
|
<ElFormItem v-if="requiresTargetId" :label="targetLabel" prop="target_id">
|
||||||
<ElSelect
|
<ElSelect
|
||||||
v-model="form.target_id"
|
v-model="form.target_id"
|
||||||
filterable
|
filterable
|
||||||
@@ -284,6 +284,9 @@
|
|||||||
const targetPlaceholder = computed(() =>
|
const targetPlaceholder = computed(() =>
|
||||||
form.operation_type === 'assign_shop' ? '请选择启用的目标店铺' : '请选择启用的套餐系列'
|
form.operation_type === 'assign_shop' ? '请选择启用的目标店铺' : '请选择启用的套餐系列'
|
||||||
)
|
)
|
||||||
|
const targetLabel = computed(() =>
|
||||||
|
form.operation_type === 'assign_shop' ? '选择店铺' : '选择套餐系列'
|
||||||
|
)
|
||||||
const createDrawerBusy = computed(() => submitting.value || fileUploading.value)
|
const createDrawerBusy = computed(() => submitting.value || fileUploading.value)
|
||||||
|
|
||||||
const getOperationLabel = (operationType: DeviceImportTaskOperationType) => {
|
const getOperationLabel = (operationType: DeviceImportTaskOperationType) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user