Explorar el Código

菜单权限一览表按钮编辑权限开放

cyy hace 2 semanas
padre
commit
e5b67df21e
Se han modificado 2 ficheros con 413 adiciones y 31 borrados
  1. 15 3
      src/api/permission/page.js
  2. 398 28
      src/views/platform/auth/board/index.vue

+ 15 - 3
src/api/permission/page.js

@@ -65,7 +65,7 @@ export function savePagePermission(params) {
 /**
  * 查询-人员权限一览列表
  * @param {*} params
- * 
+ *
  */
 export function searchPeoplePermission(params) {
   return request({
@@ -78,13 +78,25 @@ export function searchPeoplePermission(params) {
 /**
  * 导出-权限一览列表导出
  * @param {*} params
- * 
+ *
  */
 export function getFilePermission(params) {
   return request({
     url: '/platform/v3' + '/role/getFilePermission',
     method: 'post',
     data: params,
-    responseType: 'arraybuffer',
+    responseType: 'arraybuffer'
+  })
+}
+
+/**
+ * 查询-获取页面按钮权限
+ * @param {*} params
+ */
+export function getButtons(params) {
+  return request({
+    url: '/platform/v3/role/getButtons?authId=' + params,
+    method: 'post',
+    data: params
   })
 }

+ 398 - 28
src/views/platform/auth/board/index.vue

@@ -102,8 +102,8 @@
           label="功能页面名称/角色名称"
         />
         <el-table-column
-          v-for="item in columns"
-          :key="item"
+          v-for="(item, index) in columns"
+          :key="item + '_' + index"
           :prop="item"
           :label="item"
           align="center"
@@ -122,6 +122,18 @@
           </template>
           <!-- <span>{{ row }} -{{ column }}-{{ $index }}</span> -->
         </el-table-column>
+        <!--操作列begin-->
+        <el-table-column fixed="right" label="操作" align="center" width="140">
+          <template slot-scope="{ row }">
+            <el-button
+              type="text"
+              size="mini"
+              icon="ibps-icon-edit"
+              @click="handleEditButtonPermission(row)"
+              >按钮权限</el-button
+            >
+          </template>
+        </el-table-column>
         <!--操作列end-->
       </el-table>
       <div
@@ -156,15 +168,72 @@
         </el-pagination>
       </div>
     </div>
+    <!-- 按钮权限弹窗 -->
+    <el-dialog
+      title="按钮权限"
+      :visible.sync="buttonDialogVisible"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      width="560px"
+      @close="closeButtonDialog"
+    >
+      <el-form
+        ref="buttonForm"
+        :model="buttonForm"
+        label-width="80px"
+        size="mini"
+      >
+        <el-form-item
+          v-for="item in buttonFormItems"
+          :key="item.key"
+          :label="item.label"
+        >
+          <template v-if="buttonForm[item.key]">
+            <el-radio-group v-model="buttonForm[item.key].type">
+              <el-radio-button label="none">无</el-radio-button>
+              <el-radio-button label="all">所有</el-radio-button>
+              <el-radio-button label="custom">自定义</el-radio-button>
+            </el-radio-group>
+            <div
+              v-show="buttonForm[item.key].type === 'custom'"
+              style="margin-top: 8px"
+            >
+              <ibps-role-selector
+                v-model="buttonForm[item.key].roles"
+                placeholder="请选择角色"
+                multiple
+                @callback="(data) => handleRoleCallback(item.key, data)"
+              />
+            </div>
+          </template>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="el-dialog--center">
+        <el-button type="primary" size="mini" @click="confirmButtonDialog"
+          >确定</el-button
+        >
+        <el-button size="mini" @click="closeButtonDialog">关闭</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { debounce } from 'lodash'
-import { searchPagePermission, savePagePermission, getFilePermission } from '@/api/permission/page'
+import {
+  searchPagePermission,
+  savePagePermission,
+  getFilePermission,
+  getButtons
+} from '@/api/permission/page'
+import IbpsRoleSelector from '@/business/platform/org/role/selector'
 // import height from '@/mixins/height'
 export default {
   name: 'board-list',
+  components: {
+    IbpsRoleSelector
+  },
   data() {
     return {
       formInline: {
@@ -205,7 +274,24 @@ export default {
       editFalg: false,
       ibpsData: [],
       loading: false,
-      changeRows: []
+      changeRows: [],
+      // 按钮权限弹窗
+      buttonDialogVisible: false,
+      buttonPageId: '',
+      // getButtons 返回的 res.variables.data.ID_,随操作同步
+      buttonDataId: '',
+      // 原始 FUNCTION_BUTTONS_ 完整数据 { function_buttons, edit_buttons }
+      buttonPermissionPayload: null,
+      buttonFormItems: [
+        { key: 'edit', label: '编制' },
+        { key: 'add', label: '添加' },
+        { key: 'remove', label: '删除' }
+      ],
+      buttonForm: {
+        edit: { type: 'none', roles: '', rolesName: '' },
+        add: { type: 'none', roles: '', rolesName: '' },
+        remove: { type: 'none', roles: '', rolesName: '' }
+      }
     }
   },
   computed: {
@@ -244,6 +330,39 @@ export default {
     })
   },
   methods: {
+    getDefaultButtonForm() {
+      return {
+        edit: { type: 'none', roles: '', rolesName: '' },
+        add: { type: 'none', roles: '', rolesName: '' },
+        remove: { type: 'none', roles: '', rolesName: '' }
+      }
+    },
+    /**
+     * 编制/添加/删除 匹配规则
+     */
+    getButtonMatchConfigs() {
+      return [
+        {
+          key: 'edit',
+          label: '编制',
+          match: (item) =>
+            item.label === '编制' ||
+            item.code === 'bz' ||
+            item.button_type === 'openTask'
+        },
+        {
+          key: 'add',
+          label: '添加',
+          match: (item) => item.button_type === 'add' || item.label === '添加'
+        },
+        {
+          key: 'remove',
+          label: '删除',
+          match: (item) =>
+            item.button_type === 'remove' || item.label === '删除'
+        }
+      ]
+    },
     search() {
       this.loading = true
       console.log('this.pagination==>', this.pagination)
@@ -288,30 +407,33 @@ export default {
       })
     },
     exportData() {
-       getFilePermission({
-         requestPage: {
-           "limit": 999,
-           "pageNo": 1
-         },
-         customs: this.formInline
-       }).then(res => {
-         console.log('res', res)
-         let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
-         const downloadElement = document.createElement('a');
-         let href = window.URL.createObjectURL(blob);
-         downloadElement.href = href;
-         downloadElement.download = "菜单权限一览列表.xlsx"; // 文件名字
-         document.body.appendChild(downloadElement);
-         downloadElement.click();
-         document.body.removeChild(downloadElement); // 下载完成移除元素
-         window.URL.revokeObjectURL(href); // 释放掉blob对象
-         this.$message.success('导出成功');
-       }).catch(error => {
-         console.error('导出失败:', error);
-         this.$message.error('导出失败,请重试');
-       })
-
-     },
+      getFilePermission({
+        requestPage: {
+          limit: 999,
+          pageNo: 1
+        },
+        customs: this.formInline
+      })
+        .then((res) => {
+          console.log('res', res)
+          let blob = new Blob([res.data], {
+            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
+          })
+          const downloadElement = document.createElement('a')
+          let href = window.URL.createObjectURL(blob)
+          downloadElement.href = href
+          downloadElement.download = '菜单权限一览列表.xlsx' // 文件名字
+          document.body.appendChild(downloadElement)
+          downloadElement.click()
+          document.body.removeChild(downloadElement) // 下载完成移除元素
+          window.URL.revokeObjectURL(href) // 释放掉blob对象
+          this.$message.success('导出成功')
+        })
+        .catch((error) => {
+          console.error('导出失败:', error)
+          this.$message.error('导出失败,请重试')
+        })
+    },
     rowChange(row) {
       const index = this.changeRows.findIndex((t) => t.pageId === row.pageId)
       if (index === -1) {
@@ -344,6 +466,254 @@ export default {
       }
       this.editFalg = true
     },
+    /**
+     * 固定列:按钮权限
+     */
+    handleEditButtonPermission(row) {
+      getButtons(row.pageId)
+        .then((res) => {
+          const root =
+            res && res.variables && res.variables.data
+              ? res.variables.data
+              : null
+          // 同步全局 ID_
+          this.buttonDataId =
+            root && root.ID_ != null && root.ID_ !== '' ? root.ID_ : ''
+          const payload = this.parseButtonPermissionPayload(res)
+          const buttons = (payload && payload.function_buttons) || []
+          if (!buttons.length) {
+            this.$message.warning('暂无按钮权限数据')
+            return
+          }
+          const formResult = this.buildButtonFormByButtons(buttons)
+          if (!formResult.items.length) {
+            this.$message.warning('暂无按钮权限数据')
+            return
+          }
+          this.buttonPageId = row.pageId
+          this.buttonPermissionPayload = payload
+          this.buttonFormItems = formResult.items
+          this.buttonForm = formResult.form
+          this.buttonDialogVisible = true
+        })
+        .catch((error) => {
+          console.error('获取按钮权限失败:', error)
+          this.$message.error('获取按钮权限失败')
+        })
+    },
+    /**
+     * 解析 res.variables.data.FUNCTION_BUTTONS_ 完整结构
+     * @returns {{ function_buttons: Array, edit_buttons: Array }|null}
+     */
+    parseButtonPermissionPayload(res) {
+      const root =
+        res && res.variables && res.variables.data ? res.variables.data : null
+      if (!root) return null
+
+      let raw =
+        root.FUNCTION_BUTTONS_ != null
+          ? root.FUNCTION_BUTTONS_
+          : root.FUNCTION_BUTTONS_m != null
+          ? root.FUNCTION_BUTTONS_m
+          : root.function_buttons != null
+          ? root.function_buttons
+          : null
+      if (raw == null || raw === '') return null
+
+      if (typeof raw === 'string') {
+        try {
+          raw = JSON.parse(raw)
+        } catch (e) {
+          console.error('解析 FUNCTION_BUTTONS_ 失败:', e)
+          return null
+        }
+      }
+
+      // 已是完整对象
+      if (raw && !Array.isArray(raw) && typeof raw === 'object') {
+        return {
+          function_buttons: Array.isArray(raw.function_buttons)
+            ? JSON.parse(JSON.stringify(raw.function_buttons))
+            : [],
+          edit_buttons: Array.isArray(raw.edit_buttons)
+            ? JSON.parse(JSON.stringify(raw.edit_buttons))
+            : []
+        }
+      }
+
+      // 仅按钮数组
+      if (Array.isArray(raw)) {
+        return {
+          function_buttons: JSON.parse(JSON.stringify(raw)),
+          edit_buttons: []
+        }
+      }
+      return null
+    },
+    /**
+     * 根据 function_buttons 构建弹窗表单(仅展示匹配到的编制/添加/删除)
+     */
+    buildButtonFormByButtons(buttons) {
+      const configs = this.getButtonMatchConfigs()
+      const items = []
+      const form = {}
+      configs.forEach((cfg) => {
+        const button = (buttons || []).find((item) => item && cfg.match(item))
+        if (!button) return
+        items.push({ key: cfg.key, label: button.label || cfg.label })
+        form[cfg.key] = this.resolveButtonRights(button)
+      })
+      return { items, form }
+    },
+    /**
+     * 解析单个按钮的 rights 回显
+     * 优先级:none(无) > all(所有) > role(自定义)
+     */
+    resolveButtonRights(button) {
+      if (!button) {
+        return { type: 'none', roles: '', rolesName: '' }
+      }
+      const rights = Array.isArray(button.rights)
+        ? button.rights
+        : button.rights
+        ? [button.rights]
+        : []
+      const hasNone = rights.some((item) => item && item.type === 'none')
+      const hasAll = rights.some((item) => item && item.type === 'all')
+      const roleRights = rights.filter((item) => item && item.type === 'role')
+      // 存在多种时优先回显无、所有
+      if (hasNone) {
+        return { type: 'none', roles: '', rolesName: '' }
+      }
+      if (hasAll) {
+        return { type: 'all', roles: '', rolesName: '' }
+      }
+      if (roleRights.length > 0) {
+        const roles = roleRights
+          .map((item) => item.rightsId)
+          .filter((id) => id !== undefined && id !== null && id !== '')
+          .join(',')
+        const rolesName = roleRights
+          .map((item) => item.rightsName)
+          .filter((name) => name !== undefined && name !== null && name !== '')
+          .join(',')
+        return { type: 'custom', roles, rolesName }
+      }
+      return { type: 'none', roles: '', rolesName: '' }
+    },
+    /**
+     * 角色选择回调,同步角色名称
+     */
+    handleRoleCallback(key, data) {
+      if (!this.buttonForm[key]) return
+      const list = Array.isArray(data) ? data : data ? [data] : []
+      const rolesName = list
+        .map((item) => item && item.name)
+        .filter((name) => !!name)
+        .join(',')
+      this.$set(this.buttonForm[key], 'rolesName', rolesName)
+    },
+    /**
+     * 根据表单生成 rights
+     */
+    buildRightsByFormItem(formItem) {
+      if (!formItem) {
+        return [{ type: 'none' }]
+      }
+      if (formItem.type === 'all') {
+        return [{ type: 'all' }]
+      }
+      if (formItem.type === 'custom') {
+        return [
+          {
+            type: 'role',
+            rightsId: formItem.roles || '',
+            rightsName: formItem.rolesName || ''
+          }
+        ]
+      }
+      return [{ type: 'none' }]
+    },
+    /**
+     * 按弹窗表单回写并重新拼接 FUNCTION_BUTTONS_ 字符串
+     */
+    rebuildButtonPermissionString() {
+      const payload = this.buttonPermissionPayload
+        ? JSON.parse(JSON.stringify(this.buttonPermissionPayload))
+        : { function_buttons: [], edit_buttons: [] }
+      const buttons = Array.isArray(payload.function_buttons)
+        ? payload.function_buttons
+        : []
+      const configs = this.getButtonMatchConfigs()
+      configs.forEach((cfg) => {
+        const formItem = this.buttonForm[cfg.key]
+        if (!formItem) return
+        const button = buttons.find((item) => item && cfg.match(item))
+        if (!button) return
+        button.rights = this.buildRightsByFormItem(formItem)
+      })
+      const result = {
+        function_buttons: buttons,
+        edit_buttons: Array.isArray(payload.edit_buttons)
+          ? payload.edit_buttons
+          : []
+      }
+      return JSON.stringify(result)
+    },
+    closeButtonDialog() {
+      this.buttonDialogVisible = false
+      this.buttonPageId = ''
+      this.buttonDataId = ''
+      this.buttonPermissionPayload = null
+      this.buttonFormItems = [
+        { key: 'edit', label: '编制' },
+        { key: 'add', label: '添加' },
+        { key: 'remove', label: '删除' }
+      ]
+      this.buttonForm = this.getDefaultButtonForm()
+    },
+    /**
+     * 按钮权限弹窗确定
+     */
+    async confirmButtonDialog() {
+      // 自定义类型未选择角色时提示
+      const invalid = (this.buttonFormItems || []).some((item) => {
+        const formItem = this.buttonForm[item.key]
+        return (
+          formItem &&
+          formItem.type === 'custom' &&
+          (!formItem.roles || !String(formItem.roles).trim())
+        )
+      })
+      if (invalid) {
+        this.$message.warning('请完善自定义角色')
+        return
+      }
+      const buttonPermissionStr = this.rebuildButtonPermissionString()
+      console.log('FUNCTION_BUTTONS_==>', buttonPermissionStr)
+      console.log('buttonDataId(ID_)==>', this.buttonDataId)
+      const updateParamsRecord = {
+        tableName: 'ibps_data_template_tpl',
+        updList: [
+          {
+            where: {
+              id_: this.buttonDataId
+            },
+            param: {
+              FUNCTION_BUTTONS_: buttonPermissionStr
+            }
+          }
+        ]
+      }
+      try {
+        await this.$common.request('update', updateParamsRecord)
+        this.$message.success('设置成功')
+        this.closeButtonDialog()
+      } catch (error) {
+        console.error('设置按钮权限失败:', error)
+        this.$message.error('设置失败')
+      }
+    },
     tableSave() {
       if (this.changeRows.length === 0) {
         this.$message.warning('列表无数据变更')