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

feat:新增监审项目管理-按钮权限
fix:修补成本监审辅助管-按钮权限的bug,成本监审表模版管理的bug

cb_luzhixia 1 месяц назад
Родитель
Сommit
47488ee8d3
26 измененных файлов с 1124 добавлено и 418 удалено
  1. 8 0
      src/api/auditInitiation.js
  2. 4 4
      src/api/costFormManage.js
  3. 4 4
      src/api/costSurveyFdTemplate.js
  4. 1 0
      src/components/costAudit/CostAuditDialog.vue
  5. 9 1
      src/components/costAudit/EstablishmentDialog.vue
  6. 8 1
      src/components/costAudit/SelectCatalogDialog.vue
  7. 2 2
      src/components/layouts/HtSideBar/components/HtMenuItem.vue
  8. 4 3
      src/components/layouts/HtSideBar/components/HtSubmenu.vue
  9. 43 1
      src/mixins/useDict.js
  10. 10 0
      src/plugins/index.js
  11. 2 148
      src/plugins/permissions.js
  12. 274 0
      src/plugins/regionPermission.js
  13. 24 12
      src/views/costAudit/baseInfo/auditDocManage/index.vue
  14. 3 0
      src/views/costAudit/baseInfo/auditEntityManage/index.vue
  15. 7 1
      src/views/costAudit/baseInfo/catalogManage/index.vue
  16. 14 4
      src/views/costAudit/baseInfo/costFormManage/index.vue
  17. 136 58
      src/views/costAudit/baseInfo/costFormManage/infoMaintain.vue
  18. 171 80
      src/views/costAudit/baseInfo/costVerifyManage/index.vue
  19. 21 5
      src/views/costAudit/baseInfo/financeSheetManage/index.vue
  20. 239 48
      src/views/costAudit/baseInfo/financeSheetManage/infoMaintain.vue
  21. 53 20
      src/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/RegionSelector.vue
  22. 26 4
      src/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/index.vue
  23. 3 3
      src/views/costAudit/projectInfo/auditProjectManage/initiation/index.vue
  24. 10 11
      src/views/costAudit/projectInfo/auditProjectManage/memoManage/memoManageMixin.js
  25. 19 4
      src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/index.vue
  26. 29 4
      src/views/home/index.vue

+ 8 - 0
src/api/auditInitiation.js

@@ -1,3 +1,11 @@
+/*
+ * @Author: cb_luzhixia cb_luzhixia@163.com
+ * @Date: 2025-10-29 19:19:31
+ * @LastEditors: cb_luzhixia cb_luzhixia@163.com
+ * @LastEditTime: 2025-11-11 10:35:28
+ * @FilePath: \cbjsxt-front-master\src\api\auditInitiation.js
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
 import request from '@/utils/request'
 const url = window.context.form
 

+ 4 - 4
src/api/costFormManage.js

@@ -84,11 +84,11 @@ export function getCostFormVersionsByTemplateId(params) {
 }
 
 // 获取所有成本核定表模板数据
-export function getCostFormDataStorageTables(params) {
+export function getCostFormDataStorageTables(data) {
   return request({
-    url: `${url}/costVerifyTemplate/v1/listAll`,
-    method: 'get',
-    params: { ...params },
+    url: `${url}/costVerifyTemplate/v1/listPage`,
+    method: 'post',
+    data,
   })
 }
 

+ 4 - 4
src/api/costSurveyFdTemplate.js

@@ -56,11 +56,11 @@ export function getSurveyFdVersionsByTemplateId(params) {
   })
 }
 
-export function getSurveyFdList(params) {
+export function getSurveyFdList(data) {
   return request({
-    url: `${url}/costSurveyFdTemplate/v1/listAll`,
-    method: 'get',
-    params,
+    url: `${url}/costSurveyFdTemplate/v1/listPage`,
+    method: 'post',
+    data,
   })
 }
 

+ 1 - 0
src/components/costAudit/CostAuditDialog.vue

@@ -210,6 +210,7 @@
 
 <style scoped>
   .dialog-content {
+    min-height: 50px;
     max-height: 520px;
     overflow-y: auto;
     overflow-x: hidden;

+ 9 - 1
src/components/costAudit/EstablishmentDialog.vue

@@ -569,7 +569,15 @@
         } else {
           // 当弹窗显示时初始化数据
           if (val) {
-            this.formData.areaCode = ''
+            // this.formData.areaCode = ''
+            if (this.$permission.getUserInfo()) {
+              let user = this.$permission.getUserInfo()
+              if (user.dataScope === 1) {
+                this.formData.areaCode = user.cityCode
+              } else if (user.dataScope === 2) {
+                this.formData.areaCode = user.countyCode
+              }
+            }
             // 其他初始化逻辑
           }
           // 当弹窗关闭时重置表单

+ 8 - 1
src/components/costAudit/SelectCatalogDialog.vue

@@ -5,9 +5,10 @@
     :visible="dialogVisible"
     :width="dialogWidth"
     :close-on-click-modal="false"
-    :show-confirm-btn="true"
+    :show-confirm-btn="!isViewMode"
     :show-cancel-btn="true"
     :confirm-loading="submitting"
+    :cancel-text="isViewMode ? '关闭' : '取消'"
     @confirm="handleConfirm"
     @cancel="handleCancel"
     @close="handleCancel"
@@ -18,6 +19,7 @@
       :placeholder="formItem.placeholder || catalogProps.placeholder"
       v-bind="catalogProps"
       style="width: 100%"
+      :disabled="isViewMode"
     ></el-cascader>
   </CostAuditDialog>
 </template>
@@ -54,6 +56,11 @@
         type: String,
         default: '',
       },
+      // 是否为查看模式
+      isViewMode: {
+        type: Boolean,
+        default: false,
+      },
     },
     data() {
       return {

+ 2 - 2
src/components/layouts/HtSideBar/components/HtMenuItem.vue

@@ -174,8 +174,8 @@
     }
   }
   .svg-icon {
-    width: 16px;
-    height: 16px;
+    width: 24px;
+    height: 24px;
     object-fit: contain;
     filter: brightness(0) invert(1);
   }

+ 4 - 3
src/components/layouts/HtSideBar/components/HtSubmenu.vue

@@ -113,12 +113,13 @@
       color: var(--themeColor);
     }
   }
+
   .icon-svg {
-    width: 16px;
-    height: 16px;
+    width: 24px;
+    height: 24px;
     object-fit: contain;
     filter: brightness(0) invert(1);
-    margin-right: 0;
     margin-right: 4px;
+    vertical-align: middle;
   }
 </style>

+ 43 - 1
src/mixins/useDict.js

@@ -120,6 +120,7 @@ export const regionMixin = {
   data() {
     return {
       districtTree: [], // 省市区数据
+      districtTreeData: [], // 省市区数据
       provinces: [], // 省份城市数据
       regionNameMap: {}, // 存储区域代码和名称
       districtTreeCascaderProps: {
@@ -163,7 +164,48 @@ export const regionMixin = {
   methods: {
     getDistrictTreeData() {
       getDistrictTree().then((res) => {
-        this.districtTree = res.value
+        this.districtTreeData = res.value
+        this.districtTree = this.districtTreeData
+        if (this.$permission.isAdminOrProvince()) {
+          // 管理员或省级权限,显示所有数据
+          this.districtTree = this.districtTreeData
+        } else {
+          // 非管理员且数据范围为区域时,筛选出当前用户区域下的市区数据
+          let user = this.$permission.getUserInfo()
+          if (user.dataScope === 1) {
+            let arr = []
+            this.districtTreeData.forEach((item) => {
+              if (item.children) {
+                item.children.forEach((child) => {
+                  if (child.code === user.cityCode) {
+                    arr.push(child)
+                  }
+                })
+              }
+            })
+            this.districtTreeData = arr
+          } else if (user.dataScope === 2) {
+            // 只返回当前县的
+
+            let arr = []
+            this.districtTreeData.forEach((item) => {
+              if (item.children) {
+                item.children.forEach((child) => {
+                  if (child.code === user.cityCode) {
+                    if (child.children) {
+                      child.children = child.children.filter(
+                        (c) => c.code === user.countyCode
+                      )
+                    }
+                    arr.push(child)
+                  }
+                })
+              }
+            })
+            this.districtTreeData = arr
+          }
+          this.districtTree = this.districtTreeData
+        }
       })
     },
     // 获取所有省份

+ 10 - 0
src/plugins/index.js

@@ -1,3 +1,11 @@
+/*
+ * @Author: cb_luzhixia cb_luzhixia@163.com
+ * @Date: 2025-11-10 21:49:58
+ * @LastEditors: cb_luzhixia cb_luzhixia@163.com
+ * @LastEditTime: 2025-11-11 10:37:14
+ * @FilePath: \cbjsxt-front-master\src\plugins\index.js
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
 /* 公共引入,勿随意修改,修改时需经过确认 */
 import Vue from 'vue'
 import './element'
@@ -10,11 +18,13 @@ import '@/styles/base.scss'
 import '@/config/permission'
 import '@/utils/errorLog'
 import permissions from './permissions'
+import regionPermission from './regionPermission'
 import Global from '@/utils/global'
 import VueClipboard from 'vue-clipboard2'
 import fullscreen from 'vue-fullscreen'
 
 Vue.use(Global)
 Vue.use(permissions)
+Vue.use(regionPermission)
 Vue.use(VueClipboard)
 Vue.use(fullscreen)

+ 2 - 148
src/plugins/permissions.js

@@ -1,4 +1,6 @@
 import store from '@/store'
+// 导入区域权限指令
+import { regionPermission } from './regionPermission'
 
 // 现有权限指令
 const permissions = {
@@ -13,162 +15,14 @@ const permissions = {
   },
 }
 
-// 权限处理逻辑封装为函数,方便inserted和update钩子复用
-function handlePermission(element, binding) {
-  // 获取用户信息
-  const userInfo = store.state.user.userInfo || {}
-  const user = userInfo.user || {}
-  // 更加健壮的管理员权限判断,接受布尔值true、字符串'true'等真值
-  const isAdmin = !!user.admin
-  const dataScope = user.dataScope ?? 999 // 默认无权限
-
-  // 权限级别定义
-  const PERMISSION_LEVEL = {
-    PROVINCE: 0, // 省级
-    CITY: 1, // 市级
-    COUNTY: 2, // 县级
-  }
-
-  // 分类权限定义 - 基于表格结构
-  const PERMISSION_CATEGORIES = {
-    // 第一类:省级维护,市县查看
-    ADMIN_PROVINCE_VIEW_OTHERS: [
-      'catalogManage', // 监审目录管理
-      'auditEntityManage', // 被监审单位管理
-      'costFormManage', // 成本监审表模板管理
-      'financeSheetManage', // 财务数据表模板管理
-      'costVerifyManage', // 成本核定表模板管理
-      'auditReviewDocManage', // 监审文书管理
-      'auditDocNoManage', // 监审文号管理
-      'auditDocManage', // 监审资料管理
-      'annualReviewPlan', // 年度审计计划
-      'auditInitiation', // 监审立项管理
-    ],
-
-    // 第二类:省市县可查看添加本级及下级,同级不可查看添加
-    // LEVEL_BASED_MANAGE: [
-    //   'annualReviewPlan',        // 年度审计计划
-    //   'auditInitiation',       // 监审立项管理
-    // ],
-
-    // 第三类:跟着数据权限走
-    // DATA_BASED_MANAGE: [
-    //   'auditProject',          // 监审项目管理
-    //   'taskManagement',        // 任务管理
-    //   'superviseMatters'       // 督办管理
-    // ],
-  }
-
-  // 解析绑定值
-  const options = binding.value || {}
-  const action = options.action || 'view' // 默认只有查看权限
-  const category = options.category || '' // 权限分类标识
-  const targetData = options.targetData || {} // 目标数据,用于判断同级等场景
-  const displayMode = options.displayMode || 'hidden' // 无权限时的显示模式:'hidden'(隐藏)或 'disabled'(禁用)
-
-  // 判断是否拥有权限
-  let hasPermission = false
-
-  // 管理员拥有所有权限
-  if (isAdmin) {
-    hasPermission = true
-  } else {
-    // 基于分类的权限判断逻辑
-
-    // 第一类权限:省级维护,市县查看
-    if (PERMISSION_CATEGORIES.ADMIN_PROVINCE_VIEW_OTHERS.includes(category)) {
-      if (action === 'view') {
-        // 所有级别都可查看
-        hasPermission = true
-      } else {
-        // 新增、编辑、删除操作只有省级可执行
-        // 确保dataScope为0的省级用户有正确权限
-        hasPermission = dataScope === PERMISSION_LEVEL.PROVINCE
-      }
-    }
-  }
-
-  // 根据displayMode决定无权限时的处理方式
-  if (!hasPermission) {
-    if (displayMode === 'disabled') {
-      // 禁用模式:保留元素但禁用交互
-      element.setAttribute('disabled', 'disabled')
-      element.style.cursor = 'not-allowed'
-      element.style.opacity = '0.6'
-      element.style.pointerEvents = 'none' // 禁用所有指针事件
-
-      // 添加提示类名,可用于自定义样式
-      element.classList.add('permission-disabled')
-
-      // 对于a标签的特殊处理
-      if (element.tagName === 'A') {
-        // 移除href属性或设置为无效值
-        if (element.hasAttribute('href')) {
-          element.setAttribute(
-            'data-original-href',
-            element.getAttribute('href')
-          )
-          element.removeAttribute('href')
-        }
-        element.setAttribute('tabindex', '-1') // 从Tab键序列中移除
-      }
-
-      // 阻止所有事件冒泡和默认行为,确保元素真正不可交互
-      const preventEvent = (e) => {
-        e.stopPropagation()
-        e.preventDefault()
-        return false
-      }
-
-      // 使用捕获模式添加所有可能的交互事件阻止
-      const events = [
-        'click',
-        'mousedown',
-        'mouseup',
-        'dblclick',
-        'touchstart',
-        'touchend',
-        'touchmove',
-        'touchcancel',
-        'keydown',
-        'keypress',
-        'keyup',
-        'focus',
-        'blur',
-      ]
-
-      events.forEach((event) => {
-        element.addEventListener(event, preventEvent, true)
-      })
-
-      // 重写元素上可能存在的onclick等属性
-      element.onclick = null
-      element.onmousedown = null
-      element.onmouseup = null
-      element.ondblclick = null
-    } else {
-      // 默认隐藏模式:移除元素
-      element.parentNode && element.parentNode.removeChild(element)
-    }
-  }
-}
-
-// 区域权限指令定义 - 同时使用inserted和update钩子确保动态元素也能正确应用权限
-const regionPermission = {
-  inserted: handlePermission,
-  update: handlePermission,
-}
-
 // 安装函数
 const install = function (Vue) {
   Vue.directive('permissions', permissions)
-  Vue.directive('region-permission', regionPermission)
 }
 
 // 全局安装
 if (window.Vue) {
   window['permissions'] = permissions
-  window['regionPermission'] = regionPermission
   Vue.use(install)
 }
 

+ 274 - 0
src/plugins/regionPermission.js

@@ -0,0 +1,274 @@
+import store from '@/store'
+
+/**
+ * 区域权限指令实现
+ * 用于处理基于用户级别(省级、市级、县级)的权限控制
+ */
+
+// 权限判断公共工具
+const permissionUtils = {
+  /**
+   * 获取当前登录用户信息
+   * @returns {Object} 用户信息对象
+   */
+  getUserInfo() {
+    const userInfo = store.state.user.userInfo || {}
+    return userInfo.user || {}
+  },
+
+  /**
+   * 判断是否为管理员账号
+   * @returns {Boolean} 是否为管理员
+   */
+  isAdmin() {
+    const user = this.getUserInfo()
+    return !!user.admin
+  },
+
+  /**
+   * 判断是否为省级账号
+   * @returns {Boolean} 是否为省级账号
+   */
+  isProvince() {
+    const user = this.getUserInfo()
+    return user.dataScope === PERMISSION_LEVEL.PROVINCE
+  },
+
+  /**
+   * 判断是否为管理员或省级账号
+   * @returns {Boolean} 是否为管理员或省级账号
+   */
+  isAdminOrProvince() {
+    return this.isAdmin() || this.isProvince()
+  },
+
+  /**
+   * 根据操作和分类判断权限
+   * @param {String} action - 操作类型:'view', 'add', 'edit', 'delete'
+   * @param {String} category - 权限分类
+   * @returns {Boolean} 是否有权限
+   */
+  hasPermission(action, category) {
+    if (this.isAdmin()) {
+      return true
+    }
+
+    const user = this.getUserInfo()
+    const dataScope = user.dataScope ?? 999
+
+    // 对于省级维护,市县查看的分类
+    if (PERMISSION_CATEGORIES.ADMIN_PROVINCE_VIEW_OTHERS.includes(category)) {
+      if (action === 'view') {
+        return true
+      } else {
+        return dataScope === PERMISSION_LEVEL.PROVINCE
+      }
+    }
+
+    return false
+  },
+}
+
+// 权限级别定义
+export const PERMISSION_LEVEL = {
+  PROVINCE: 0, // 省级
+  CITY: 1, // 市级
+  COUNTY: 2, // 县级
+}
+
+// 分类权限定义 - 基于表格结构
+export const PERMISSION_CATEGORIES = {
+  // 第一类:省级维护,市县查看
+  ADMIN_PROVINCE_VIEW_OTHERS: [
+    'catalogManage', // 监审目录管理
+    'auditEntityManage', // 被监审单位管理
+    'auditReviewDocManage', // 监审文书管理
+    'auditDocNoManage', // 监审文号管理
+    'auditDocManage', // 监审资料管理
+    'annualReviewPlan', // 年度审计计划
+    'auditInitiation', // 监审立项管理
+    'costFormManage', // 成本调查表模板管理
+    'financeSheetManage', // 财务数据表模板管理
+    'costVerifyManage', // 成本核定表模板管理
+  ],
+
+  // 第二类:省市县都可添加但各维护各,省级添加的市县查看,同级不可查看
+  // LEVEL_BASED_MANAGE: [
+  //   'costFormManage', // 成本调查表模板管理
+  //   'financeSheetManage', // 财务数据表模板管理
+  //   'costVerifyManage', // 成本核定表模板管理
+  // ],
+
+  // 第三类:跟着数据权限走
+  // DATA_BASED_MANAGE: [
+  //   'auditProject',          // 监审项目管理
+  //   'taskManagement',        // 任务管理
+  //   'superviseMatters'       // 督办管理
+  // ],
+}
+
+/**
+ * 权限处理逻辑封装为函数
+ * @param {HTMLElement} element - 要处理权限的DOM元素
+ * @param {Object} binding - Vue指令绑定对象
+ */
+export function handlePermission(element, binding) {
+  // 获取用户信息
+  const userInfo = store.state.user.userInfo || {}
+  const user = userInfo.user || {}
+  // 更加健壮的管理员权限判断,接受布尔值true、字符串'true'等真值
+  const isAdmin = !!user.admin
+  const dataScope = user.dataScope ?? 999 // 默认无权限
+
+  // 解析绑定值
+  const options = binding.value || {}
+  const action = options.action || 'view' // 默认只有查看权限
+  const category = options.category || '' // 权限分类标识
+  const targetData = options.targetData || {} // 目标数据,用于判断同级等场景
+  const displayMode = options.displayMode || 'hidden' // 无权限时的显示模式:'hidden'(隐藏)或 'disabled'(禁用)
+  // 判断是否拥有权限
+  let hasPermission = false
+
+  // 管理员拥有所有权限
+  if (isAdmin) {
+    hasPermission = true
+  } else {
+    // 基于分类的权限判断逻辑
+
+    // 第一类权限:省级维护,市县查看
+    if (PERMISSION_CATEGORIES.ADMIN_PROVINCE_VIEW_OTHERS.includes(category)) {
+      if (action === 'view') {
+        // 所有级别都可查看
+        hasPermission = true
+      } else {
+        // 新增、编辑、删除操作只有省级可执行
+        // 确保dataScope为0的省级用户有正确权限
+        hasPermission = dataScope === PERMISSION_LEVEL.PROVINCE
+      }
+    }
+    // 第二类权限:省市县都可添加但各维护各,省级添加的市县查看,同级不可查看
+    //  if (PERMISSION_CATEGORIES.LEVEL_BASED_MANAGE.includes(category)) {
+    //   if (action === 'view') {
+    //     // 省级可查看所有添加的市县
+    //     hasPermission = true
+    //   } else {
+    //     // 新增、编辑、删除操作只有数据创建者和当前用户是用一个可执行
+    //     if (
+    //       targetData.createBy === user.username
+    //     ) {
+    //       hasPermission = true
+    //     }
+
+    //     // hasPermission = dataScope === PERMISSION_LEVEL[category.split('Manage')[0]]
+    //   }
+    // }
+
+    // 第三类权限:跟着数据权限走
+    // if (PERMISSION_CATEGORIES.DATA_BASED_MANAGE.includes(category)) {
+    //   // 数据权限判断逻辑...
+    // }
+  }
+
+  // 根据displayMode决定无权限时的处理方式
+  if (!hasPermission) {
+    if (displayMode === 'disabled') {
+      // 禁用模式:保留元素但禁用交互
+      element.setAttribute('disabled', 'disabled')
+      element.style.cursor = 'not-allowed'
+      element.style.opacity = '0.6'
+      element.style.pointerEvents = 'none' // 禁用所有指针事件
+
+      // 添加提示类名,可用于自定义样式
+      element.classList.add('permission-disabled')
+
+      // 对于a标签的特殊处理
+      if (element.tagName === 'A') {
+        // 移除href属性或设置为无效值
+        if (element.hasAttribute('href')) {
+          element.setAttribute(
+            'data-original-href',
+            element.getAttribute('href')
+          )
+          element.removeAttribute('href')
+        }
+        element.setAttribute('tabindex', '-1') // 从Tab键序列中移除
+      }
+
+      // 阻止所有事件冒泡和默认行为,确保元素真正不可交互
+      const preventEvent = (e) => {
+        e.stopPropagation()
+        e.preventDefault()
+        return false
+      }
+
+      // 使用捕获模式添加所有可能的交互事件阻止
+      const events = [
+        'click',
+        'mousedown',
+        'mouseup',
+        'dblclick',
+        'touchstart',
+        'touchend',
+        'touchmove',
+        'touchcancel',
+        'keydown',
+        'keypress',
+        'keyup',
+        'focus',
+        'blur',
+      ]
+
+      events.forEach((event) => {
+        element.addEventListener(event, preventEvent, true)
+      })
+
+      // 重写元素上可能存在的onclick等属性
+      element.onclick = null
+      element.onmousedown = null
+      element.onmouseup = null
+      element.ondblclick = null
+    } else {
+      // 默认隐藏模式:移除元素
+      element.parentNode && element.parentNode.removeChild(element)
+    }
+  }
+}
+
+// 区域权限指令定义 - 同时使用inserted和update钩子确保动态元素也能正确应用权限
+export const regionPermission = {
+  inserted: handlePermission,
+  update: handlePermission,
+}
+
+// 安装函数
+const install = function (Vue) {
+  Vue.directive('region-permission', regionPermission)
+
+  // 挂载权限判断工具到Vue原型
+  Vue.prototype.$permission = permissionUtils
+
+  // 全局挂载regionPermission对象,方便其他地方使用
+  if (window.Vue) {
+    window['regionPermission'] = regionPermission
+    window['permissionUtils'] = permissionUtils
+  }
+}
+
+// 全局安装
+if (window.Vue) {
+  window['regionPermission'] = regionPermission
+  Vue.use(install)
+}
+
+// 导出
+export default {
+  regionPermission,
+  handlePermission,
+  PERMISSION_LEVEL,
+  PERMISSION_CATEGORIES,
+  permissionUtils,
+  install,
+}
+
+// 同时导出permissionUtils,方便在非Vue组件中使用
+export { permissionUtils }

+ 24 - 12
src/views/costAudit/baseInfo/auditDocManage/index.vue

@@ -62,7 +62,6 @@
             v-region-permission="{
               category: 'auditDocManage',
               action: 'view',
-              displayMode: 'disabled',
             }"
             href="#"
             class="link-text"
@@ -88,6 +87,14 @@
         <template slot-scope="scope">
           <!-- 文字按钮样式 -->
           <el-button
+            v-region-permission="{ category: 'auditDocManage', action: 'view' }"
+            size="mini"
+            type="text"
+            @click="handleView(scope.row)"
+          >
+            查看
+          </el-button>
+          <el-button
             v-region-permission="{ category: 'auditDocManage', action: 'edit' }"
             size="mini"
             type="text"
@@ -107,12 +114,8 @@
           >
             删除
           </el-button>
-          <el-button
-            v-region-permission="{ category: 'auditDocManage', action: 'edit' }"
-            size="mini"
-            type="text"
-            @click="handleLink(scope.row)"
-          >
+          <!-- v-region-permission="{ category: 'auditDocManage', action: 'edit' }" -->
+          <el-button size="mini" type="text" @click="handleLink(scope.row)">
             关联监审目录
           </el-button>
         </template>
@@ -135,7 +138,7 @@
     <el-dialog
       :title="dialogTitle"
       :visible.sync="dialogVisible"
-      width="500px"
+      width="600px"
       @close="handleDialogClose"
     >
       <el-form
@@ -186,14 +189,23 @@
       </el-form>
 
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 认</el-button>
-        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button
+          v-if="dialogTitle !== '查看监审资料'"
+          type="primary"
+          @click="submitForm"
+        >
+          确 认
+        </el-button>
+        <el-button @click="dialogVisible = false">
+          {{ dialogTitle === '查看监审资料' ? '关闭' : '取消' }}
+        </el-button>
       </div>
     </el-dialog>
     <SelectCatalogDialog
       :dialog-visible="selectDialogVisible"
       :value="currentDocument.catalogId"
       :form-item="{ placeholder: '请选择监审目录' }"
+      :is-view-mode="!$permission.isAdminOrProvince()"
       @confirm="confirmSelect"
       @update:dialogVisible="selectDialogVisible = $event"
     ></SelectCatalogDialog>
@@ -278,7 +290,7 @@
       handleView(row) {
         this.currentDocument = {
           ...row,
-          uploadUrl: row.uploadUrl ? row.uploadUrl.split(',') : [''],
+          uploadUrl: row.uploadUrl ? row.uploadUrl.split(',') : [],
         }
         this.dialogTitle = '查看监审资料'
         this.dialogVisible = true
@@ -332,7 +344,7 @@
         this.isEdit = true
         this.currentDocument = {
           ...row,
-          uploadUrl: row.uploadUrl ? row.uploadUrl.split(',') : [''],
+          uploadUrl: row.uploadUrl ? row.uploadUrl.split(',') : [],
         }
         // 清除表单校验状态
         if (this.$refs.documentForm) {

+ 3 - 0
src/views/costAudit/baseInfo/auditEntityManage/index.vue

@@ -207,6 +207,9 @@
       }
     },
     mounted() {
+      if (!this.$permission.isAdminOrProvince()) {
+        this.columns.splice(this.columns.length - 1, 1)
+      }
       this.handleSearch()
     },
     methods: {

+ 7 - 1
src/views/costAudit/baseInfo/catalogManage/index.vue

@@ -186,7 +186,13 @@
             </span>
           </template>
         </el-table-column>
-        <el-table-column label="操作" width="360" fixed="right" align="center">
+        <el-table-column
+          v-if="$permission.isAdminOrProvince()"
+          label="操作"
+          width="360"
+          fixed="right"
+          align="center"
+        >
           <template slot-scope="scope">
             <div>
               <el-button

+ 14 - 4
src/views/costAudit/baseInfo/costFormManage/index.vue

@@ -49,6 +49,7 @@
 
       <!-- 操作按钮 -->
       <div class="operation-bar">
+        <!-- v-region-permission="{ category: 'costFormManage', action: 'add' }" -->
         <el-button
           v-region-permission="{ category: 'costFormManage', action: 'add' }"
           plain
@@ -81,6 +82,9 @@
           :show-pagination="true"
           :pagination="pagination"
           :loading="loading"
+          :table-props="{
+            defaultSort: { prop: 'createTime', order: 'descending' },
+          }"
           @selection-change="handleSelectionChange"
           @pagination-change="handlePaginationChange"
         >
@@ -117,6 +121,7 @@
               v-region-permission="{
                 category: 'costFormManage',
                 action: 'edit',
+                targetData: row,
               }"
               type="text"
               size="mini"
@@ -128,6 +133,7 @@
               v-region-permission="{
                 category: 'costFormManage',
                 action: 'delete',
+                targetData: row,
               }"
               class="delete-btn"
               type="text"
@@ -140,6 +146,7 @@
               v-region-permission="{
                 category: 'costFormManage',
                 action: 'edit',
+                targetData: row,
               }"
               class="ml10"
               trigger="click"
@@ -153,6 +160,7 @@
                   v-region-permission="{
                     category: 'costFormManage',
                     action: 'edit',
+                    targetData: row,
                   }"
                   @click.native="handleDropdownCommand('infoMaintain', row)"
                 >
@@ -162,6 +170,7 @@
                   v-region-permission="{
                     category: 'costFormManage',
                     action: 'edit',
+                    targetData: row,
                   }"
                   @click.native="handleDropdownCommand('status', row)"
                 >
@@ -476,7 +485,8 @@
             prop: 'createTime',
             label: '创建时间',
             slotName: 'createTime',
-            width: '100px',
+            width: '120px',
+            sortable: true,
           },
           {
             prop: 'action',
@@ -533,9 +543,9 @@
         }
         getCostFormList(params)
           .then((res) => {
-            if (res.code === 200) {
-              this.tableData = res.value.records || []
-              this.pagination.total = res.value.total || 0
+            if (res.rows.length > 0) {
+              this.tableData = res.rows || []
+              this.pagination.total = res.total || 0
               this.batchGetCatalogNames()
             }
           })

+ 136 - 58
src/views/costAudit/baseInfo/costFormManage/infoMaintain.vue

@@ -476,7 +476,9 @@
                       type="text"
                       size="mini"
                       :disabled="viewDetail"
-                      @click="handleMoveUp(scope.$index)"
+                      @click="
+                        handleMoveUp(scope.$index, '单记录表头', scope.row)
+                      "
                     >
                       上升
                     </el-button>
@@ -745,7 +747,9 @@
                       type="text"
                       size="mini"
                       :disabled="scope.row.isDisabled || viewDetail"
-                      @click="handleMoveUp(scope.$index)"
+                      @click="
+                        handleMoveUp(scope.$index, '固定表表头', scope.row)
+                      "
                     >
                       上升
                     </el-button>
@@ -1192,7 +1196,9 @@
                       type="text"
                       size="mini"
                       :disabled="scope.row.isDisabled || viewDetail"
-                      @click="handleMoveUp(scope.$index)"
+                      @click="
+                        handleMoveUp(scope.$index, '动态表表头', scope.row)
+                      "
                     >
                       上升
                     </el-button>
@@ -2293,7 +2299,8 @@
             }
 
             let dynamicChildOrderNum =
-              this.contentEditForm.dynamicTable.dynamicTables.length + 1
+              this.contentEditForm.dynamicTable.dynamicTables[parentIndex2]
+                .children.length + 1
             let dynamicValues = { ...parentRow.dynamicValues }
             for (const key in dynamicValues) {
               if (key == '序号') {
@@ -2401,8 +2408,16 @@
               this.contentEditForm.tableHeaders
             this.contentEditForm.fixedTable.tableHeaders =
               this.contentEditForm.tableHeaders
-            // 确保加载后的表头按正确顺序显示
-            this.updateTableHeadersOrderNumbers()
+            // 表头按照orderNum重新排序
+            this.contentEditForm.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
+            this.contentEditForm.dynamicTable.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
+            this.contentEditForm.fixedTable.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
             // 同时获取表头标题信息
             listByTemplateIdAndVersion(surveyTemplateId, versionId)
               .then((response) => {
@@ -2830,17 +2845,18 @@
           this.swamTableArr(newDynamicTableData, row, true)
           this.contentEditForm.dynamicTable.dynamicTables = newDynamicTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, true, true)
-          this.contentEditForm.tableHeaders = newTableHeaders
-          // if (index > 0) {
-          //   const temp = this.contentEditForm.tableHeaders[index]
-          //   this.contentEditForm.tableHeaders.splice(index, 1)
-          //   this.contentEditForm.tableHeaders.splice(index - 1, 0, temp)
-          //   // 更新表头的序号
-          //   this.updateTableHeadersOrderNumbers()
-          // }
+          // const tableHeaders = this.contentEditForm.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, true, true)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          // console.log('newTableHeaders', newTableHeaders)
+          if (index > 0) {
+            const temp = this.contentEditForm.tableHeaders[index]
+            this.contentEditForm.tableHeaders.splice(index, 1)
+            this.contentEditForm.tableHeaders.splice(index - 1, 0, temp)
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
       // 下降
@@ -2857,32 +2873,69 @@
           this.swamTableArr(newDynamicTableData, row, false)
           this.contentEditForm.dynamicTable.dynamicTables = newDynamicTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, false)
-          this.contentEditForm.tableHeaders = newTableHeaders
-          // if (index < this.contentEditForm.tableHeaders.length - 1) {
-          //   const temp = this.contentEditForm.tableHeaders[index]
-          //   this.contentEditForm.tableHeaders.splice(index, 1)
-          //   this.contentEditForm.tableHeaders.splice(index + 1, 0, temp)
-          //   // 更新表头的序号
-          //   this.updateTableHeadersOrderNumbers()
-          // }
+          // const tableHeaders = this.contentEditForm.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, false)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          if (index < this.contentEditForm.tableHeaders.length - 1) {
+            const temp = this.contentEditForm.tableHeaders[index]
+            this.contentEditForm.tableHeaders.splice(index, 1)
+            this.contentEditForm.tableHeaders.splice(index + 1, 0, temp)
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
 
       swamTableArr(arr, row, asc, isHeader) {
-        const isChild = row.isChild || row.isSubItem || false
-        if (isChild) {
-          // 子节点处理逻辑后续实现 parentid rowid
-          let child = arr.find((item) => item.rowid === row.parentid)
-          // const rowIndex = arr.indexOf(row);
-          // newFixedTableData[rowIndex]
-          this.doSwamTableArr(child.children, row, asc, isHeader)
-        } else {
+        if (isHeader) {
           // 创建数组副本以确保Vue能检测到变化
           // 直接替换整个数组,确保Vue能检测到变化
           this.doSwamTableArr(arr, row, asc, isHeader)
+        } else {
+          const isChild = row.isChild || row.isSubItem || false
+          if (isChild) {
+            // 子节点处理逻辑后续实现 parentid rowid
+            let child = arr.find((item) => item.rowid === row.parentid)
+            // const rowIndex = arr.indexOf(row);
+            // newFixedTableData[rowIndex]
+            this.doSwamTableArr(child.children, row, asc, isHeader)
+          } else {
+            this.doSwamTableArr(arr, row, asc, isHeader)
+          }
+        }
+      },
+
+      // 更新表头序号
+      updateTableHeadersOrderNumbers() {
+        if (!this.contentEditForm || !this.contentEditForm.tableHeaders) return
+
+        // 更新主表头的orderNum
+        this.contentEditForm.tableHeaders.forEach((header, index) => {
+          header.orderNum = index + 1
+        })
+
+        // 同步更新固定表和动态表的表头序号
+        if (
+          this.contentEditForm.fixedTable &&
+          this.contentEditForm.fixedTable.tableHeaders
+        ) {
+          this.contentEditForm.fixedTable.tableHeaders.forEach(
+            (header, index) => {
+              header.orderNum = index + 1
+            }
+          )
+        }
+
+        if (
+          this.contentEditForm.dynamicTable &&
+          this.contentEditForm.dynamicTable.tableHeaders
+        ) {
+          this.contentEditForm.dynamicTable.tableHeaders.forEach(
+            (header, index) => {
+              header.orderNum = index + 1
+            }
+          )
         }
       },
 
@@ -3006,27 +3059,6 @@
           }
         )
       },
-      // 更新表头序号
-      updateTableHeadersOrderNumbers() {
-        // 先按orderNum排序
-        this.contentEditForm.fixedTable.tableHeaders.sort((a, b) => {
-          // 处理序号字段(确保它始终在第一位)
-          if (a.fieldName === '序号') return -1
-          if (b.fieldName === '序号') return 1
-
-          // 按orderNum排序
-          const orderA = a.orderNum !== undefined ? parseInt(a.orderNum) : 0
-          const orderB = b.orderNum !== undefined ? parseInt(b.orderNum) : 0
-          return orderA - orderB
-        })
-
-        // 重新分配序号(从1开始)
-        this.contentEditForm.fixedTable.tableHeaders.forEach(
-          (header, index) => {
-            this.$set(header, 'orderNum', index + 1)
-          }
-        )
-      },
 
       // 绑定字典变化
       handleBindDictChange(row) {
@@ -3579,7 +3611,54 @@
         dynamicTables.forEach((row) => {
           processNode(row)
         })
+        // 重新给子节点赋值orderNum 保证所有元素orderNum字段不重复
+        // 为所有子节点分配唯一的orderNum,但保持父节点的orderNum不变
+
+        // 计算所有已存在的orderNum中的最大值
+        let maxExistingOrderNum = 0
+
+        // 首先遍历结果数组找出当前最大的orderNum
+        result.forEach((item) => {
+          const orderNum =
+            typeof item.orderNum === 'number'
+              ? item.orderNum
+              : parseInt(item.orderNum, 10) || 0
+          if (orderNum > maxExistingOrderNum) {
+            maxExistingOrderNum = orderNum
+          }
+        })
+        // 子节点orderNum从当前最大orderNum + 1开始
+        let childOrderNumCounter = maxExistingOrderNum + 1
+
+        // 创建一个映射表,用于记录每个子节点对应的新orderNum
+        const childOrderMap = new Map()
+        // 第一次遍历:为每个子节点分配新的orderNum并存储映射关系
+        function assignChildOrderNums(nodes) {
+          nodes.forEach((node) => {
+            if (node.isChild || node.isSubItem) {
+              // 为每个子节点分配唯一的orderNum
+              childOrderMap.set(node.id || node.rowid, childOrderNumCounter++)
+            }
+            // 递归处理子节点
+            if (node.children && node.children.length > 0) {
+              assignChildOrderNums(node.children)
+            }
+          })
+        }
+        // 第二次遍历:更新结果数组中的orderNum
+        assignChildOrderNums(dynamicTables)
 
+        // 应用新的orderNum到结果数组
+        result.forEach((item) => {
+          // 只更新子节点的orderNum
+          if (item.isChild || item.isSubItem) {
+            const newOrderNum =
+              childOrderMap.get(item.id) || childOrderMap.get(item.rowid)
+            if (newOrderNum) {
+              item.orderNum = newOrderNum
+            }
+          }
+        })
         return result
       },
       //保存固定表项目数据
@@ -3756,7 +3835,6 @@
         })
 
         this.contentEditForm.fixedTable.fixedTables = treeData
-        console.log('树形结构数据:', treeData)
       },
 
       /**

+ 171 - 80
src/views/costAudit/baseInfo/costVerifyManage/index.vue

@@ -40,14 +40,26 @@
     <!-- 操作按钮 -->
     <div class="operation-bar">
       <el-button
+        v-region-permission="{
+          category: 'costVerifyManage',
+          action: 'add',
+        }"
         plain
         type="success"
         icon="el-icon-circle-plus"
         @click="handleAdd"
       >
+        <!-- v-region-permission="{
+          category: 'costVerifyManage',
+          action: 'add',
+        }" -->
         添加
       </el-button>
       <el-button
+        v-region-permission="{
+          category: 'costVerifyManage',
+          action: 'delete',
+        }"
         plain
         type="danger"
         icon="el-icon-delete"
@@ -65,6 +77,7 @@
         :data="tableData"
         border
         style="width: 100%"
+        :default-sort="{ prop: 'createTime', order: 'descending' }"
         @selection-change="handleSelectionChange"
       >
         <el-table-column
@@ -138,6 +151,7 @@
           prop="createTime"
           label="创建时间"
           width="160"
+          sortable
           show-overflow-tooltip
           align="center"
         >
@@ -148,6 +162,7 @@
         </el-table-column>
 
         <el-table-column
+          v-if="$permission.isAdminOrProvince()"
           label="操作"
           width="240"
           fixed="right"
@@ -156,6 +171,10 @@
         >
           <template slot-scope="scope">
             <el-button
+              v-region-permission="{
+                category: 'costVerifyManage',
+                action: 'view',
+              }"
               type="text"
               size="mini"
               @click="handleViewDetail(scope.row)"
@@ -164,6 +183,11 @@
             </el-button>
             <el-button
               v-if="scope.row.status != '0'"
+              v-region-permission="{
+                category: 'costVerifyManage',
+                action: 'edit',
+                targetData: scope.row,
+              }"
               type="text"
               size="mini"
               @click="handleEdit(scope.row)"
@@ -171,6 +195,11 @@
               修改
             </el-button>
             <el-button
+              v-region-permission="{
+                category: 'costVerifyManage',
+                action: 'edit',
+                targetData: scope.row,
+              }"
               type="text"
               size="mini"
               @click="handleStatusChange(scope.row)"
@@ -180,6 +209,11 @@
             </el-button>
             <el-button
               v-if="scope.row.status != '0'"
+              v-region-permission="{
+                category: 'costVerifyManage',
+                action: 'delete',
+                targetData: scope.row,
+              }"
               type="text"
               size="mini"
               @click="handleDeleteRow(scope.row)"
@@ -826,7 +860,7 @@
                   <template slot-scope="scope">
                     <div class="table-actions">
                       <el-button
-                        v-if="scope.row.isChild"
+                        v-if="!scope.row.isChild"
                         type="text"
                         size="mini"
                         :disabled="dialogTitle == '查看成本核定模板'"
@@ -1027,7 +1061,7 @@
           type: '',
           catalogId: '',
           keyword: '',
-          pageNum: 1,
+          page: 1,
           pageSize: 50,
         },
         props: {
@@ -1347,9 +1381,9 @@
         this.loading = true
         getCostFormDataStorageTables(this.searchForm).then((res) => {
           this.loading = false
-          if (res.code === 200) {
-            this.tableData = res.value.records
-            this.pagination.total = res.value.total
+          if (res.rows.length > 0) {
+            this.tableData = res.rows || []
+            this.pagination.total = res.total || 0
             this.batchGetCatalogNames()
           }
         })
@@ -1360,7 +1394,7 @@
         this.searchForm = {
           catalogId: '',
           keyword: '',
-          pageNum: 1,
+          page: 1,
           pageSize: 10,
         }
         this.handleSearch()
@@ -1519,6 +1553,10 @@
           )
             ? tableHeadersRes.value
             : []
+          // 表头按照orderNum重新排序
+          this.contentEditForm.fixedTable.tableHeaders.sort(
+            (a, b) => a.orderNum - b.orderNum
+          )
 
           // 检查是否有fieldName为"序号"的数据
           const hasSerialNumber =
@@ -1849,31 +1887,53 @@
         this.$set(row.fixedValues, rkey, value)
       },
       // 上升
-      handleMoveUp(index, tableType) {
+      handleMoveUp(index, tableType, row) {
         if (tableType === '固定表') {
           const fixedTableData = this.contentEditForm.fixedTable.fixedTables
           const newFixedTableData = [...fixedTableData]
           this.swamTableArr(newFixedTableData, row, true)
           this.contentEditForm.fixedTable.fixedTables = newFixedTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, true, true)
-          this.contentEditForm.tableHeaders = newTableHeaders
+          // const tableHeaders = this.contentEditForm.fixedTable.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, true, true)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          if (index > 0) {
+            const temp = this.contentEditForm.fixedTable.tableHeaders[index]
+            this.contentEditForm.fixedTable.tableHeaders.splice(index, 1)
+            this.contentEditForm.fixedTable.tableHeaders.splice(
+              index - 1,
+              0,
+              temp
+            )
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
       // 下降
-      handleMoveDown(index, tableType) {
+      handleMoveDown(index, tableType, row) {
         if (tableType === '固定表') {
           const fixedTableData = this.contentEditForm.fixedTable.fixedTables
           const newFixedTableData = [...fixedTableData]
           this.swamTableArr(newFixedTableData, row, false)
           this.contentEditForm.fixedTable.fixedTables = newFixedTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, false)
-          this.contentEditForm.tableHeaders = newTableHeaders
+          // const tableHeaders = this.contentEditForm.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, false)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          if (index < this.contentEditForm.fixedTable.tableHeaders.length - 1) {
+            const temp = this.contentEditForm.fixedTable.tableHeaders[index]
+            this.contentEditForm.fixedTable.tableHeaders.splice(index, 1)
+            this.contentEditForm.fixedTable.tableHeaders.splice(
+              index + 1,
+              0,
+              temp
+            )
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
       swamTableArr(arr, row, asc, isHeader) {
@@ -1942,22 +2002,21 @@
         arr[rowIndex] = swam
         arr[swamIndex] = curr
       },
-      // 更新固定表中显示的序号值
-      updateFixedTableDisplayOrder() {
-        this.contentEditForm.fixedTable.fixedTables.forEach((row, index) => {
-          // 更新 orderText(显示用序号)
-          row.orderText = index + 1
-
-          // 更新 orderNum(用于后端)
-          row.orderNum = index + 1
-
-          // 如果有"序号"列,也更新该列的值
-          if (row.fixedValues && row.fixedValues['序号'] !== undefined) {
-            // 可以根据需求决定是否更新,这里保持原值或更新为新序号
-            // row.fixedValues['序号'] = index + 1
-          }
-        })
+      // 更新表头序号
+      updateTableHeadersOrderNumbers() {
+        // 更新固定表的表头序号
+        if (
+          this.contentEditForm.fixedTable &&
+          this.contentEditForm.fixedTable.tableHeaders
+        ) {
+          this.contentEditForm.fixedTable.tableHeaders.forEach(
+            (header, index) => {
+              header.orderNum = index + 1
+            }
+          )
+        }
       },
+
       // 添加子项方法
       handleAddChildItem(index, type, parentRow) {
         if (!parentRow.rowid) {
@@ -1966,19 +2025,47 @@
 
         switch (type) {
           case '固定表项目':
+            let parentIndex1 =
+              this.contentEditForm.fixedTable.fixedTables.findIndex(
+                (item) => item.rowid == parentRow.rowid
+              )
+            if (
+              !this.contentEditForm.fixedTable.fixedTables[parentIndex1]
+                .children
+            ) {
+              this.$set(
+                this.contentEditForm.fixedTable.fixedTables[parentIndex1],
+                'children',
+                []
+              )
+            }
+
             let childOrderNum =
-              this.contentEditForm.fixedTable.fixedTables.length + 1
+              this.contentEditForm.fixedTable.fixedTables[parentIndex1].children
+                .length + 1
+
+            let fixedValues = {
+              ...parentRow.fixedValues,
+            }
+
+            for (const key in fixedValues) {
+              if (key == '序号') {
+                fixedValues[key] = childOrderNum
+              } else {
+                fixedValues[key] = ''
+              }
+            }
 
             const fixedNewRow = {
-              orderText: '子项序号',
-              orderNum: childOrderNum,
+              orderText: this.contentEditForm.fixedTable.fixedTables.length + 1,
+              orderNum: this.contentEditForm.fixedTable.fixedTables.length + 1,
               cellCode: '',
               calculationFormula: '',
               unit: '',
               tabtype: this.contentEditForm.templateType,
               surveyTemplateId: this.contentEditForm.surveyTemplateId,
               versionId: this.versionId,
-              fixedValues: { ...parentRow.fixedValues },
+              fixedValues: fixedValues,
               parentid: parentRow.rowid,
               isChild: true,
               isSubItem: true,
@@ -1992,12 +2079,15 @@
                 }
               }
             )
-
-            this.contentEditForm.fixedTable.fixedTables.splice(
-              index + 1,
-              0,
-              fixedNewRow
-            )
+            this.contentEditForm.fixedTable.fixedTables[
+              parentIndex1
+            ].children.push(fixedNewRow)
+
+            // this.contentEditForm.fixedTable.fixedTables.splice(
+            //   index + 1,
+            //   0,
+            //   fixedNewRow
+            // )
             break
         }
         this.$nextTick(() => {
@@ -2296,12 +2386,16 @@
        * @param {Object} responseData - listByCurrentTemplateId接口返回的数据
        */
       parseAndDisplayFixedTableData(responseData) {
-        let fixedFields = this.contentEditForm.fixedTable.tableHeaders
-          .map((item) => item.fieldName)
-          .join(',')
-        this.contentEditForm.fixedTable.fixedTablesTitle = this.stringToObjects(
-          fixedFields || ''
-        )
+        if (responseData.value.fixedFields) {
+          this.contentEditForm.fixedTable.fixedTablesTitle =
+            this.stringToObjects(responseData.value.fixedFields || '')
+        } else {
+          let fixedFields = this.contentEditForm.fixedTable.tableHeaders
+            .map((item) => item.fieldName)
+            .join(',')
+          this.contentEditForm.fixedTable.fixedTablesTitle =
+            this.stringToObjects(fixedFields || '')
+        }
         const fixedTitles = this.contentEditForm.fixedTable.fixedTablesTitle
         this.contentEditForm.fixedTable.fixedTableHeaders = fixedTitles.filter(
           (title) => title.rkey !== '序号'
@@ -2313,20 +2407,20 @@
         ) {
           return
         }
+
         const itemList = responseData.value.itemlist
+        const allRows = []
+        const rowMap = new Map()
 
         // 清空现有数据
         this.contentEditForm.fixedTable.fixedTables = []
 
-        // 使用Map来存储所有行,便于快速查找父项
-        const rowMap = new Map()
-        const parentItems = []
-
         // 遍历itemList,为每个项目创建一行数据
         itemList.forEach((item, index) => {
           // 判断是否为子项(parentid不为-1且不为"-1")
           const isSubItem =
             item.parentid && item.parentid !== -1 && item.parentid !== '-1'
+
           const newRow = {
             orderText: item.orderNum || '', // 显示用序号
             orderNum: item.orderNum || '', // 保留原始序号用于发送后端
@@ -2350,48 +2444,45 @@
             newRow.orderNum = parseInt(item.orderNum, 10) || 0
           }
 
+          // 初始化fixedValues并填充实际值
           fixedTitles.forEach((title) => {
             newRow.fixedValues[title.rkey] = item[title.rkey] || ''
           })
 
-          // 将行添加到Map中
-          rowMap.set(newRow.rowid, newRow)
-          if (newRow.itemId) {
-            rowMap.set(newRow.itemId, newRow)
-          }
-
-          // 如果是父项,添加到父项数组
-          if (!isSubItem) {
-            parentItems.push(newRow)
-          }
+          allRows.push(newRow)
+          // 构建rowMap用于快速查找
+          if (newRow.rowid) rowMap.set(String(newRow.rowid), newRow)
+          if (newRow.itemId) rowMap.set(String(newRow.itemId), newRow)
         })
 
-        // 构建父子关系
-        rowMap.forEach((row) => {
-          if (row.isChild && row.parentid) {
-            const parent = rowMap.get(row.parentid)
+        // 构建树形结构
+        const treeData = []
+        const parentItems = allRows.filter((item) => !item.isChild)
+
+        // 父级按orderNum正序排序
+        parentItems.sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
+
+        // 将子项添加到对应的父项的children中
+        allRows.forEach((item) => {
+          if (item.isChild) {
+            const parentId = String(item.parentid)
+            const parent = rowMap.get(parentId)
             if (parent) {
-              parent.children.push(row)
-              // 确保父项有hasChildren标记
-              parent.hasChildren = true
+              parent.children.push(item)
             }
           }
         })
 
-        // 对父项按orderNum排序
-        parentItems.sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
-
-        // 对子项按orderNum排序
+        // 对子项进行排序
         parentItems.forEach((parent) => {
-          if (parent.children && parent.children.length > 0) {
-            parent.children.sort(
-              (a, b) => (a.orderNum || 0) - (b.orderNum || 0)
-            )
-          }
+          parent.children.sort(
+            (a, b) =>
+              (a.fixedValues['序号'] || 0) - (b.fixedValues['序号'] || 0)
+          )
+          treeData.push(parent)
         })
 
-        // 设置最终的fixedTables数据
-        this.contentEditForm.fixedTable.fixedTables = parentItems
+        this.contentEditForm.fixedTable.fixedTables = treeData
       },
       /**
        * 将固定表项目的数据根据固定列拆分成对应的数据结构
@@ -2643,7 +2734,7 @@
       },
 
       handleCurrentChange(val) {
-        this.searchForm.pageNum = val
+        this.searchForm.page = val
         this.handleSearch()
       },
 

+ 21 - 5
src/views/costAudit/baseInfo/financeSheetManage/index.vue

@@ -48,6 +48,10 @@
 
       <!-- 操作按钮 -->
       <div class="operation-bar">
+        <!-- v-region-permission="{
+            category: 'financeSheetManage',
+            action: 'add',
+          }" -->
         <el-button
           v-region-permission="{
             category: 'financeSheetManage',
@@ -86,6 +90,9 @@
           :show-pagination="true"
           :pagination="pagination"
           :loading="loading"
+          :table-props="{
+            defaultSort: { prop: 'createTime', order: 'descending' },
+          }"
           @selection-change="handleSelectionChange"
           @pagination-change="handlePaginationChange"
         >
@@ -122,6 +129,7 @@
               v-region-permission="{
                 category: 'financeSheetManage',
                 action: 'edit',
+                targetData: row,
               }"
               type="text"
               size="mini"
@@ -133,6 +141,7 @@
               v-region-permission="{
                 category: 'financeSheetManage',
                 action: 'delete',
+                targetData: row,
               }"
               class="delete-btn"
               type="text"
@@ -145,6 +154,7 @@
               v-region-permission="{
                 category: 'financeSheetManage',
                 action: 'edit',
+                targetData: row,
               }"
               class="ml10"
               trigger="click"
@@ -158,6 +168,7 @@
                   v-region-permission="{
                     category: 'financeSheetManage',
                     action: 'edit',
+                    targetData: row,
                   }"
                   @click.native="handleDropdownCommand('infoMaintain', row)"
                 >
@@ -167,6 +178,7 @@
                   v-region-permission="{
                     category: 'financeSheetManage',
                     action: 'edit',
+                    targetData: row,
                   }"
                   @click.native="handleDropdownCommand('status', row)"
                 >
@@ -474,7 +486,8 @@
             prop: 'createTime',
             label: '创建时间',
             slotName: 'createTime',
-            width: '100px',
+            width: '120px',
+            sortable: true,
           },
           {
             prop: 'action',
@@ -488,6 +501,9 @@
       },
     },
     mounted() {
+      if (!this.$permission.isAdminOrProvince()) {
+        this.tableColumns.splice(this.tableColumns.length - 1, 1)
+      }
       // 初始加载数据
       this.handleSearch()
     },
@@ -523,14 +539,14 @@
 
         const params = {
           catalogId: this.searchForm.catalogId,
-          pageNum: this.pagination.currentPage,
+          page: this.pagination.currentPage,
           pageSize: this.pagination.pageSize,
         }
         getSurveyFdList(params)
           .then((res) => {
-            if (res.code === 200) {
-              this.tableData = res.value.records || []
-              this.pagination.total = res.value.total || 0
+            if (res.rows.length > 0) {
+              this.tableData = res.rows || []
+              this.pagination.total = res.total || 0
               this.batchGetCatalogNames()
             }
           })

+ 239 - 48
src/views/costAudit/baseInfo/financeSheetManage/infoMaintain.vue

@@ -1426,6 +1426,7 @@
           :data="indicatorTableData"
           border
           style="width: 100%; margin-top: 10px"
+          class="mb20"
           @row-click="handleRowClick"
         >
           <el-table-column label="选择" width="60">
@@ -2315,19 +2316,47 @@
 
         switch (type) {
           case '固定表项目':
+            let parentIndex1 =
+              this.contentEditForm.fixedTable.fixedTables.findIndex(
+                (item) => item.rowid == parentRow.rowid
+              )
+            if (
+              !this.contentEditForm.fixedTable.fixedTables[parentIndex1]
+                .children
+            ) {
+              this.$set(
+                this.contentEditForm.fixedTable.fixedTables[parentIndex1],
+                'children',
+                []
+              )
+            }
+
             let childOrderNum =
-              this.contentEditForm.fixedTable.fixedTables.length + 1
+              this.contentEditForm.fixedTable.fixedTables[parentIndex1].children
+                .length + 1
+
+            let fixedValues = {
+              ...parentRow.fixedValues,
+            }
+
+            for (const key in fixedValues) {
+              if (key == '序号') {
+                fixedValues[key] = childOrderNum
+              } else {
+                fixedValues[key] = ''
+              }
+            }
 
             const fixedNewRow = {
-              orderText: childOrderNum, // 显示用的序号文本
-              orderNum: childOrderNum, // 发送给后端的序号
+              orderText: this.contentEditForm.fixedTable.fixedTables.length + 1,
+              orderNum: this.contentEditForm.fixedTable.fixedTables.length + 1,
               cellCode: '',
               calculationFormula: '',
               unit: '',
               tabtype: this.templateType,
               surveyTemplateId: this.surveyTemplateId,
               versionId: this.versionId,
-              fixedValues: { ...parentRow.fixedValues },
+              fixedValues: fixedValues,
               parentid: parentRow.rowid,
               isChild: true,
               isSubItem: true,
@@ -2341,26 +2370,52 @@
                 }
               }
             )
-
-            this.contentEditForm.fixedTable.fixedTables.splice(
-              index + 1,
-              0,
-              fixedNewRow
-            )
+            this.contentEditForm.fixedTable.fixedTables[
+              parentIndex1
+            ].children.push(fixedNewRow)
+            // this.contentEditForm.fixedTable.fixedTables.splice(
+            //   index + 1,
+            //   0,
+            //   fixedNewRow
+            // )
             break
 
           case '动态表项目':
             // 生成子项序号 (在整个列表中的统一序号)
+            let parentIndex2 =
+              this.contentEditForm.dynamicTable.dynamicTables.findIndex(
+                (item) => item.rowid == parentRow.rowid
+              )
+            if (
+              !this.contentEditForm.dynamicTable.dynamicTables[parentIndex2]
+                .children
+            ) {
+              this.$set(
+                this.contentEditForm.dynamicTable.dynamicTables[parentIndex2],
+                'children',
+                []
+              )
+            }
+
             let dynamicChildOrderNum =
-              this.contentEditForm.dynamicTable.dynamicTables.length + 1
+              this.contentEditForm.dynamicTable.dynamicTables[parentIndex2]
+                .children.length + 1
+            let dynamicValues = { ...parentRow.dynamicValues }
+            for (const key in dynamicValues) {
+              if (key == '序号') {
+                dynamicValues[key] = dynamicChildOrderNum
+              } else {
+                dynamicValues[key] = ''
+              }
+            }
 
             const dynamicNewRow = {
-              orderText: dynamicChildOrderNum, // 显示用的序号文本
-              orderNum: dynamicChildOrderNum, // 发送给后端的序号
+              orderText: dynamicChildOrderNum,
+              orderNum: dynamicChildOrderNum,
               tabtype: this.templateType,
               surveyTemplateId: this.surveyTemplateId,
               versionId: this.versionId,
-              dynamicValues: { ...parentRow.dynamicValues },
+              dynamicValues: dynamicValues,
               parentid: parentRow.rowid,
               isChild: true,
               isSubItem: true,
@@ -2374,12 +2429,15 @@
                 }
               }
             )
-
-            this.contentEditForm.dynamicTable.dynamicTables.splice(
-              index + 1,
-              0,
-              dynamicNewRow
-            )
+            this.contentEditForm.dynamicTable.dynamicTables[
+              parentIndex2
+            ].children.push(dynamicNewRow)
+
+            // this.contentEditForm.dynamicTable.dynamicTables.splice(
+            //   index + 1,
+            //   0,
+            //   dynamicNewRow
+            // )
             break
         }
 
@@ -2447,6 +2505,16 @@
               this.contentEditForm.tableHeaders
             this.contentEditForm.fixedTable.tableHeaders =
               this.contentEditForm.tableHeaders
+            // 表头按照orderNum重新排序
+            this.contentEditForm.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
+            this.contentEditForm.dynamicTable.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
+            this.contentEditForm.fixedTable.tableHeaders.sort(
+              (a, b) => a.orderNum - b.orderNum
+            )
 
             // 同时获取表头标题信息
             listByTemplateIdAndVersion(surveyTemplateId, versionId)
@@ -2763,6 +2831,8 @@
               this.contentEditForm.fixedTable.fixedTablesTitle.filter(
                 (title) => title.rkey !== '序号'
               )
+            // 重新排序
+            this.updateTableHeadersOrderNumbers()
             handleDelete()
             break
 
@@ -2772,6 +2842,8 @@
               return
             }
             this.contentEditForm.fixedTable.fixedTables.splice(index, 1)
+            // 重新排序
+            this.updateTableHeadersOrderNumbers()
             handleDelete() // 执行删除逻辑
             break
           case '动态表表头':
@@ -2831,17 +2903,17 @@
           this.swamTableArr(newDynamicTableData, row, true)
           this.contentEditForm.dynamicTable.dynamicTables = newDynamicTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, true, true)
-          this.contentEditForm.tableHeaders = newTableHeaders
-          // if (index > 0) {
-          //   const temp = this.contentEditForm.tableHeaders[index]
-          //   this.contentEditForm.tableHeaders.splice(index, 1)
-          //   this.contentEditForm.tableHeaders.splice(index - 1, 0, temp)
-          //   // 更新表头的序号
-          //   this.updateTableHeadersOrderNumbers()
-          // }
+          // const tableHeaders = this.contentEditForm.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, true, true)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          if (index > 0) {
+            const temp = this.contentEditForm.tableHeaders[index]
+            this.contentEditForm.tableHeaders.splice(index, 1)
+            this.contentEditForm.tableHeaders.splice(index - 1, 0, temp)
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
       // 下降
@@ -2858,17 +2930,17 @@
           this.swamTableArr(newDynamicTableData, row, false)
           this.contentEditForm.dynamicTable.dynamicTables = newDynamicTableData
         } else {
-          const tableHeaders = this.contentEditForm.tableHeaders
-          const newTableHeaders = [...tableHeaders]
-          this.swamTableArr(newTableHeaders, row, false, true)
-          this.contentEditForm.tableHeaders = newTableHeaders
-          // if (index < this.contentEditForm.tableHeaders.length - 1) {
-          //   const temp = this.contentEditForm.tableHeaders[index]
-          //   this.contentEditForm.tableHeaders.splice(index, 1)
-          //   this.contentEditForm.tableHeaders.splice(index + 1, 0, temp)
-          //   // 更新表头的序号
-          //   this.updateTableHeadersOrderNumbers()
-          // }
+          // const tableHeaders = this.contentEditForm.tableHeaders
+          // const newTableHeaders = [...tableHeaders]
+          // this.swamTableArr(newTableHeaders, row, false, true)
+          // this.contentEditForm.tableHeaders = newTableHeaders
+          if (index < this.contentEditForm.tableHeaders.length - 1) {
+            const temp = this.contentEditForm.tableHeaders[index]
+            this.contentEditForm.tableHeaders.splice(index, 1)
+            this.contentEditForm.tableHeaders.splice(index + 1, 0, temp)
+            // 更新表头的序号
+            this.updateTableHeadersOrderNumbers()
+          }
         }
       },
 
@@ -2939,6 +3011,38 @@
         arr[rowIndex] = swam
         arr[swamIndex] = curr
       },
+      // 更新表头序号
+      updateTableHeadersOrderNumbers() {
+        if (!this.contentEditForm || !this.contentEditForm.tableHeaders) return
+
+        // 更新主表头的orderNum
+        this.contentEditForm.tableHeaders.forEach((header, index) => {
+          header.orderNum = index + 1
+        })
+
+        // 同步更新固定表和动态表的表头序号
+        if (
+          this.contentEditForm.fixedTable &&
+          this.contentEditForm.fixedTable.tableHeaders
+        ) {
+          this.contentEditForm.fixedTable.tableHeaders.forEach(
+            (header, index) => {
+              header.orderNum = index + 1
+            }
+          )
+        }
+
+        if (
+          this.contentEditForm.dynamicTable &&
+          this.contentEditForm.dynamicTable.tableHeaders
+        ) {
+          this.contentEditForm.dynamicTable.tableHeaders.forEach(
+            (header, index) => {
+              header.orderNum = index + 1
+            }
+          )
+        }
+      },
 
       // 绑定字典变化
       handleBindDictChange(row) {
@@ -3363,7 +3467,54 @@
         dynamicTables.forEach((row) => {
           processNode(row)
         })
+        // 重新给子节点赋值orderNum 保证所有元素orderNum字段不重复
+        // 为所有子节点分配唯一的orderNum,但保持父节点的orderNum不变
+
+        // 计算所有已存在的orderNum中的最大值
+        let maxExistingOrderNum = 0
+
+        // 首先遍历结果数组找出当前最大的orderNum
+        result.forEach((item) => {
+          const orderNum =
+            typeof item.orderNum === 'number'
+              ? item.orderNum
+              : parseInt(item.orderNum, 10) || 0
+          if (orderNum > maxExistingOrderNum) {
+            maxExistingOrderNum = orderNum
+          }
+        })
+        // 子节点orderNum从当前最大orderNum + 1开始
+        let childOrderNumCounter = maxExistingOrderNum + 1
 
+        // 创建一个映射表,用于记录每个子节点对应的新orderNum
+        const childOrderMap = new Map()
+        // 第一次遍历:为每个子节点分配新的orderNum并存储映射关系
+        function assignChildOrderNums(nodes) {
+          nodes.forEach((node) => {
+            if (node.isChild || node.isSubItem) {
+              // 为每个子节点分配唯一的orderNum
+              childOrderMap.set(node.id || node.rowid, childOrderNumCounter++)
+            }
+            // 递归处理子节点
+            if (node.children && node.children.length > 0) {
+              assignChildOrderNums(node.children)
+            }
+          })
+        }
+        // 第二次遍历:更新结果数组中的orderNum
+        assignChildOrderNums(dynamicTables)
+
+        // 应用新的orderNum到结果数组
+        result.forEach((item) => {
+          // 只更新子节点的orderNum
+          if (item.isChild || item.isSubItem) {
+            const newOrderNum =
+              childOrderMap.get(item.id) || childOrderMap.get(item.rowid)
+            if (newOrderNum) {
+              item.orderNum = newOrderNum
+            }
+          }
+        })
         return result
       },
       //保存固定表项目数据
@@ -3570,6 +3721,8 @@
         }
 
         const itemList = responseData.value.itemlist
+        const allRows = []
+        const rowMap = new Map()
 
         // 清空现有数据
         this.contentEditForm.dynamicTable.dynamicTables = []
@@ -3589,8 +3742,9 @@
             parentid: item.parentid || -1,
             isChild: isSubItem,
             isSubItem: isSubItem,
-            rowid: item.rowid || Date.now() + Math.random() + index,
+            rowid: item.rowid || this.generateUUID(),
             jsonstr: item.jsonstr || null,
+            children: [], // 添加children数组用于树形结构
           }
 
           // 确保orderNum是数字类型
@@ -3600,16 +3754,53 @@
 
           // 初始化dynamicValues并填充实际值
           dynamicTitles.forEach((title) => {
-            newRow.dynamicValues[title.rkey] = item[title.rkey] || ''
+            // 特殊处理序号字段,需要保存到dynamicValues中供输入框使用
+            if (title.rkey === '序号') {
+              // 优先使用item中的序号值,如果没有则保持为空
+              newRow.dynamicValues[title.rkey] = item[title.rkey] || ''
+            }
+            // 排除其他序号相关字段,避免重复显示
+            else if (title.rkey !== 'ordernum' && title.rkey !== 'orderText') {
+              newRow.dynamicValues[title.rkey] = item[title.rkey] || ''
+            }
           })
 
-          this.contentEditForm.dynamicTable.dynamicTables.push(newRow)
+          allRows.push(newRow)
+          // 构建rowMap用于快速查找
+          if (newRow.rowid) rowMap.set(String(newRow.rowid), newRow)
+          if (newRow.itemId) rowMap.set(String(newRow.itemId), newRow)
+        })
+
+        // 构建树形结构
+        const treeData = []
+        const parentItems = allRows.filter((item) => !item.isChild)
+
+        // 父级按orderNum正序排序
+        parentItems.sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
+
+        // 将子项添加到对应的父项的children中
+        allRows.forEach((item) => {
+          if (item.isChild) {
+            const parentId = String(item.parentid)
+            const parent = rowMap.get(parentId)
+            if (parent) {
+              parent.children.push(item)
+            }
+          }
         })
 
-        // 按orderNum排序,确保整个列表按统一序号排序
-        this.contentEditForm.dynamicTable.dynamicTables.sort((a, b) => {
-          return (a.orderNum || 0) - (b.orderNum || 0)
+        // 对子项进行排序
+        parentItems.forEach((parent) => {
+          parent.children.sort(
+            (a, b) =>
+              (Number(a.dynamicValues['序号']) || 0) -
+              (Number(b.dynamicValues['序号']) || 0)
+          )
+          treeData.push(parent)
         })
+
+        this.contentEditForm.dynamicTable.dynamicTables = treeData
+        console.log('树形结构数据:', treeData)
       },
       //分割字符串
       stringToObjects(str) {

+ 53 - 20
src/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/RegionSelector.vue

@@ -4,7 +4,11 @@
       v-model="provinceId"
       placeholder="请选择省份"
       style="margin-right: 10px; width: 35%"
-      :disabled="disabled"
+      :disabled="
+        disabled ||
+        $permission.getUserInfo().dataScope === 1 ||
+        $permission.getUserInfo().dataScope === 2
+      "
       @change="handleProvinceChange"
     >
       <el-option
@@ -18,7 +22,12 @@
       v-model="cityId"
       placeholder="请选择城市"
       style="margin-right: 10px; width: 35%"
-      :disabled="!provinceId || disabled"
+      :disabled="
+        !provinceId ||
+        disabled ||
+        $permission.getUserInfo().dataScope === 1 ||
+        $permission.getUserInfo().dataScope === 2
+      "
       @change="handleCityChange"
     >
       <el-option
@@ -31,7 +40,9 @@
     <el-select
       v-model="districtId"
       placeholder="请选择区/县"
-      :disabled="!cityId || disabled"
+      :disabled="
+        !cityId || disabled || $permission.getUserInfo().dataScope === 2
+      "
       style="width: 30%"
       @change="handleDistrictChange"
     >
@@ -333,49 +344,71 @@
 
           if (level === 2) {
             // 县
-            const res = await getCityListByPid({ pid: pid })
-            this.districts = res.value
             districtId = finalId
             districtName = finalName
+
             // 市
             const cityList = await getDistrictTree()
             const city = await this.findFirstByIdRecursive(
               cityList.value,
               pid.toString()
             )
+            cityId = Number(city.id)
+            cityName = city.name
+
+            // 获取市对应的区县列表(确保区县选项有数据)
+            const districtRes = await getCityListByPid({ pid: cityId })
+            this.districts = districtRes.value || []
+
+            // 省
             const province = await this.findFirstByIdRecursive(
               cityList.value,
               city.parentId.toString()
             )
-            const cityRes = await getCityListByPid({ pid: province.id })
-            this.cities = cityRes.value
-            cityId = Number(city.id)
-            cityName = city.name
-            // 省
+            provinceId = Number(province.id)
+            provinceName = province.name
+
+            // 获取省对应的城市列表(确保城市选项有数据)
+            const cityRes = await getCityListByPid({ pid: provinceId })
+            this.cities = cityRes.value || []
+
+            // 确保省份选项有数据(从本地省份列表中获取)
             const result = this.localProvinces.find(
-              (item) => item.id === Number(province.id)
+              (item) => item.id === provinceId
             )
-            provinceId = result.id
-            provinceName = result.name
-            provinceCode = result.code
+            if (result) {
+              provinceCode = result.code
+            }
           } else if (level === 1) {
             // 市
-            const res = await getCityListByPid({ pid: pid })
-            this.cities = res.value
             cityId = finalId
             cityName = finalName
+
+            // 获取市对应的区县列表(确保区县选项有数据)
+            const districtRes = await getCityListByPid({ pid: cityId })
+            this.districts = districtRes.value || []
+
             // 省
             if (pid) {
+              provinceId = pid
               const result = this.localProvinces.find((item) => item.id === pid)
-              provinceId = result.id
-              provinceName = result.name
-              provinceCode = result.code
+              if (result) {
+                provinceName = result.name
+                provinceCode = result.code
+              }
+
+              // 获取省对应的城市列表(确保城市选项有数据)
+              const cityRes = await getCityListByPid({ pid: provinceId })
+              this.cities = cityRes.value || []
             }
           } else if (level === 0) {
             // 省
             provinceId = finalId
             provinceName = finalName
-            await this.handleProvinceChange(provinceId)
+
+            // 获取省对应的城市列表(确保城市选项有数据)
+            const cityRes = await getCityListByPid({ pid: provinceId })
+            this.cities = cityRes.value || []
           }
 
           this.provinceId = provinceId

+ 26 - 4
src/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/index.vue

@@ -210,6 +210,7 @@
                   clearable
                   multiple
                   style="width: 80%"
+                  @change="handleUnitChange"
                 >
                   <el-option
                     v-for="unit in unitList"
@@ -706,14 +707,14 @@
             this.searchForm.areaCode[this.searchForm.areaCode.length - 1] || '',
           planYear: this.searchForm.year,
           projectName: this.searchForm.projectName,
-          pageNum: this.pagination.currentPage,
+          page: this.pagination.currentPage,
           pageSize: this.pagination.pageSize,
         }
         getDataList(params)
           .then(async (res) => {
             this.loading = false
-            this.projectList = res.value.records || []
-            this.pagination.total = res.value.total || 0
+            this.projectList = res.rows || []
+            this.pagination.total = res.total || 0
             await this.fetchRegionNames(this.projectList, 'areaCode')
             this.batchGetOrgNames() //获取监审主体名称
           })
@@ -721,7 +722,10 @@
             this.loading = false
           })
       },
-
+      handleUnitChange(value) {
+        // this.currentProject.auditedUnitId = value
+        console.log('选择的被监审单位:', value)
+      },
       // 处理选择被监审单位后的回调
       handleUnitSelected(selectedUnit) {
         this.currentProject.auditedUnitId = selectedUnit.unitId
@@ -737,6 +741,13 @@
       // 处理监审目录选择后的回调
       handleCatalogChange(value) {
         this.currentProject.catalogId = value
+        // 监审形式赋值
+        // const selectedCatalog = this.catalogList.find(
+        //   (item) => item.id === value
+        // )
+        // if (selectedCatalog) {
+        //   this.currentProject.auditType = selectedCatalog.auditType
+        // }
       },
 
       // 处理新增
@@ -761,6 +772,16 @@
           cityName: '',
           districtName: '',
         }
+        if (this.$permission.getUserInfo()) {
+          let user = this.$permission.getUserInfo()
+          if (user.dataScope === 0) {
+            this.currentProject.areaCode = user.provinceCode
+          } else if (user.dataScope === 1) {
+            this.currentProject.areaCode = user.cityCode
+          } else if (user.dataScope === 2) {
+            this.currentProject.areaCode = user.countyCode
+          }
+        }
         this.dialogVisible = true
       },
       // 处理查看
@@ -919,6 +940,7 @@
         this.dialogAddUnitVisible = false
         this.getAllUnitList()
         this.currentProject.auditedUnitId.push(value)
+        this.currentProject.areaCode = data.areaCode[data.areaCode.length - 1]
       },
     },
   }

+ 3 - 3
src/views/costAudit/projectInfo/auditProjectManage/initiation/index.vue

@@ -321,15 +321,15 @@
             this.searchForm.areaCode[this.searchForm.areaCode.length - 1] || '',
           projectYear: this.searchForm.projectYear,
           projectName: this.searchForm.projectName,
-          pageNum: this.pagination.currentPage,
+          page: this.pagination.currentPage,
           pageSize: this.pagination.pageSize,
         }
 
         try {
           getDataList(params)
             .then((res) => {
-              this.projectList = res.value.value.records
-              this.pagination.total = res.value.value.total
+              this.projectList = res.rows || []
+              this.pagination.total = res.total || 0
               this.batchGetOrgNames()
               this.batchGetUnitNames()
               this.batchGetAreaNames()

+ 10 - 11
src/views/costAudit/projectInfo/auditProjectManage/memoManage/memoManageMixin.js

@@ -22,7 +22,7 @@ export const memoManageMixin = {
         slotName: 'reminder-type',
       },
       {
-        prop: 'projectName',
+        prop: 'task',
         label: '成本监审任务',
         width: 160,
         headerAlign: 'center',
@@ -90,7 +90,7 @@ export const memoManageMixin = {
         content: '',
         startTime: '',
         endTime: '',
-        pageNum: 1,
+        page: 1,
         pageSize: 50,
       },
       listTotal: 0,
@@ -159,6 +159,8 @@ export const memoManageMixin = {
       handler(newVal) {
         if (newVal) {
           this.lunarInfo = this.getLunarInfo(this.selectedDate)
+          this.searchParams.memoDate = moment(newVal).format('YYYY-MM-DD')
+          this.handleSearch()
         }
       },
       deep: true,
@@ -315,7 +317,6 @@ export const memoManageMixin = {
         )
         return this._getBasicDateInfo(year, month, day)
       } catch (error) {
-        console.warn('农历转换出错:', error)
         // 出错时也返回基本日期信息
         return this._getBasicDateInfo(
           date.getFullYear(),
@@ -387,8 +388,8 @@ export const memoManageMixin = {
           pageSize: this.searchParams.pageSize,
         }
         const res = await getMemoList(params)
-        if (res.code == 200) {
-          this.memoList = res.value.records || []
+        if (res.rows && res.rows.length > 0) {
+          this.memoList = res.rows || []
           // 只处理day字段,不调用详情接口
           this.memoList.forEach((item) => {
             const date = new Date(item.memoDate)
@@ -396,7 +397,7 @@ export const memoManageMixin = {
           })
           // 在列表数据设置完成后,只调用一次详情接口获取所有需要的详情
           await this.getTasksByDateList()
-          this.listTotal = res.value.total || 0
+          this.listTotal = res.total || 0
         }
       } catch (error) {
         console.error('获取数据失败:', error)
@@ -404,7 +405,7 @@ export const memoManageMixin = {
     },
     handleReset() {
       this.searchParams = {
-        pageNum: 1,
+        page: 1,
         pageSize: 10,
         startTime: '',
         endTime: '',
@@ -424,7 +425,7 @@ export const memoManageMixin = {
     },
     // 处理分页变化
     handlePaginationChange({ currentPage, pageSize }) {
-      this.searchParams.pageNum = currentPage
+      this.searchParams.page = currentPage
       this.searchParams.pageSize = pageSize
       this.handleSearch()
     },
@@ -432,8 +433,6 @@ export const memoManageMixin = {
     initCalendarData(num) {
       this.selectedDate = new Date()
       this.lunarInfo = this.getLunarInfo(this.selectedDate)
-      console.log('初始化日历数据:', this.selectedDate)
-      console.log('初始化日历数据:', this.lunarInfo)
       this.handleSearch(num)
     },
     onTabChange(tab) {
@@ -442,7 +441,7 @@ export const memoManageMixin = {
       this.searchParams.year = ''
       this.searchParams.projectId = ''
       this.searchParams.content = ''
-      this.searchParams.pageNum = 1
+      this.searchParams.page = 1
       if (tab.name == 'calendar') {
         ;(this.currentYear = new Date().getFullYear()),
           (this.currentMonth = new Date().getMonth() + 1), // 月份从1开始

+ 19 - 4
src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/index.vue

@@ -70,7 +70,7 @@
               任务制定
             </el-button>
             <el-button
-              v-if="row.status != '2'"
+              v-if="row.status != '2' && showPublishButton(row)"
               type="text"
               @click="handleTaskPublish(row)"
             >
@@ -302,6 +302,21 @@
       this.handleSearch()
     },
     methods: {
+      showPublishButton(row) {
+        // projectMembers leaderId 等于 当前登录用户id 才显示发布按钮
+        let user = this.$permission.getUserInfo()
+        let auditTeamMembers = []
+        if (row.projectMembers) {
+          auditTeamMembers = row.projectMembers.split(',')
+        }
+        if (
+          this.$permission.isAdmin() ||
+          row.leaderId === user.userId ||
+          auditTeamMembers.some((item) => item === user.userId)
+        ) {
+          return true
+        }
+      },
       // 获取用户信息
       getUser() {
         getAllUserList().then((res) => {
@@ -336,11 +351,11 @@
       handleSearch() {
         getDataList({
           ...this.searchForm,
-          pageNum: this.pagination.currentPage,
+          page: this.pagination.currentPage,
           pageSize: this.pagination.pageSize,
         }).then((res) => {
-          this.taskList = res.value.value.records
-          this.pagination.total = res.value.value.total
+          this.taskList = res.rows || []
+          this.pagination.total = res.total || 0
           this.getAllUnitList()
         })
       },

+ 29 - 4
src/views/home/index.vue

@@ -104,7 +104,12 @@
           >
             <el-table-column align="center" label="预警" width="60">
               <template slot-scope="scope">
-                <el-tag v-if="scope.row.warning" type="warning">预警</el-tag>
+                <img
+                  v-if="scope.row.warning"
+                  src="@/assets/index_images/index-icon7@2x.png"
+                  alt=""
+                  style="width: 15px"
+                />
               </template>
             </el-table-column>
             <el-table-column
@@ -312,7 +317,7 @@
                         alt=""
                         style="width: 15px; height: 15px"
                       />
-                      <span class="ml10">{{ item.projectName }}</span>
+                      <span class="ml10">{{ item.task }}</span>
                     </div>
                     <div class="news-meta mb10">
                       <div class="left-icon w40">
@@ -339,7 +344,7 @@
                       </div>
                     </div>
                     <div class="news-meta">
-                      <div class="left-icon">
+                      <div class="left-icon content-text">
                         <img
                           style="
                             width: 14px;
@@ -354,6 +359,17 @@
                   </div>
                 </li>
               </ul>
+              <!-- 分页 -->
+              <el-pagination
+                v-if="listTotal > 0"
+                :current-page="searchParams.page"
+                :page-size="searchParams.pageSize"
+                :page-sizes="[50, 100]"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="listTotal"
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+              ></el-pagination>
             </el-col>
           </el-row>
         </el-card>
@@ -448,6 +464,14 @@
     },
     mounted() {
       this.$el.querySelector('div.el-calendar__header').remove()
+      let user = this.$permission.getUserInfo()
+      if (user.dataScope === 0) {
+        this.areaCode = user.provinceCode
+      } else if (user.dataScope === 1) {
+        this.areaCode = user.cityCode
+      } else if (user.dataScope === 2) {
+        this.areaCode = user.countyCode
+      }
       this.initChart()
       this.initCalendarData(5)
     },
@@ -701,7 +725,8 @@
     width: 40%;
   }
   .content-text {
-    display: inline-block;
+    display: flex;
+    align-items: center;
     width: 95%;
     overflow: hidden;
     text-overflow: ellipsis;