Просмотр исходного кода

feat(web-admin): gate archive actions and price columns by menu codes

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 1 месяц назад
Родитель
Сommit
b92418fa4a
1 измененных файлов с 48 добавлено и 7 удалено
  1. 48 7
      web-admin/src/views/pl/plan-archive/index.vue

+ 48 - 7
web-admin/src/views/pl/plan-archive/index.vue

@@ -88,6 +88,7 @@
             @clear="handleQuickSearchClear"
           />
           <el-button
+            v-if="canArchive"
             class="btn-main"
             type="primary"
             :disabled="!selectedPlan || selectedPlan.followStatus === 'cancelled'"
@@ -503,7 +504,7 @@
               </template>
             </el-table-column>
             <el-table-column
-              v-if="isColumnVisible('productUnitPrice')"
+              v-if="isArchiveColumnVisible('productUnitPrice')"
               label="单价(元)"
               min-width="100"
               align="right"
@@ -522,7 +523,7 @@
               </template>
             </el-table-column>
             <el-table-column
-              v-if="isColumnVisible('productAmount')"
+              v-if="isArchiveColumnVisible('productAmount')"
               label="金额(元)"
               min-width="100"
               align="right"
@@ -576,10 +577,11 @@
       v-model:visible="viewVisible"
       :plan-id="viewPlanId"
       show-archive-io-fields
+      :show-archive-price-fields="canViewPrice"
     >
       <template v-if="viewingPlan" #hero-actions>
         <el-button
-          v-if="viewingPlan.followStatus !== 'cancelled'"
+          v-if="canArchive && viewingPlan.followStatus !== 'cancelled'"
           class="btn-main"
           type="primary"
           @click="handleArchive(viewingPlan)"
@@ -617,6 +619,7 @@ import {
   Search
 } from '@element-plus/icons-vue'
 import { planApi, type Plan } from '@/api/pl'
+import { fetchGetMenuCodes } from '@/api/auth'
 import { pickBxData } from '@/utils/http/bx'
 import PlPlanContractCell from '@/components/business/pl-plan-contract-cell/index.vue'
 import PlPlanArchiveDialog from '@/components/business/pl-plan-archive-dialog/index.vue'
@@ -677,6 +680,8 @@ const PLAN_MERGE_COLUMN_PROPS = [
 ] as const
 
 const loading = ref(false)
+const canArchive = ref(false)
+const canViewPrice = ref(false)
 const viewVisible = ref(false)
 const viewPlanId = ref('')
 const viewDialogRef = ref<InstanceType<typeof PlPlanViewDialog>>()
@@ -685,7 +690,9 @@ const archivePlanId = ref('')
 const erpBatchLoading = ref(false)
 const planList = ref<Plan[]>([])
 
-const listColumnDefs = [
+const PRICE_COLUMN_PROPS = new Set(['productUnitPrice', 'productAmount'])
+
+const allListColumnDefs = [
   { prop: 'planDate', label: '计划日期' },
   { prop: 'archiveStatus', label: '归档状态' },
   { prop: 'followStatus', label: '跟进状态' },
@@ -712,13 +719,42 @@ const listColumnDefs = [
   { prop: 'productAmount', label: '金额(元)' }
 ]
 
+const listColumnDefs = computed(() =>
+  canViewPrice.value
+    ? allListColumnDefs
+    : allListColumnDefs.filter((def) => !PRICE_COLUMN_PROPS.has(def.prop))
+)
+
 const {
   visibleColumns,
   checkAll,
   isIndeterminate,
   isColumnVisible,
   resetToDefault
-} = usePersistedListColumns('pl-plan-archive-list-columns-v5', listColumnDefs)
+} = usePersistedListColumns('pl-plan-archive-list-columns-v6', allListColumnDefs)
+
+function isArchiveColumnVisible(prop: string) {
+  if (PRICE_COLUMN_PROPS.has(prop) && !canViewPrice.value) return false
+  return isColumnVisible(prop)
+}
+
+watch(canViewPrice, (ok) => {
+  if (ok) return
+  visibleColumns.value = visibleColumns.value.filter((prop) => !PRICE_COLUMN_PROPS.has(prop))
+})
+
+async function loadArchivePermissions() {
+  try {
+    const perm = await fetchGetMenuCodes()
+    const all = !!perm?.all || !!perm?.isSuperAdmin
+    const codes = perm?.menuCodes || []
+    canArchive.value = all || codes.includes('pl:plan-archive:archive')
+    canViewPrice.value = all || codes.includes('pl:plan-archive:price')
+  } catch {
+    canArchive.value = false
+    canViewPrice.value = false
+  }
+}
 
 const selectedRows = ref<Plan[]>([])
 
@@ -754,8 +790,8 @@ const archiveStatsRowColumns = computed((): StatsRowColumn[] => {
     { key: '__index', interactive: false },
     { key: 'planNo', interactive: true, prop: 'planNo' }
   ]
-  for (const def of listColumnDefs) {
-    if (!isColumnVisible(def.prop)) continue
+  for (const def of listColumnDefs.value) {
+    if (!isArchiveColumnVisible(def.prop)) continue
     cols.push({
       key: def.prop,
       interactive: def.prop !== 'stopKind',
@@ -975,6 +1011,10 @@ function archiveButtonLabel(row: Plan) {
 }
 
 async function handleArchive(row: Plan) {
+  if (!canArchive.value) {
+    ElMessage.warning('无运输计划归档操作权限')
+    return
+  }
   // 打开归档弹窗:已归档走调整;未归档/已暂存可直接打开(证书齐备仅在「确认归档」时校验,以便支持暂存)
   archivePlanId.value = row.id
   archiveDialogVisible.value = true
@@ -1048,6 +1088,7 @@ useDbInstantSearch(
 )
 
 onMounted(() => {
+  loadArchivePermissions()
   fetchData()
 
   nextTick(() => recalcTableHeight())