ludc
2024-01-16 02e7ca80d849ad8a99974bd08f9e68a78f36d601
分类授权数据授权界面编写与接口修改
已修改20个文件
已添加1个文件
675 ■■■■ 文件已修改
Source/UBCS-WEB/src/components/Theme/ClassifyAuthDialog.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Theme/DataAuthDialog.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Theme/ThemeClassifyTrees.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/main.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/entity/ClassifyAuth.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClient.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClientFallback.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/ClassifyAuthController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/MenuController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RoleController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/feign/SysClient.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/mapper/ClassifyAuthMapper.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/mapper/MenuMapper.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IClassifyAuthService.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IMenuService.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IRoleService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/ClassifyAuthServiceImpl.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/MenuServiceImpl.java 98 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/RoleServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/resources/mapper/MenuMapper.xml 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/Theme/ClassifyAuthDialog.vue
@@ -40,6 +40,7 @@
            v-if="item.type === 'select'"
            slot="prepend"
            v-model="row[item.prop]"
            @change="roleChange"
          >
            <el-option
              v-for="optionItem in roleList"
@@ -188,6 +189,11 @@
      this.$emit('update:visible', false);
      this.classifyAuthData = [];
    },
    // è§’色改变时
    roleChange(roleId){
      console.log(roleId);
    },
    // å¢žåŠ è¡Œ
    addClassifyAuth() {
      if(this.roleList.length<=0){
Source/UBCS-WEB/src/components/Theme/DataAuthDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,343 @@
<template>
  <el-dialog
    v-dialogDrag
    :close-on-click-modal="false"
    :visible.sync="isShowDialog"
    append-to-body
    class="avue-dialog avue-dialog--top"
    title="数据授权"
    top="-45px" @close="closeDialog">
    <el-table
      ref="dataTable"
      v-loading="isLoading"
      :data="classifyAuthData"
      :header-cell-style="{ background: '#FAFAFA', color: '#505050' }"
      :height="tableHeight"
      border
      class="cus-table"
      @select="handleSelection"
      @row-click="handleRowClick"
      @select-all="handleSelectionAll"
      @selection-change="handleSelectionChange"
      @sort-change="sortChange"
    >
      <el-table-column
        type="selection"
        width="55"
      ></el-table-column>
      <el-table-column
        v-for="(item, index) in classifyAuthHeader"
        v-if="classifyAuthHeader.length !== 0"
        :key="index"
        :label="item.label"
        :prop="item.prop"
        :show-overflow-tooltip="true"
        :width="item.width"
        align="center"
      >
        <template slot-scope="{ row }">
          <el-select
            v-if="item.type === 'select'"
            slot="prepend"
            v-model="row[item.prop]"
            @change="roleChange"
          >
            <el-option
              v-for="optionItem in roleList"
              :key="optionItem.id"
              :label="optionItem.roleName"
              :value="optionItem.id"
            >
            </el-option>
          </el-select>
          <el-input
            v-if="item.type === 'text'"
            v-model="row[item.prop]"
            readonly
            type="text"
          >
          </el-input>
          <el-checkbox
            v-if="item.type === 'checkbox'"
            v-model="row[item.prop]">
          </el-checkbox>
        </template>
      </el-table-column>
    </el-table>
    <div slot="footer" class="dialog-footer">
      <el-button type="info" plain @click="selectAllButton">按钮全选</el-button>
      <el-button class="el-icon-plus" type="success" plain @click="addClassifyAuth"></el-button>
      <el-button class="el-icon-minus" type="warning" plain @click="subClassifyAuth"></el-button>
      <el-button type="primary" plain @click="submit">提 äº¤</el-button>
      <el-button type="danger" plain @click="isShowDialog = false">关 é—­</el-button>
    </div>
  </el-dialog>
</template>
<script>
import {getButtonByParentCode} from "@/api/system/menu"
import {getPage} from "@/api/system/role"
import {saveOrUpdate, getClassifyAuthList} from "@/api/system/classifyAuth"
import {v4 as uuidv4} from 'uuid';
export default {
  name: "dataAuthDialog.vue",
  props: {
    classifyData: {
      type: "Object",
      default: "",
    },
    /**对话框显示隐藏控制*/
    visible: {
      type: "Boolean",
      default: false,
    },
  },
  data() {
    return {
      // å¯¹è¯æ¡†æ˜¾ç¤ºæŽ§åˆ¶
      isShowDialog: this.visible,
      isLoading: false,
      tableHeight: 'calc(100vh - 550px)',
      classifyAuthData: [],
      //列头
      classifyAuthHeader: [],
      //按钮数据
      classifyAuthButton: [],
      //角色列表
      roleList: [],
      //当前选中的表格行
      selectList: [],
    };
  },
  watch: {
    // ç›‘听父组件传的窗口显示隐藏的值
    visible() {
      if (this.visible) {
        this.isShowDialog = this.visible;
        return new Promise((resolve, reject) => {
          getButtonByParentCode({code: this.classifyData.attributes.id}).then(res => {
            // è®°å½•按钮数据
            this.classifyAuthButton = res.data.data;
            const list = res.data.data;
            let tempData = [];
            // è§’色列
            tempData.push({
              label: "角色",
              prop: "roleData",
              type: "select",
              width: 150,
            });
            // ç¼–码项分类授权
            tempData.push({
              label: "编码项数据授权",
              prop: "classifyItem",
              type: "text",
              width: 180,
            });
            list.forEach(item => {
              let columnItem = {
                label: item.name,
                prop: item.id,
                type: "checkbox",
                width: 180,
              };
              tempData.push(columnItem);
            })
            this.classifyAuthHeader = tempData
            resolve();
          }).catch(err => {
            reject(err)
          });
          // èŽ·å–è§’è‰²åˆ—è¡¨
          getPage(1, -1, null).then(res => {
            this.roleList = res.data.data.records;
          });
          // èŽ·å–è¯¥åˆ†ç±»ä¸‹å·²æŽˆæƒçš„åˆ†ç±»æŽˆæƒä¿¡æ¯
          getClassifyAuthList({classifyId: this.classifyData.oid,authType: "data_auth"}).then(res => {
            //console.log(res.data.data);
            let authDatas = res.data.data;
            if (authDatas.length > 0) {
              authDatas.forEach(authData => {
                let item = {
                  oid: authData.oid,
                  roleData: authData.roleId,
                  classifyItem: this.classifyData.label,
                  uuid: uuidv4(),//生成唯一的id
                }
                //将按钮设置进去
                authData.buttonIdList.forEach(data => {
                  Vue.set(item, data, true);
                });
                //console.log(item)
                this.classifyAuthData.push(item);
              })
            }
          });
        });
      }
    },
  },
  computed: {},
  mounted() {
  },
  created() {
  },
  methods: {
    // å…³é—­å¯¹è¯æ¡†
    closeDialog() {
      this.$emit('update:visible', false);
      this.classifyAuthData = [];
    },
    // è§’色改变时
    roleChange(roleId){
      console.log(roleId);
    },
    // å¢žåŠ è¡Œ
    addClassifyAuth() {
      if(this.roleList.length<=0){
        this.$message.warning("当前租户不存在角色信息!");
        return;
      }
      let item = {
        roleData: this.roleList[0].id,
        classifyItem: this.classifyData.label,
        uuid: uuidv4(),//生成唯一的id
      }
      //将按钮设置进去
      this.classifyAuthButton.forEach(data => {
        Vue.set(item, data.id, false);
      })
      //console.log(item)
      this.classifyAuthData.push(item)
      // console.log(this.classifyAuthData);
    },
    // åˆ é™¤è¡Œ
    subClassifyAuth() {
      for (let item of this.selectList) {
        let index = this.classifyAuthData.findIndex(data => data.index === item.index);
        if (index !== -1) {
          this.classifyAuthData.splice(index, 1);
        }
      }
    },
    handleRowClick(row, column) {
      this.selectList.push(row);
      this.$refs.dataTable.toggleRowSelection(row);
    },
    // å¤šé€‰
    handleSelectionChange(list) {
      this.selectList = list;
      //console.log("多选");
    },
    // é€‰æ‹©å…¨éƒ¨
    handleSelectionAll(list) {
      this.selectList = list;
    },
    // ä¿å­˜åˆ†ç±»æŽˆæƒä¿¡æ¯
    submit() {
      if (this.classifyAuthData.length <= 0) {
        this.$message.warning('授权列表为空!')
        return;
      }
      let isRepeat = false;
      // éåŽ†æ•°ç»„ï¼Œæ¯”è¾ƒåŽé¢çš„å¯¹è±¡çš„roleData是否与前面的对象相等
      for (let i = 0; i < this.classifyAuthData.length - 1; i++) {
        let currentRoleId = this.classifyAuthData[i].roleData;
        for (let j = i + 1; j < this.classifyAuthData.length; j++) {
          if (currentRoleId === this.classifyAuthData[j].roleData) {
            isRepeat = true;
            break;
          }
        }
        if (isRepeat) {
          break;
        }
      }
      if (isRepeat) {
        this.$message.warning("角色和分类已经存在,请重新配置!");
        return;
      }
      let form = [];
      let flag = false;
      this.classifyAuthData.forEach(item => {
        let itemButtonList = [];
        //筛选出按钮勾选为true的列
        for (let key in item) {
          if (item[key] === true) {
            itemButtonList.push(key);
          }
        }
        /**如果itemButtonList为空证明是,
         æ·»åŠ äº†è§’è‰²ä½†æ˜¯æ²¡å‹¾é€‰ä»»ä½•çš„æŒ‰é’®*/
        if (itemButtonList.length <= 0) {
          flag = true;
          return;
        }
        let data = {
          oid: item.oid,
          roleId: item.roleData,
          classifyId: this.classifyData.oid,
          buttonIds: itemButtonList.join(","),
          authType: "data_auth",
        }
        form.push(data);
      });
      if (flag) {
        this.$message.warning('有未勾选操作的权限,不允许授权')
        return;
      }
      // console.log(form)
      // è°ƒç”¨ä¿å­˜åˆ†ç±»æŽˆæƒçš„æŽ¥å£
      saveOrUpdate(form).then(res => {
        this.$message({
          type: "success",
          message: res.data.msg,
        });
        // this.isShowDialog = false
      }, (error) => {
        window.console.log(error);
      })
    },
    // å…¨é€‰æŒ‰é’®
    selectAllButton(){
      if(this.selectList.length!==1){
        this.$message.warning("请只选择一行需要全选的按钮的数据行!");
        return;
      }
      this.classifyAuthButton.forEach(item => {
        //console.log("item",item);
        Vue.set(this.selectList[0], item.id, true);
      });
      //console.log("this.selectList",this.selectList);
    },
  },
};
</script>
<style lang="scss" scoped>
// æ»šåŠ¨æ¡æ ·å¼ä¿®æ”¹
// æ»šåŠ¨æ¡çš„å®½åº¦
/deep/ .el-table__body-wrapper::-webkit-scrollbar {
  height: 15px; // çºµå‘滚动条 å¿…写
  background: white;
  border: white;
  width: 10px;
}
// æ»šåŠ¨æ¡çš„æ»‘å—
/deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background-color: #ececec;
  border-radius: 20px;
  border: #ececec;
}
/deep/ .el-table__body-wrapper {
  height: calc(100% - 50px) !important;
}
</style>
Source/UBCS-WEB/src/components/Theme/ThemeClassifyTrees.vue
@@ -32,6 +32,10 @@
                       style="width: 56px;text-align: center;padding-left: 3px" type="primary"
                       @click="classifyAuthHandler">分类授权
            </el-button>
            <el-button v-if="permissionList.classifyAuth" plain size="small"
                       style="width: 56px;text-align: center;padding-left: 3px" type="primary"
                       @click="dataAuthHandler">数据授权
            </el-button>
          </div>
          <!-- å·¦ä¾§æ ‘-->
@@ -116,6 +120,11 @@
          :classifyData="classifyData"
          :visible.sync="classifyAuthVisible"
        ></classify-auth-dialog>
        <!-- æ•°æ®æŽˆæƒå¯¹è¯æ¡† -->
        <data-auth-dialog
          :classifyData="classifyData"
          :visible.sync="dataAuthVisible"
        ></data-auth-dialog>
      </basic-container>
    </el-aside>
    <el-main>
@@ -452,6 +461,8 @@
      TreeAddFormVisible: false,
      //分类授权对话框
      classifyAuthVisible: false,
      //数据授权对话框
      dataAuthVisible: false,
      //当前点击项
      nodeClickList: "",
      ClonenodeClickList: "",
@@ -759,6 +770,15 @@
      }
      this.classifyData = this.nodeClickList;
      this.classifyAuthVisible = true;
    },
    // æ•°æ®æŽˆæƒå¯¹è¯æ¡†æ‰“å¼€
    dataAuthHandler() {
      if (this.nodeClickList.oid === '' || this.nodeClickList.oid === undefined) {
        this.$message.warning('请至少选择一条数据!')
        return;
      }
      this.classifyData = this.nodeClickList;
      this.dataAuthVisible = true;
    },
    flowingDependHandler() {
      if (this.nodeClickList.length <= 0) {
@@ -1116,10 +1136,10 @@
    },
    //树点击事件
    async nodeClick(data) {
      getAuthButtonList({classifyId: data.oid}).then(res => {
      getAuthButtonList({classifyId: data.oid,code: "classifyTree",authType: "classify_auth"}).then(res => {
        this.btnAuthList = res.data.data;
      }).catch(error => {
        console.log(error)
        window.console.log(error)
      })
      //操作新增和修改的业务类型隐藏
      this.TreeFlagCode = !data;
Source/UBCS-WEB/src/main.js
@@ -38,6 +38,7 @@
import classifyTrees from "@/components/Theme/ThemeClassifyTrees"
import classifyTreeform from "@/components/Theme/ThemeClassifyTreeform"
import classifyAuthDialog from "@/components/Theme/ClassifyAuthDialog"
import dataAuthDialog from "@/components/Theme/DataAuthDialog"
import TemplatePro from "@/components/Theme/ThemeTemplatePro"
import attrCrud from "@/components/Theme/ThemeAttrCrud"
import formulaEditor from "@/components/code-dialog-page/formulaEditor"
@@ -100,6 +101,7 @@
Vue.component('originalLink',originalLink)
Vue.component('classifyTrees',classifyTrees)
Vue.component('classifyAuthDialog',classifyAuthDialog)
Vue.component('dataAuthDialog',dataAuthDialog)
Vue.component('classifyTreeform',classifyTreeform)
Vue.component('TemplatePro',TemplatePro)
Vue.component('formulaEditor',formulaEditor)
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/entity/ClassifyAuth.java
@@ -9,7 +9,7 @@
import java.util.List;
/**
 * åˆ†ç±»æŽˆæƒå‚数对象
 * åˆ†ç±»æŽˆæƒï¼Œæ•°æ®æŽˆæƒå‚数对象
 * @author ludc
 * @date 2023/12/25 15:36
 */
@@ -40,4 +40,9 @@
     */
    private String buttonIds;
    /**
     * æŽˆæƒç±»åž‹
     */
    private String authType;
}
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClient.java
@@ -112,7 +112,7 @@
     * @return List<Menu>
     */
    @GetMapping(MENU_BUTTON)
    R<List<Menu>> getMenuButtonByType(@RequestParam("btmType") String btmType);
    R<List<Menu>> getMenuButtonByType(@RequestParam("classifyId") String classifyId,@RequestParam("btmType") String btmType,@RequestParam("authType") String authType);
    /**
     * èŽ·å–éƒ¨é—¨
Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClientFallback.java
@@ -48,7 +48,7 @@
    }
    @Override
    public R<List<Menu>> getMenuButtonByType(String btmType) {
    public R<List<Menu>> getMenuButtonByType(String classifyId, String btmType, String authType) {
        return R.fail("获取数据失败");
    }
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
@@ -3896,11 +3896,10 @@
    @Override
    public MdmUIInfoVO getUIInfoByClassifyOid(String codeClassifyOid, String functionId) {
        VciBaseUtil.alertNotNull(codeClassifyOid, "主题库分类主键");
        MdmUIInfoVO uiInfoVO = getTableDefineByTemplateVO(getUsedTemplateByClassifyOid(codeClassifyOid));
        uiInfoVO.setLeaf(classifyService.countChildrenByClassifyOid(codeClassifyOid) == 0);
        if (StringUtils.isNotBlank(functionId) && !"~".equalsIgnoreCase(functionId)) {
            List<Menu> buttonVOS = iSysClient.getMenuButtonByType(uiInfoVO.getTemplateVO().getBtmTypeId()).getData();
            List<Menu> buttonVOS = iSysClient.getMenuButtonByType(codeClassifyOid,uiInfoVO.getTemplateVO().getBtmTypeId(),"data_auth").getData();
            //            List<SmOperationVO> operationVOS = operationService.listButtonByFunctionId(functionId);
            //            if (operationVOS == null) {
            //                operationVOS = new ArrayList<>();
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/ClassifyAuthController.java
@@ -1,7 +1,6 @@
package com.vci.ubcs.system.controller;
import com.vci.ubcs.system.entity.ClassifyAuth;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.service.IClassifyAuthService;
import com.vci.ubcs.system.vo.ClassifyAuthVO;
import io.swagger.annotations.Api;
@@ -11,11 +10,12 @@
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
 * åˆ†ç±»æŽˆæƒ
 * åˆ†ç±»æŽˆæƒ,数据授权
 * @author ludc
 * @date 2023/12/20 11:33
 */
@@ -52,11 +52,13 @@
    /**
     * æŸ¥è¯¢è¯¥åˆ†ç±»ä¸‹ï¼Œå½“前登录的角色有哪些按钮权限
     * @param classifyId
     * @param menuCode
     * @param authType
     * @return
     */
    @GetMapping("/getAuthButtonList")
    public R<Map<String,Boolean>> getAuthButtonList(@RequestParam("classifyId") String classifyId){
        return R.data(classifyAuthService.getAuthButtonList(classifyId));
    public R<Map<String,Boolean>> getAuthButtonList(@Valid @RequestParam("classifyId") String classifyId,@Valid @RequestParam("code") String menuCode,@Valid @RequestParam("authType") String authType){
        return R.data(classifyAuthService.getAuthButtonList(classifyId,menuCode,authType));
    }
}
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/MenuController.java
@@ -317,4 +317,14 @@
        return menuService.cloneMenuButton(buttonCloneVO.getMenuId(), buttonCloneVO.getButtonIds());
    }
    /**
     * æ ¹æ®è§’色id获取已授权的按钮信息
     * @param roleId
     * @return
     */
    @GetMapping("/getButtonsByRoleId")
    public R<List<Menu>> getButtonsByRoleId(@Valid @RequestParam("roleId") String roleId,@Valid @RequestParam("code") String menuCode){
        return R.data(menuService.getButtonsByRoleId(roleId,menuCode));
    }
}
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/RoleController.java
@@ -22,6 +22,7 @@
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.vci.ubcs.system.cache.NacosConfigCache;
import com.vci.ubcs.system.cache.SysCache;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.entity.Role;
import com.vci.ubcs.system.service.IRoleService;
import com.vci.ubcs.system.user.cache.UserCache;
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/feign/SysClient.java
@@ -83,8 +83,8 @@
    @Override
    @GetMapping(MENU_BUTTON)
    public R<List<Menu>> getMenuButtonByType(String btmType) {
        return R.data(menuService.getMenuButtonByType(btmType, AuthUtil.getUserId()));
    public R<List<Menu>> getMenuButtonByType(String classifyId,String btmType,String authType) {
        return R.data(menuService.getMenuButtonByType(classifyId,btmType,authType));
    }
    @Override
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/mapper/ClassifyAuthMapper.java
@@ -7,6 +7,7 @@
import java.util.List;
/**
 * åˆ†ç±»æŽˆæƒ,数据授权
 * @author ludc
 * @date 2023/12/25 15:50
 */
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/mapper/MenuMapper.java
@@ -135,11 +135,18 @@
    List<Menu> selectMenuChildByBtnType(String btmType,List<String> roleIds);
    /**
     * æ ¹æ®çˆ¶èœå•code查询菜单的子按钮
     * æ ¹æ®çˆ¶èœå•code和角色id获取已授权的按钮信息
     *
     * @return
     */
    List<Menu> getButtonByParentCode(@Param("code") String code);
    List<Menu> getButtonsByRoleIdAndCode(@Param("roleId") String roleId, @Param("code") String code);
    /**
     * æ ¹æ®çˆ¶èœå•code和角色id获取已授权的按钮信息
     *
     * @return
     */
    List<Menu> getButtonByIdsOrByParentCode(@Param("roleIds") String roleIds, @Param("code") String code,@Param("ids") List<String> ids);
    /**
     * æƒé™é…ç½®èœå•
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IClassifyAuthService.java
@@ -10,7 +10,7 @@
import java.util.Map;
/**
 * åˆ†ç±»æŽˆæƒ
 * åˆ†ç±»æŽˆæƒ,数据授权
 * @author ludc
 * @date 2023/12/25 15:34
 */
@@ -33,9 +33,20 @@
    /**
     * æŸ¥è¯¢è¯¥åˆ†ç±»ä¸‹ï¼Œå½“前登录的角色有哪些按钮权限
     * @param classifyId
     * @param menuCode
     * @param authType
     * @return
     */
    Map<String,Boolean> getAuthButtonList(String classifyId);
    Map<String,Boolean> getAuthButtonList(String classifyId,String menuCode,String authType);
    /**
     * æŸ¥è¯¢è¯¥ä¸»æ•°æ®ä¸‹ï¼Œå½“前登录的角色有哪些按钮权限
     * @param classifyId
     * @param menuCode
     * @param authType
     * @return
     */
    List<Menu> getAuthMenuButtonList(String classifyId,String menuCode,String authType);
    /**
     * æ ¹æ®è§’色id查看有哪些分类具备查看权限
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IMenuService.java
@@ -175,10 +175,12 @@
    /**
     * èŽ·å–èœå•ä¸‹é¢çš„æŒ‰é’®
     * @param btmType ä¸šåŠ¡ç±»åž‹
     * @return List<Menu>
     * @param classifyId
     * @param btmType
     * @param authType
     * @return
     */
    List<Menu> getMenuButtonByType(String btmType,Long userId);
    List<Menu> getMenuButtonByType(String classifyId,String btmType, String authType);
    /**
     * æ ¹æ®code和用户id查询菜单信息
@@ -214,7 +216,18 @@
    /**
     * æ ¹æ®ä¸»é”®èŽ·å–èœå•ä¿¡æ¯
     * @param ids
     * @param menuCode
     * @param roleIds
     * @return
     */
    List<Menu> getMenuListById(List<String> ids,String parentId);
    List<Menu> getMenuListByCode(List<String> ids,String menuCode,String roleIds);
    /**
     * æ ¹æ®è§’色id获取已授权的按钮信息
     * @param roleId
     * @param menuCode
     * @return
     */
    List<Menu> getButtonsByRoleId(String roleId, String menuCode);
}
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IRoleService.java
@@ -18,6 +18,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.entity.Role;
import com.vci.ubcs.system.vo.RoleVO;
import org.springblade.core.tool.api.R;
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/ClassifyAuthServiceImpl.java
@@ -19,6 +19,8 @@
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -26,7 +28,7 @@
import java.util.stream.Collectors;
/**
 * åˆ†ç±»æŽˆæƒ
 * åˆ†ç±»æŽˆæƒ,数据授权
 * @author ludc
 * @date 2023/12/25 15:35
 */
@@ -87,7 +89,8 @@
            throw new ServiceException("缺少必传参数分类id");
        }
        LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
            .lambda().eq(ClassifyAuth::getClassifyId,classifyAuthVO.getClassifyId());
            .lambda().eq(ClassifyAuth::getClassifyId,classifyAuthVO.getClassifyId())
            .eq(ClassifyAuth::getAuthType,classifyAuthVO.getAuthType());
        List<ClassifyAuth> classifyAuths = this.classifyAuthMapper.selectList(wrapper);
        if(classifyAuths.isEmpty()){
            return new ArrayList<ClassifyAuthVO>();
@@ -98,9 +101,33 @@
    /**
     * æŸ¥è¯¢è¯¥åˆ†ç±»ä¸‹ï¼Œå½“前登录的角色有哪些按钮权限
     * @param classifyId
     * @param menuCode
     * @param authType
     * @return
     */
    public Map<String,Boolean> getAuthButtonList(String classifyId){
    public Map<String,Boolean> getAuthButtonList(String classifyId,String menuCode,String authType){
        List<Menu> menuList = this.getButtonList(classifyId, menuCode, authType);
        if(menuList.isEmpty()){
            return new HashMap<>();
        }
        Map<String, Boolean> buttonMaps = menuList.stream()
            .collect(Collectors.toMap(Menu::getCode, menu -> true));
        return buttonMaps;
    }
    /**
     * æŸ¥è¯¢è¯¥ä¸»æ•°æ®ä¸‹ï¼Œå½“前登录的角色有哪些按钮菜单权限
     * @param classifyId
     * @param menuCode
     * @param authType
     * @return
     */
    public List<Menu> getAuthMenuButtonList(String classifyId,String menuCode,String authType){
        List<Menu> buttonList = getButtonList(classifyId, menuCode, authType);
        return buttonList;
    }
    private List<Menu> getButtonList(String classifyId,String menuCode,String authType){
        if(Func.isBlank(classifyId)){
            throw new ServiceException("必传参数分类oid不能为空!");
        }
@@ -115,6 +142,7 @@
        // å…ˆæŸ¥è¯¢æŒ‰é’®id列表
        LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
            .lambda().eq(ClassifyAuth::getClassifyId, classifyId)
            .eq(ClassifyAuth::getAuthType,authType)
            .in(ClassifyAuth::getRoleId, roleIds);
        List<ClassifyAuth> classifyAuths = this.classifyAuthMapper.selectList(wrapper);
        //如果当前分类没有找到授权配置,就依次从当前节点往上层节点找授权配置,找到了就停止,没找到就一直找到最后
@@ -139,20 +167,14 @@
        Boolean isAdmin = VciBaseUtil.checkAdminTenant();
        // æœªé…ç½®æŒ‰é’®æƒé™
        if(!isAdmin && (classifyAuths.isEmpty() || Func.isBlank(classifyAuths.get(0).getButtonIds()))){
            return new HashMap<>();
            return new ArrayList<>();
        }
        List<String> condition1 = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        // å¦‚果不是超管用户
        if(!isAdmin){
            condition1.addAll(Arrays.asList(classifyAuths.get(0).getButtonIds().split(",")));
            ids.addAll(Arrays.asList(classifyAuths.get(0).getButtonIds().split(",")));
        }
        List<Menu> menuList = menuService.getMenuListById(condition1,"1648879284590858241");
        if(menuList.isEmpty()){
            return new HashMap<>();
        }
        Map<String, Boolean> buttonMaps = menuList.stream()
            .collect(Collectors.toMap(Menu::getCode, menu -> true));
        return buttonMaps;
        return menuService.getMenuListByCode(ids,menuCode,roleIds);
    }
    /**
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/MenuServiceImpl.java
@@ -21,18 +21,17 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.code.feign.ICodeClassifyClient;
import com.vci.ubcs.starter.util.MybatisParameterUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.system.cache.NacosConfigCache;
import com.vci.ubcs.system.cache.SysCache;
import com.vci.ubcs.system.dto.MenuDTO;
import com.vci.ubcs.system.entity.*;
import com.vci.ubcs.system.mapper.ClassifyAuthMapper;
import com.vci.ubcs.system.service.*;
import com.vci.ubcs.system.vo.MenuVO;
import com.vci.ubcs.system.mapper.MenuMapper;
import com.vci.ubcs.system.service.IMenuService;
import com.vci.ubcs.system.service.IRoleMenuService;
import com.vci.ubcs.system.service.IRoleScopeService;
import com.vci.ubcs.system.service.ITopMenuSettingService;
import com.vci.ubcs.system.wrapper.MenuWrapper;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
@@ -70,6 +69,8 @@
    private final IRoleScopeService roleScopeService;
    private final MenuMapper menuMapper;
    private final ITopMenuSettingService topMenuSettingService;
    private final ICodeClassifyClient codeClassifyClient;
    private final ClassifyAuthMapper classifyAuthMapper;
    private final static String PARENT_ID = "parentId";
    private final static Integer MENU_CATEGORY = 1;
@@ -324,18 +325,63 @@
    }
    /**
     * èŽ·å–èœå•ä¸‹é¢çš„æŒ‰é’®
     * èŽ·å–èœå•ä¸‹é¢çš„æŒ‰é’®ï¼Œåˆ«ä¹±è°ƒç”¨ï¼Œè¿™ä¸ªæ–¹æ³•æ˜¯é’ˆå¯¹ä¸»æ•°æ®ç®¡ç†æŒ‰é’®æŸ¥è¯¢çš„
     * @param classifyId
     * @param btmType ä¸šåŠ¡ç±»åž‹
     * @return List<Menu>
     * @param authType
     * @return
     */
    @Override
    //@Cacheable(cacheNames = MENU_CACHE, key = "'auth:menuButton:'+ #btmType +':'+ #userId ")
    public List<Menu> getMenuButtonByType(String btmType,Long userId) {
        List<String> roleIds = null;
        if(!VciBaseUtil.checkAdminTenant()){
            roleIds = Arrays.asList(AuthUtil.getUser().getRoleId().split(","));
    public List<Menu> getMenuButtonByType(String classifyId,String btmType,String authType) {
        // baseMapper.selectMenuChildByBtnType(btmType,roleIds);
        if(Func.isBlank(classifyId)){
            throw new ServiceException("必传参数分类oid不能为空!");
        }
        return baseMapper.selectMenuChildByBtnType(btmType,roleIds);
        //查询分类节点的所有父级节点
        R<List<String>> listR = codeClassifyClient.selectAllParentOid(classifyId);
        if (!listR.isSuccess() && !listR.getData().isEmpty()) {
            throw new ServiceException("获取分类信息失败!");
        }
        // è¿”回的分类oid是当前节点为第一个,后面依次是他的上层节点
        List<String> classifyOidList = listR.getData();
        final String roleIds = AuthUtil.getUser().getRoleId();
        // å…ˆæŸ¥è¯¢æŒ‰é’®id列表
        LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
            .lambda().eq(ClassifyAuth::getClassifyId, classifyId)
            .eq(ClassifyAuth::getAuthType,authType)
            .in(ClassifyAuth::getRoleId, roleIds);
        List<ClassifyAuth> classifyAuths = classifyAuthMapper.selectList(wrapper);
        //如果当前分类没有找到授权配置,就依次从当前节点往上层节点找授权配置,找到了就停止,没找到就一直找到最后
        if(classifyAuths.isEmpty()){
            // ä¸‹æ ‡ä»Ž1开始因为当前节点0已经查询过
            for (int i = 1; i < classifyOidList.size(); i++) {
                classifyAuths = classifyAuthMapper.selectList(
                    Wrappers.<ClassifyAuth>query()
                        .lambda().eq(ClassifyAuth::getClassifyId, classifyOidList.get(i))
                        .in(ClassifyAuth::getRoleId, roleIds)
                );
                if(!classifyAuths.isEmpty()){
                    break;
                }
            }
        }
        //出现了错误数据,同一个角色和同一个分类id存在多条授权记录
        if(classifyAuths.size()>1){
            throw new ServiceException("角色和分类配置存在多条记录,请联系管理人员清理错误配置!");
        }
        // æ˜¯å¦ä¸ºè¶…管
        Boolean isAdmin = VciBaseUtil.checkAdminTenant();
        // æœªé…ç½®æŒ‰é’®æƒé™
        if(!isAdmin && (classifyAuths.isEmpty() || Func.isBlank(classifyAuths.get(0).getButtonIds()))){
            return new ArrayList<>();
        }
        List<String> ids = new ArrayList<>();
        // å¦‚果不是超管用户
        if(!isAdmin){
            ids.addAll(Arrays.asList(classifyAuths.get(0).getButtonIds().split(",")));
        }
        return this.getMenuListByCode(ids,btmType,roleIds);
    }
    /**
@@ -381,8 +427,7 @@
     */
    @Override
    public List<Menu> getButtonByParentCode(String code) {
        List<Menu> buttonList = menuMapper.getButtonByParentCode(code);
        return buttonList;
        return menuMapper.getButtonsByRoleIdAndCode(null,code);
    }
    /**
@@ -444,20 +489,31 @@
    /**
     * æ ¹æ®ä¸»é”®èŽ·å–èœå•ä¿¡æ¯
     * @param ids
     * @param menuCode
     * @param roleIds
     * @return
     */
    @Override
    public List<Menu> getMenuListById(List<String> ids,String parentId) {
        LambdaQueryWrapper<Menu> wrapper = Wrappers.<Menu>query()
            .lambda().eq(Menu::getCategory, "2")
            .eq(Menu::getIsDeleted,BladeConstant.DB_NOT_DELETED);
    public List<Menu> getMenuListByCode(List<String> ids,String menuCode,String roleIds){
        List<Menu> menuButtonList = null;
        if(VciBaseUtil.checkAdminTenant()){
            wrapper.eq(Menu::getParentId,parentId);
            // æ­£å¸¸æƒ…况下来说这个不存在为空的情况
            // æŸ¥è¯¢è¯¥èœå•下的所有按钮
            menuButtonList = menuMapper.getButtonByIdsOrByParentCode(null, menuCode, null);
        }else {
            wrapper.in(Menu::getId, ids);
            menuButtonList = menuMapper.getButtonByIdsOrByParentCode(roleIds,null,ids);
        }
        List<Menu> menuList = this.list(wrapper);
        return menuList;
        return menuButtonList;
    }
    /**
     * æ ¹æ®è§’色id获取已授权的按钮信息
     * @param roleId
     * @return
     */
    @Override
    public List<Menu> getButtonsByRoleId(String roleId, String menuCode) {
        return menuMapper.getButtonsByRoleIdAndCode(roleId,menuCode);
    }
}
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/RoleServiceImpl.java
@@ -21,6 +21,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.mapper.RoleMapper;
import com.vci.ubcs.system.service.IMenuService;
import com.vci.ubcs.system.service.IRoleMenuService;
Source/UBCS/ubcs-service/ubcs-system/src/main/resources/mapper/MenuMapper.xml
@@ -219,30 +219,22 @@
        ) menu ORDER BY sort
    </select>
    <select id="getButtonByParentCode" resultMap="menuResultMap">
        SELECT
            id,
            parent_id,
            code,
            name,
            alias,
            PATH,
            SOURCE,
            ACTION,
            sort
        FROM
            PL_SYS_MENU
        WHERE
            "CATEGORY" = '2'
          AND IS_DELETED = 0
          AND PARENT_ID IN (
            SELECT
            ID
            FROM
            PL_SYS_MENU
            WHERE
            CODE = #{code})
        ORDER BY SORT
    <select id="getButtonsByRoleIdAndCode" resultMap="menuResultMap">
        SELECT pm.*
        FROM PL_SYS_MENU ps,
             PL_SYS_MENU pm,
             PL_ORG_ROLE_MENU prom
        WHERE ps.ID = prom.MENU_ID
          <if test="roleId != null and roleId != ''">
              AND prom.ROLE_ID = #{roleId}
          </if>
            AND ps."CATEGORY" = 1
            AND pm.IS_DELETED = 0
          <if test="code != null and code != ''">
            AND ps.ID = pm.PARENT_ID
            AND ps.CODE = #{code}
          </if>
        ORDER BY pm.SORT ASC
    </select>
    <select id="grantTree" resultMap="treeNodeResultMap">
@@ -524,4 +516,29 @@
        order by pm.sort asc
    </select>
    <select id="getButtonByIdsOrByParentCode" resultMap="menuResultMap">
        SELECT pm.*
        FROM PL_SYS_MENU ps,
        PL_SYS_MENU pm,
        PL_ORG_ROLE_MENU prom
        WHERE ps.ID = prom.MENU_ID
        <if test="roleIds != null and roleIds != ''">
            AND prom.ROLE_ID in (#{roleIds})
        </if>
          AND ps."CATEGORY" = 1
          AND pm.IS_DELETED = 0
        <if test="code != null and code != ''">
            AND ps.ID = pm.PARENT_ID
            AND ps.CODE = #{code}
        </if>
        <if test="ids != null and ids != ''">
            AND ps.ID IN (
                <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
                    #{item}
                </foreach>
            )
        </if>
        ORDER BY pm.SORT ASC
    </select>
</mapper>