feat(ui): converge 6 page-level entity selectors to read-only session tag
- DataQuality / ProductMatrix / AlertList / ActionPlanLibrary / views.GrowthQuality / PredictAccuracy: drop entity el-select (including the "all entities" option), show read-only session entity tag (not clickable), same style as the top bar tag - drop page-level entity param from those requests; backend resolves entity from the session token (assert_entity_scope / get_entity_id) - utils/entity.ts: add sessionEntityName() (cma_entity_name else id map) - P3: ReportCenter header emoji removed; components/GrowthQuality detail drill-down el-dialog -> MyDialog (cma-entity-selectors-converge-6pages-20260914)
This commit is contained in:
@@ -98,7 +98,7 @@
|
|||||||
<el-empty v-else-if="!loading" description="点击「诊断」查看当前账套增长质量" />
|
<el-empty v-else-if="!loading" description="点击「诊断」查看当前账套增长质量" />
|
||||||
|
|
||||||
<!-- 明细下钻弹窗 -->
|
<!-- 明细下钻弹窗 -->
|
||||||
<el-dialog v-model="showDetail" :title="currentDimLabel + ' — ' + (result?.entity_name || '')" width="550px">
|
<MyDialog v-model="showDetail" :title="currentDimLabel + ' — ' + (result?.entity_name || '')" :width="550">
|
||||||
<template v-if="currentDimKey && result?.detail?.[currentDimKey]">
|
<template v-if="currentDimKey && result?.detail?.[currentDimKey]">
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
<span class="detail-score-badge" :class="scoreClass(result.detail[currentDimKey].score)">
|
<span class="detail-score-badge" :class="scoreClass(result.detail[currentDimKey].score)">
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</MyDialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -139,6 +139,7 @@ import { ref, computed } from 'vue'
|
|||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import 'echarts'
|
import 'echarts'
|
||||||
import { predictApi } from '../api/index'
|
import { predictApi } from '../api/index'
|
||||||
|
import MyDialog from './MyDialog.vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|||||||
@@ -23,3 +23,13 @@ export function effectiveEntityId(): number {
|
|||||||
const stored = Number(localStorage.getItem('cma_entity_id'))
|
const stored = Number(localStorage.getItem('cma_entity_id'))
|
||||||
return Number.isNaN(stored) ? 1 : stored
|
return Number.isNaN(stored) ? 1 : stored
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 会话企业显示名:优先 localStorage.cma_entity_name(登录时写入),否则按会话 entity_id 映射 */
|
||||||
|
export function sessionEntityName(): string {
|
||||||
|
const stored = localStorage.getItem('cma_entity_name')
|
||||||
|
if (stored) return stored
|
||||||
|
const id = effectiveEntityId()
|
||||||
|
if (id === 1) return '酣客'
|
||||||
|
if (id === 2) return '博海'
|
||||||
|
return `企业 #${id}`
|
||||||
|
}
|
||||||
|
|||||||
@@ -291,10 +291,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<div style="margin-bottom:12px;display:flex;gap:8px;align-items:center;">
|
<div style="margin-bottom:12px;display:flex;gap:8px;align-items:center;">
|
||||||
<span style="font-weight:500;">COSO内控自检表 — CMA P1内部控制五要素</span>
|
<span style="font-weight:500;">COSO内控自检表 — CMA P1内部控制五要素</span>
|
||||||
<el-select v-model="cosoEntity" size="small" style="width:160px;" @change="loadCosoChecklist">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option label="陕西酣客(白酒经销)" value="hanke" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option label="陕西博海科技(IT服务)" value="bohai" />
|
|
||||||
</el-select>
|
|
||||||
<el-button size="small" @click="loadCosoChecklist" :loading="cosoLoading">刷新</el-button>
|
<el-button size="small" @click="loadCosoChecklist" :loading="cosoLoading">刷新</el-button>
|
||||||
<el-button v-if="cosoData" type="primary" size="small" style="margin-left:12px;">生成改善行动</el-button>
|
<el-button v-if="cosoData" type="primary" size="small" style="margin-left:12px;">生成改善行动</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -350,6 +348,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { actionPlanApi, kpiApi, userApi, okrApi } from '../api/index'
|
import { actionPlanApi, kpiApi, userApi, okrApi } from '../api/index'
|
||||||
import MyDialog from '../components/MyDialog.vue'
|
import MyDialog from '../components/MyDialog.vue'
|
||||||
|
import { sessionEntityName } from '../utils/entity'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -645,7 +644,8 @@ function statusLabel(status: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── COSO内控自检 ──
|
// ── COSO内控自检 ──
|
||||||
const cosoEntity = ref('hanke')
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const cosoData = ref<any>(null)
|
const cosoData = ref<any>(null)
|
||||||
const cosoLoading = ref(false)
|
const cosoLoading = ref(false)
|
||||||
const cosoExpanded = ref<Record<string, boolean>>({})
|
const cosoExpanded = ref<Record<string, boolean>>({})
|
||||||
@@ -657,7 +657,7 @@ function toggleCosoElement(id: string) {
|
|||||||
async function loadCosoChecklist() {
|
async function loadCosoChecklist() {
|
||||||
cosoLoading.value = true
|
cosoLoading.value = true
|
||||||
try {
|
try {
|
||||||
const r: any = await actionPlanApi.cosoChecklist({ entity: cosoEntity.value })
|
const r: any = await actionPlanApi.cosoChecklist()
|
||||||
cosoData.value = r
|
cosoData.value = r
|
||||||
// 默认展开第一个
|
// 默认展开第一个
|
||||||
if (r?.elements?.length > 0) {
|
if (r?.elements?.length > 0) {
|
||||||
|
|||||||
@@ -78,10 +78,8 @@
|
|||||||
<template v-if="activeTab === 'riskMatrix'">
|
<template v-if="activeTab === 'riskMatrix'">
|
||||||
<div style="margin-bottom:12px;display:flex;gap:8px;align-items:center;">
|
<div style="margin-bottom:12px;display:flex;gap:8px;align-items:center;">
|
||||||
<span style="font-weight:500;">风险矩阵 — CMA P2 ERM框架</span>
|
<span style="font-weight:500;">风险矩阵 — CMA P2 ERM框架</span>
|
||||||
<el-select v-model="riskEntity" size="small" style="width:160px;" @change="loadRiskMatrix">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option label="陕西酣客(白酒经销)" value="hanke" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option label="陕西博海科技(IT服务)" value="bohai" />
|
|
||||||
</el-select>
|
|
||||||
<el-button size="small" @click="loadRiskMatrix" :loading="riskLoading">刷新</el-button>
|
<el-button size="small" @click="loadRiskMatrix" :loading="riskLoading">刷新</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -373,6 +371,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
import { alertApi, userApi, actionPlanApi, kpiApi, alertRulesApi } from '../api/index'
|
import { alertApi, userApi, actionPlanApi, kpiApi, alertRulesApi } from '../api/index'
|
||||||
import BotSourceTag from '../components/BotSourceTag.vue'
|
import BotSourceTag from '../components/BotSourceTag.vue'
|
||||||
import RiskCell from '../components/charts/RiskCell.vue'
|
import RiskCell from '../components/charts/RiskCell.vue'
|
||||||
|
import { sessionEntityName } from '../utils/entity'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const activeTab = ref((route.meta?.tab as string) || 'alerts')
|
const activeTab = ref((route.meta?.tab as string) || 'alerts')
|
||||||
@@ -721,7 +720,8 @@ async function loadUsers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── 风险矩阵 ──
|
// ── 风险矩阵 ──
|
||||||
const riskEntity = ref('hanke')
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const riskData = ref<any>(null)
|
const riskData = ref<any>(null)
|
||||||
const riskLoading = ref(false)
|
const riskLoading = ref(false)
|
||||||
const selectedRisk = ref<any>(null)
|
const selectedRisk = ref<any>(null)
|
||||||
@@ -743,7 +743,7 @@ async function loadRiskMatrix() {
|
|||||||
riskLoading.value = true
|
riskLoading.value = true
|
||||||
selectedRisk.value = null
|
selectedRisk.value = null
|
||||||
try {
|
try {
|
||||||
const r: any = await alertApi.riskMatrix({ entity: riskEntity.value })
|
const r: any = await alertApi.riskMatrix()
|
||||||
riskData.value = r
|
riskData.value = r
|
||||||
} catch { ElMessage.error('加载风险矩阵失败') }
|
} catch { ElMessage.error('加载风险矩阵失败') }
|
||||||
riskLoading.value = false
|
riskLoading.value = false
|
||||||
|
|||||||
@@ -198,12 +198,9 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
|
<div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
|
||||||
<span>🛡️ DAMA数据治理规则检查(财务七规则)</span>
|
<span>🛡️ DAMA数据治理规则检查(财务七规则)</span>
|
||||||
<div>
|
<div style="display:flex;align-items:center;gap:8px;">
|
||||||
<el-select v-model="govEntity" style="width:130px;margin-right:8px;" @change="runGovernanceCheck">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option label="全部实体" :value="0" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option label="酣客" :value="1" />
|
|
||||||
<el-option label="博海" :value="2" />
|
|
||||||
</el-select>
|
|
||||||
<el-button type="primary" @click="runGovernanceCheck" :loading="govChecking">重新检查</el-button>
|
<el-button type="primary" @click="runGovernanceCheck" :loading="govChecking">重新检查</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -289,6 +286,7 @@ import { ElMessage } from 'element-plus'
|
|||||||
import VChart from 'vue-echarts'
|
import VChart from 'vue-echarts'
|
||||||
import 'echarts'
|
import 'echarts'
|
||||||
import { dataQualityApi } from '../api/index'
|
import { dataQualityApi } from '../api/index'
|
||||||
|
import { sessionEntityName } from '../utils/entity'
|
||||||
|
|
||||||
const activeTab = ref('kpi')
|
const activeTab = ref('kpi')
|
||||||
const govLoaded = ref(false)
|
const govLoaded = ref(false)
|
||||||
@@ -305,7 +303,8 @@ const govScore = ref(0)
|
|||||||
const govTotalDeduct = ref(0)
|
const govTotalDeduct = ref(0)
|
||||||
const govIssues = ref<any[]>([])
|
const govIssues = ref<any[]>([])
|
||||||
const govCheckedAt = ref('')
|
const govCheckedAt = ref('')
|
||||||
const govEntity = ref(0)
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const govChecking = ref(false)
|
const govChecking = ref(false)
|
||||||
const govRuleMeta = ref<any>({})
|
const govRuleMeta = ref<any>({})
|
||||||
|
|
||||||
@@ -413,9 +412,8 @@ async function runCheck() {
|
|||||||
async function runGovernanceCheck() {
|
async function runGovernanceCheck() {
|
||||||
govChecking.value = true
|
govChecking.value = true
|
||||||
try {
|
try {
|
||||||
const params: any = {}
|
// 会话账套:不再传页面级 entity_id(后端 assert_entity_scope 按 token 绑定账套取数)
|
||||||
if (govEntity.value) params.entity_id = govEntity.value
|
const r: any = await dataQualityApi.governanceCheck()
|
||||||
const r: any = await dataQualityApi.governanceCheck(params)
|
|
||||||
govScore.value = r.score ?? 0
|
govScore.value = r.score ?? 0
|
||||||
govTotalDeduct.value = r.total_deduct ?? 0
|
govTotalDeduct.value = r.total_deduct ?? 0
|
||||||
govIssues.value = r.issues || []
|
govIssues.value = r.issues || []
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>📈 增长质量诊断</h2>
|
<h2>📈 增长质量诊断</h2>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-select v-model="entityId" size="small" style="width:130px" @change="loadData">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option :value="1" label="酣客" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option :value="2" label="博海" />
|
|
||||||
</el-select>
|
|
||||||
<el-select v-model="period" size="small" style="width:140px" @change="loadData" :loading="loadingPeriods">
|
<el-select v-model="period" size="small" style="width:140px" @change="loadData" :loading="loadingPeriods">
|
||||||
<el-option v-for="p in periods" :key="p" :value="p" :label="p" />
|
<el-option v-for="p in periods" :key="p" :value="p" :label="p" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -82,8 +80,10 @@
|
|||||||
import { ref, computed, onMounted, nextTick } from 'vue'
|
import { ref, computed, onMounted, nextTick } from 'vue'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { sessionEntityName } from '@/utils/entity'
|
||||||
|
|
||||||
const entityId = ref(Number(localStorage.getItem('cma_entity_id') || 1))
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const period = ref('2026-06')
|
const period = ref('2026-06')
|
||||||
const periods = ref<string[]>([])
|
const periods = ref<string[]>([])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@@ -129,7 +129,7 @@ const dimensionRows = computed(() => {
|
|||||||
async function loadPeriods() {
|
async function loadPeriods() {
|
||||||
loadingPeriods.value = true
|
loadingPeriods.value = true
|
||||||
try {
|
try {
|
||||||
const r: any = await api.get('/growth-quality/periods', { params: { entity_id: entityId.value } })
|
const r: any = await api.get('/growth-quality/periods')
|
||||||
periods.value = r.data || r || []
|
periods.value = r.data || r || []
|
||||||
if (periods.value.length && !periods.value.includes(period.value)) {
|
if (periods.value.length && !periods.value.includes(period.value)) {
|
||||||
period.value = periods.value[periods.value.length - 1]
|
period.value = periods.value[periods.value.length - 1]
|
||||||
@@ -141,7 +141,7 @@ async function loadPeriods() {
|
|||||||
async function loadData() {
|
async function loadData() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const r: any = await api.get('/growth-quality/diagnosis', { params: { entity_id: entityId.value, period: period.value } })
|
const r: any = await api.get('/growth-quality/diagnosis', { params: { period: period.value } })
|
||||||
const d = r.data || r || {}
|
const d = r.data || r || {}
|
||||||
overall.value = d.overall ?? null
|
overall.value = d.overall ?? null
|
||||||
level.value = d.level || ''
|
level.value = d.level || ''
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h3>预测准确率报表</h3>
|
<h3>预测准确率报表</h3>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-select v-model="entityId" size="small" style="width:200px;" @change="loadAccuracy">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option label="陕西酣客(白酒经销)" :value="1" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option label="陕西博海科技(IT服务)" :value="2" />
|
|
||||||
</el-select>
|
|
||||||
<el-button size="small" @click="loadAccuracy" :loading="loading" type="primary">刷新</el-button>
|
<el-button size="small" @click="loadAccuracy" :loading="loading" type="primary">刷新</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,9 +101,11 @@
|
|||||||
import { ref, nextTick, onMounted } from 'vue'
|
import { ref, nextTick, onMounted } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { predictApi } from '../api/index'
|
import { predictApi } from '../api/index'
|
||||||
|
import { sessionEntityName } from '../utils/entity'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const entityId = ref(1)
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const accuracyData = ref<any[]>([])
|
const accuracyData = ref<any[]>([])
|
||||||
const summary = ref<any>({})
|
const summary = ref<any>({})
|
||||||
const accuracyChartRef = ref<HTMLElement | null>(null)
|
const accuracyChartRef = ref<HTMLElement | null>(null)
|
||||||
@@ -114,7 +114,7 @@ let accuracyChart: any = null
|
|||||||
async function loadAccuracy() {
|
async function loadAccuracy() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const r: any = await predictApi.forecastAccuracy({ entity_id: entityId.value })
|
const r: any = await predictApi.forecastAccuracy()
|
||||||
accuracyData.value = r.data || []
|
accuracyData.value = r.data || []
|
||||||
summary.value = r.summary || {}
|
summary.value = r.summary || {}
|
||||||
nextTick(() => renderAccuracyChart())
|
nextTick(() => renderAccuracyChart())
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>🌟 波士顿产品矩阵</h2>
|
<h2>🌟 波士顿产品矩阵</h2>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-select v-model="entityId" size="small" style="width:130px" @change="loadData">
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-option :value="1" label="酣客" />
|
<el-tag size="small" type="primary" effect="plain">{{ entityLabel }}</el-tag>
|
||||||
<el-option :value="2" label="博海" />
|
|
||||||
</el-select>
|
|
||||||
<el-select v-model="months" size="small" style="width:140px" @change="loadData">
|
<el-select v-model="months" size="small" style="width:140px" @change="loadData">
|
||||||
<el-option :value="3" label="近3月" />
|
<el-option :value="3" label="近3月" />
|
||||||
<el-option :value="6" label="近6月" />
|
<el-option :value="6" label="近6月" />
|
||||||
@@ -85,8 +83,10 @@
|
|||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
import { sessionEntityName } from '@/utils/entity'
|
||||||
|
|
||||||
const entityId = ref<number>(Number(localStorage.getItem('cma_entity_id') || 1))
|
// 企业只读标识(账套由登录窗口选定,页内无切换入口)
|
||||||
|
const entityLabel = ref(sessionEntityName())
|
||||||
const months = ref(3)
|
const months = ref(3)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const hasData = ref(false)
|
const hasData = ref(false)
|
||||||
@@ -109,7 +109,7 @@ function quadrantTag(k: string) { return quadrantMeta[k]?.tag || 'info' }
|
|||||||
async function loadData() {
|
async function loadData() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const r = await api.get('/products/matrix', { params: { entity_id: entityId.value, months: months.value } })
|
const r = await api.get('/products/matrix', { params: { months: months.value } })
|
||||||
const d = r.data || r
|
const d = r.data || r
|
||||||
hasData.value = d.has_data
|
hasData.value = d.has_data
|
||||||
message.value = d.message || ''
|
message.value = d.message || ''
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="report-page">
|
<div class="report-page">
|
||||||
<!-- 顶部 -->
|
<!-- 顶部 -->
|
||||||
<div class="report-header">
|
<div class="report-header">
|
||||||
<h3 class="page-title">📊 CMA管理报表</h3>
|
<h3 class="page-title">CMA管理报表</h3>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
<!-- 企业只读标识(不可点):账套由登录窗口选定,页内无切换入口 -->
|
||||||
<el-tag size="small" type="primary" effect="plain" class="entity-tag">{{ currentEntityNameTag }}</el-tag>
|
<el-tag size="small" type="primary" effect="plain" class="entity-tag">{{ currentEntityNameTag }}</el-tag>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
@change="onPeriodChange"
|
@change="onPeriodChange"
|
||||||
/>
|
/>
|
||||||
<el-button text size="small" :loading="loading" @click="loadAll">刷新</el-button>
|
<el-button text size="small" :loading="loading" @click="loadAll">刷新</el-button>
|
||||||
<el-button type="primary" size="small" @click="openDupont">📊 杜邦分析</el-button>
|
<el-button type="primary" size="small" @click="openDupont">杜邦分析</el-button>
|
||||||
<el-button type="success" size="small" @click="openSubjectManage">📋 科目打标</el-button>
|
<el-button type="success" size="small" @click="openSubjectManage">📋 科目打标</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user