xiejun
2024-01-23 f09e05514d9a9e2623cfa73c4de1ffa98bb30bf8
Source/UBCS-WEB/src/components/Theme/DataAuthDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,429 @@
<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(row.roleData,row)"
          >
            <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]"
            :disabled="row.authButton.allDisabled ? true : row.authButton[item.code]">
          </el-checkbox>
        </template>
      </el-table-column>
    </el-table>
    <div slot="footer" class="dialog-footer">
      <el-button plain type="info" @click="selectAllButton">按钮全选</el-button>
      <el-button class="el-icon-plus" plain type="success" @click="addClassifyAuth"></el-button>
      <el-button class="el-icon-minus" plain type="warning" @click="subClassifyAuth"></el-button>
      <el-button plain type="primary" @click="submit">提 äº¤</el-button>
      <el-button plain type="danger" @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, getButtonsByRoleId} 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,
    },
    TreeNode:{
      type:Object
    }
  },
  data() {
    return {
      // å¯¹è¯æ¡†æ˜¾ç¤ºæŽ§åˆ¶
      isShowDialog: this.visible,
      isLoading: false,
      tableHeight: 'calc(100vh - 550px)',
      classifyAuthData: [],
      //列头
      classifyAuthHeader: [],
      //按钮数据
      classifyAuthButton: [],
      //角色列表
      roleList: [],
      //当前选中的表格行
      selectList: [],
      itemKey: '',
      addIndex: Number,
      currentRow: {}
    };
  },
  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,
                code: item.code,
                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, index) => {
                let item = {
                  oid: authData.oid,
                  roleData: authData.roleId,
                  classifyItem: this.classifyData.label,
                  index: index,
                  authButton:{},
                  uuid: uuidv4(),//生成唯一的id
                }
                //将按钮设置进去
                authData.buttonIdList.forEach(data => {
                  Vue.set(item, data, true);
                });
                this.classifyAuthData.push(item);
                this.addIndex = this.classifyAuthData.length - 1; //添加行下标等于classifyAuthData的长度-1
                this.roleHandlerMethods(authData.roleId, 'create', index)
              })
            }
          });
        });
      }
    },
  },
  computed: {},
  mounted() {
  },
  created() {
  },
  methods: {
    // å…³é—­å¯¹è¯æ¡†
    closeDialog() {
      this.$emit('update:visible', false);
      this.classifyAuthData = [];
    },
    roleHandlerMethods(id, type, index) {
      if (this.classifyAuthData.length === 0) {
        return;
      }
      //filteredItems æœªæŽˆæƒæ•°ç»„
      getButtonsByRoleId({roleId: id, code: this.TreeNode.id}).then(res => {
        const filteredItems = this.classifyAuthButton.filter(item =>
          !res.data.data.some(x => x.id === item.id)
        );
        //和表格列进行对比
        this.classifyAuthHeader.forEach((item) => {
          const isMatched = filteredItems.some((x) => x.id === item.prop);
          this.$nextTick(() => {
            if (this.classifyAuthData[index]) {
              if (isMatched) {
                Object.keys(this.classifyAuthData[index]).forEach((key) => {
                  this.$set(this.classifyAuthData[index].authButton,item.code,true);
                });
              } else {
                Object.keys(this.classifyAuthData[index]).forEach((key) => {
                  this.$set(this.classifyAuthData[index].authButton,item.code,false);
                });
              }
            }
          });
        });
        //添加‘查看’禁用
        if (this.classifyAuthData.authButton) {
          this.classifyAuthData.forEach((classkey, classIndex) => {
            if (classkey.authButton.classify_view) {
              this.$set(this.classifyAuthData[classIndex].authButton,"allDisabled",true);
            } else {
              this.classifyAuthData[classIndex].authButton.allDisabled = false;
            }
          });
        }
        //强制刷新表格
        this.itemKey = uuidv4();
      });
    },
    // è§’色改变时
    async roleChange(row, currentRow) {
      try {
        this.currentRow = currentRow;
        const res = await getButtonsByRoleId({roleId: row, code: this.TreeNode.id});
        const filteredItems = this.classifyAuthButton.filter(item => {
          return !res.data.data.find(x => x.id === item.id);
        });
        this.classifyAuthHeader.forEach(item => {
          const isMatched = filteredItems.some(x => x.id === item.prop);
          this.$nextTick(() => {
            if (currentRow) {
              if (isMatched) {
                Object.keys(currentRow).forEach((key) => {
                  currentRow.authButton[item.code] = true;
                  if (!currentRow.authButton.classify_view) {
                    currentRow.authButton.allDisabled = false;
                  }
                });
              } else {
                Object.keys(currentRow).forEach((key) => {
                  currentRow.authButton[item.code] = false;
                  if (!currentRow.authButton.classify_view) {
                    currentRow.authButton.allDisabled = false;
                  }
                });
              }
            }
            this.itemKey = uuidv4(); // å¼ºåˆ¶åˆ·æ–°è¡¨æ ¼
          });
        });
      } catch (error) {
        console.error(error);
      }
    },
    // å¢žåŠ è¡Œ
    addClassifyAuth() {
      if (this.roleList.length <= 0) {
        this.$message.warning("当前租户不存在角色信息!");
        return;
      }
      this.addIndex++; //自定义生成添加行下标
      let item = {
        roleData: this.roleList[0].id,
        classifyItem: this.classifyData.label,
        authButton:{},
        uuid: uuidv4(),//生成唯一的id,
        index: this.addIndex,
      }
      //将按钮设置进去
      this.classifyAuthButton.forEach(data => {
        Vue.set(item, data.id, false);
      })
      //console.log(item)
      this.classifyAuthData.push(item)
      this.roleHandlerMethods(this.roleList[0].id, 'add', this.addIndex)
    },
    // åˆ é™¤è¡Œ
    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>