wangting
2024-10-25 2b3a7e06b9fb836b5004273f9a411cf78b4af844
Source/plt-web/plt-web-ui/src/views/system/department/index.vue
@@ -1,15 +1,369 @@
<template>
  <basic-container>
    <avue-crud
      ref="departCrud"
      :data="tableData"
      :option="option"
      :page.sync="page"
      :table-loading="tableLoading"
      @on-load="getTableList"
      @refresh-change="handleRefresh"
      @selection-change="selectChange"
      @row-save="rowSaveHandler"
      @row-update="rowUpdateHandler"
      @row-del="rowDeleteHandler"
      @current-row-change="handleCurrentRowChange"
    >
      <template slot="menu" slot-scope="{row,size,type}">
        <el-button icon="el-icon-circle-plus-outline" size="small" type="text" @click="handleAdd()">新增子级</el-button>
        <el-button v-if="row.ALLDept !== 'ALLDept'" icon="el-icon-edit" size="small" type="text"
                   @click="editBtnClick(row)">编辑
        </el-button>
        <el-button v-if="row.ALLDept !== 'ALLDept'" icon="el-icon-delete" size="small" type="text"
                   @click="rowDeleteHandler(row)">删除
        </el-button>
      </template>
      <template slot="menuLeft" slot-scope="scope">
        <el-button icon="el-icon-school" plain size="small" type="primary" @click="assignMembersHandler">分配成员
        </el-button>
        <el-button icon="el-icon-user" plain size="small" type="primary" @click="statisticsHandler">统计</el-button>
        <el-button icon="el-icon-upload2" plain size="small" type="primary" @click="upLoadHandler">导入部门</el-button>
        <el-button icon="el-icon-download" plain size="small" type="primary" @click="downLoadHandler">下载导入模板</el-button>
      </template>
    </avue-crud>
    <!-- 统计对话框   -->
    <el-dialog
      v-dialogDrag
      v-loading="statisticsLoading"
      :visible.sync="statisticsVisible"
      append-to-body="true"
      class="avue-dialog"
      title="人员信息"
      width="50%"
    >
      <avue-crud
        :data="countData"
        :option="countOption"
      >
      </avue-crud>
      <div slot="footer" class="dialog-footer" style="display: flex;gap: 20px;justify-content: center">
        <div>
          <el-tag>当前角色总人数: {{ this.countData.length }}</el-tag>
        </div>
        <el-button icon="el-icon-close" size="small" type="danger" @click="statisticsVisible = false">关 闭</el-button>
      </div>
    </el-dialog>
    <!-- 分配成员穿梭框   -->
    <transfer ref="transfer" :left-role-data="leftTransferData" :right-role-data="rightTransferData"
              :transferTitle="transferTitle" title="部门添加成员"
              @transferSend="departTransferSend">
    </transfer>
    <!-- 导入部门   -->
    <upload-file ref="upload" :fileType="upFileType" :fileUrl="fileUrl" :tipList="tipList" title="导入部门"
                 @updata="getTableList"></upload-file>
  </basic-container>
</template>
<script>
import {
  refTree,
  addDept,
  updateDept,
  deleteDept,
  countSmUserByDeptOid,
  listUserUnInDeptOid,
  listUserByDeptOid,
  saveUsersDepts,
  download
} from "@/api/system/departMent/api";
import basicOption from '@/util/basic-option';
import {column} from './option'
import func from "@/util/func";
export default {
  name: "departmentManage",
  data() {
    return {
      tableData: [],
      option: {
        ...basicOption,
        rowKey: 'oid',
        rowParentKey: 'parentId',
        selection: false,
        addBtn: false,
        editBtn: false,
        delBtn: false,
        gridBtn: false,
        menuWidth:280,
        highlightCurrentRow: true,
        calcHeight: -60,
        column: column
      },
      tableLoading: false,
      departCurrenRow: {},
      parentId: '',
      statisticsLoading: false,
      statisticsVisible: false,
      countData: [],
      countOption: {
        ...basicOption,
        selection: false,
        refreshBtn: false,
        addBtn: false,
        header :false,
        menu: false,
        calcHeight:80,
        column: [
          {
            label: '部门',
            prop: 'pkDepartmentName',
            sortable: true,
          },
          {
            label: '用户名',
            prop: 'id',
            sortable: true,
          },
          {
            label: '真实姓名',
            prop: 'name',
            sortable: true,
          },
          {
            label: '角色',
            prop: 'pkPersonName',
            sortable: true,
            overHidden: true,
          },
        ]
      },
      leftTransferData: [],
      rightTransferData: [],
      transferTitle: ['待选人员', '已选人员'],
      tipList: ['导入模板中标明红色字体的为必输项', '导入结构为树结构时请保证ID列不能重复', '父ID请使用界面上部门的唯一标识ID或者Excel中手动输入的ID', '父ID列为空时,导入的部门即为顶层部门'],
      upFileType: ['xls', 'xlsx'],
      fileUrl: 'api/departmentQueryController/importDept',
    }
  },
  methods: {
    // 表格初始化请求
    getTableList() {
      refTree({queryAllLevel: true, 'extandParamsMap[showAllDepartmentNode]': true}).then(res => {
        this.tableData = this.departDtaFormAtter(res.data.treeData);
      })
    },
    // 分配部门数据转换
    departDtaFormAtter(items) {
      return items.map(item => {
        // 转换当前节点的属性
        const formList = {
          oid: item.oid,
          id: item.attributes.id,
          name: item.attributes.name,
          description: item.attributes.description,
          code: item.attributes.code,
          specialties: item.attributes.specialties,
          uniqueId: item.attributes.uniqueId,
          ALLDept: item.attributes.ALLDept ? item.attributes.ALLDept : "",
          parentId: item.parentId,
          parentName: item.parentName,
          parentBtmName: item.parentBtmName,
          // 如果children存在且不为空,则递归转换children
          children: item.children && item.children.length > 0 ? this.departDtaFormAtter(item.children) : undefined
        };
        return formList;
      });
    },
    // 列头刷新
    handleRefresh() {
      this.getTableList();
    },
    // 下拉
    selectChange() {
    },
    // 表格行新增子级
    handleAdd() {
      this.$refs.departCrud.rowAdd();
    },
    // 添加
    rowSaveHandler(row, done, loading) {
      row = {...row, ...{pkFatherDepartment: this.parentId}};
      addDept(row).then(res => {
        if (res.data.code === 200) {
          this.$message.success(res.data.obj);
          this.getTableList();
          done();
        }
      }).catch(err => {
        console.log(err);
        loading();
      })
    },
    // 编辑按钮点击事件
    editBtnClick(row) {
      this.$refs.departCrud.rowEdit(row);
    },
    // 编辑
    rowUpdateHandler(row, index, done, loading) {
      let params = {
        name: row.name,
        id: row.id,
        code: row.code,
        specialties: row.specialties,
        description: row.description,
        oid: row.oid
      }
      updateDept(params).then(res => {
        if (res.data.code === 200) {
          this.$message.success(res.data.obj);
          this.getTableList();
          done();
        }
      }).catch(err => {
        console.log(err);
        loading();
      })
    },
    // 删除
    rowDeleteHandler(row) {
      let params = {
        ids: row.oid
      }
      this.$confirm('您确定要删除当前部门吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteDept(params).then(res => {
          if (res.data.code === 200) {
            this.$message.success(res.data.obj);
            this.getTableList();
          }
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // 表格行 行单选
    handleCurrentRowChange(row) {
      // 单独添加 ALLDept 属性判断是否是顶层节点所有部门
      if (row.ALLDept === "ALLDept") {
        this.parentId = "";
      } else {
        this.parentId = row.oid;
      }
      this.departCurrenRow = row;
    },
    // 统计
    statisticsHandler() {
      console.log(this.departCurrenRow);
      if (func.isEmptyObject(this.departCurrenRow)) {
        this.$message.warning('请选择部门!');
        return
      }
      countSmUserByDeptOid({pkDepartment: this.departCurrenRow.ALLDept === 'ALLDept' ? null : this.departCurrenRow.oid}).then(res => {
        if (res.data.code === 200) {
          const data = res.data.data;
          this.countData = data.map(item => {
            return {
              pkDepartmentName: item.pkDepartmentName,
              name: item.name,
              id: item.id,
              pkPersonName: item.pkPersonName
            }
          });
          this.statisticsVisible = true;
        }
      }).catch(err => {
        console.log(err)
      })
    },
    // 分配成员
    assignMembersHandler() {
      if (func.isEmptyObject(this.departCurrenRow)) {
        this.$message.error('请选择部门节点');
        return
      }
      if (this.departCurrenRow.ALLDept === "ALLDept") {
        this.$message.error('此节点为部门标识,不能执行分配成员操作,请选择其他节点!')
        return
      }
      Promise.all([
        listUserUnInDeptOid({pkDepartment: this.departCurrenRow.oid}),
        listUserByDeptOid({pkDepartment: this.departCurrenRow.oid})
      ]).then(([unInRoleRes, byRoleRes]) => {
        if (unInRoleRes.data.code === 200 && byRoleRes.data.code === 200) {
          const leftData = [...unInRoleRes.data.data, ...byRoleRes.data.data];
          // 组装好穿梭框可用数据
          this.leftTransferData = leftData.map(item => {
            return {
              name: item.name + `(${item.id})`,
              oid: item.oid
            }
          })
          this.rightTransferData = byRoleRes.data.data.map(item => item.oid);
          this.$refs.transfer.visible = true;
        }
      }).catch(err => {
        console.error(err);
      });
    },
    // 分配成员穿梭框回填
    departTransferSend(row) {
      let params = {
        userOids: row.join(','),
        deptId: this.departCurrenRow.oid
      }
      saveUsersDepts(params).then(res => {
        console.log(res);
        this.$message.success(res.data.obj);
        this.getTableList();
      }).catch(err => {
        console.log(err);
      })
    },
    // 下载导入模板
    downLoadHandler() {
      download().then(res => {
        func.downloadFileByBlobHandler(res);
        this.$message.success('下载成功')
      }).catch(err => {
        this.$message.error(err);
      })
    },
    // 导入部门
    upLoadHandler() {
      this.$refs.upload.visible = true;
    }
  }
}
</script>