mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 18:10:30 +08:00
feat(m9): add subscription report config (localStorage MVP)
This commit is contained in:
@@ -136,6 +136,7 @@ const menuItems = [
|
||||
{ path: "/devices", icon: "🖥️", label: "设备管理", roles: ["SYS_ADMIN","SALES","DELIVERY"] },
|
||||
{ path: "/todos", icon: "🔔", label: "待办中心", roles: ["SYS_ADMIN","SALES","LICENSE_OPS"] },
|
||||
{ path: "/reports/contract-sn", icon: "📊", label: "报表中心", roles: ["SYS_ADMIN"] },
|
||||
{ path: "/reports/subscriptions", icon: "📧", label: "报表订阅", roles: ["SYS_ADMIN"] },
|
||||
];
|
||||
|
||||
const visibleMenu = computed(() => menuItems.filter(m => auth.hasAnyRole(m.roles)));
|
||||
|
||||
@@ -188,6 +188,12 @@ const routes = [
|
||||
component: () => import("../views/ProfileView.vue"),
|
||||
meta: { roles: ["SYS_ADMIN", "SALES", "LICENSE_OPS"], title: "个人设置" },
|
||||
},
|
||||
{
|
||||
path: "reports/subscriptions",
|
||||
name: "report-subscriptions",
|
||||
component: () => import("../views/SubscriptionReportView.vue"),
|
||||
meta: { roles: ["SYS_ADMIN"], title: "报表订阅" },
|
||||
},
|
||||
{
|
||||
path: "reports/project-health",
|
||||
name: "project-health",
|
||||
|
||||
@@ -44,6 +44,7 @@ const allModuleLinks = [
|
||||
{ to: "/devices", label: "设备管理", roles: ["SYS_ADMIN", "SALES", "DELIVERY"] },
|
||||
{ to: "/todos", label: "待办中心", roles: ["SYS_ADMIN", "SALES", "LICENSE_OPS"] },
|
||||
{ to: "/reports/contract-sn", label: "报表中心", roles: ["SYS_ADMIN"] },
|
||||
{ to: "/reports/subscriptions", label: "报表订阅", roles: ["SYS_ADMIN"] },
|
||||
];
|
||||
|
||||
const visibleModuleLinks = computed(() => allModuleLinks.filter((l) => auth.hasAnyRole(l.roles)));
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const STORAGE_KEY = 'craftlabs_report_subscriptions'
|
||||
const subscriptions = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const editingIndex = ref(-1)
|
||||
const form = ref({ reportType: 'contract-sn', schedule: 'weekly', email: '', enabled: true })
|
||||
|
||||
function load() {
|
||||
try {
|
||||
const data = localStorage.getItem(STORAGE_KEY)
|
||||
subscriptions.value = data ? JSON.parse(data) : []
|
||||
} catch { subscriptions.value = [] }
|
||||
}
|
||||
|
||||
function save() {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(subscriptions.value))
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
editingIndex.value = -1
|
||||
form.value = { reportType: 'contract-sn', schedule: 'weekly', email: '', enabled: true }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function openEdit(idx) {
|
||||
editingIndex.value = idx
|
||||
form.value = { ...subscriptions.value[idx] }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
if (editingIndex.value >= 0) {
|
||||
subscriptions.value[editingIndex.value] = { ...form.value }
|
||||
} else {
|
||||
subscriptions.value.push({ ...form.value, id: Date.now() })
|
||||
}
|
||||
save()
|
||||
dialogVisible.value = false
|
||||
ElMessage.success('订阅已保存')
|
||||
}
|
||||
|
||||
function handleDelete(idx) {
|
||||
subscriptions.value.splice(idx, 1)
|
||||
save()
|
||||
ElMessage.success('订阅已删除')
|
||||
}
|
||||
|
||||
function toggleEnabled(idx) {
|
||||
subscriptions.value[idx].enabled = !subscriptions.value[idx].enabled
|
||||
save()
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="toolbar">
|
||||
<span class="title">报表订阅</span>
|
||||
<el-button type="success" @click="openCreate">新建订阅</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-empty v-if="subscriptions.length === 0" description="暂未配置报表订阅" />
|
||||
<el-table v-else :data="subscriptions" stripe>
|
||||
<el-table-column label="报表类型" width="160">
|
||||
<template #default="{ row }">
|
||||
{{ row.reportType === 'contract-sn' ? '履约对账' : row.reportType === 'callback-stats' ? 'Callback 统计' : row.reportType }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="schedule" label="推送频率" width="120" />
|
||||
<el-table-column prop="email" label="接收邮箱" min-width="200" />
|
||||
<el-table-column label="启用" width="80">
|
||||
<template #default="{ row, $index }">
|
||||
<el-switch :model-value="row.enabled" @change="toggleEnabled($index)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="{ $index }">
|
||||
<el-button type="primary" link @click="openEdit($index)">编辑</el-button>
|
||||
<el-button type="danger" link @click="handleDelete($index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="editingIndex >= 0 ? '编辑订阅' : '新建订阅'" width="480px">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="报表类型" required>
|
||||
<el-select v-model="form.reportType" style="width:100%">
|
||||
<el-option label="履约对账" value="contract-sn" />
|
||||
<el-option label="Callback 统计" value="callback-stats" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="推送频率" required>
|
||||
<el-select v-model="form.schedule" style="width:100%">
|
||||
<el-option label="每日" value="daily" />
|
||||
<el-option label="每周" value="weekly" />
|
||||
<el-option label="每月" value="monthly" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="接收邮箱" required>
|
||||
<el-input v-model="form.email" placeholder="email@example.com" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.toolbar { display: flex; justify-content: space-between; align-items: center; }
|
||||
.title { font-weight: 600; font-size: 16px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user