|
|
@@ -0,0 +1,397 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <!-- 选择清表表单 -->
|
|
|
+ <el-dialog title="选择表单" class="excel-dialog" :visible.sync="tableDialogVisible" modal-append-to-body append-to-body
|
|
|
+ :close-on-click-modal="false" width="75vw" top="10vh" @closed="cancel">
|
|
|
+ <div class="excel-container">
|
|
|
+ <div class="tree-box">
|
|
|
+ <el-select style="width: 100%" v-model="selectedExcelTemplate.id" placeholder="请选择清表模板"
|
|
|
+ @change="changeTemplate($event)">
|
|
|
+ <el-option v-for="(item, key) in excelTemplateOption" :key="key" :label="item.name" :value="item.id">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ <div class="flex" v-if="isShowSearch">
|
|
|
+ <el-input size="small" placeholder="输入关键字搜索" clearable @clear="clearInput" v-model="filterText">
|
|
|
+ </el-input>
|
|
|
+ <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="scrollbar">
|
|
|
+ <el-tree v-if="isShowLazyTree" @node-click="handleNodeClickExcel" ref="tree" class="excel-table-tree"
|
|
|
+ :props="treeProps" :data="lazyTreeData" :load="loadNode" lazy node-key="id" accordion
|
|
|
+ :default-expanded-keys="expandedKeys">
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span :class="{
|
|
|
+ 'checked-bg': tableMap.has(data.id),
|
|
|
+ 'not-create': tableMap.has(data.id) && tableMap.get(data.id).isCreate > 0
|
|
|
+ }">
|
|
|
+ {{ node.label }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+ <el-tree v-show="isShowAllTree" ref="treeAll" class="excel-table-tree" v-loading="treeLoading"
|
|
|
+ :props="treeProps" :data="allTreeData" @node-click="handleNodeClickExcel" node-key="id"
|
|
|
+ :expand-on-click-node="false" :filter-node-method="filterNode">
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span :class="{
|
|
|
+ 'checked-bg': tableMap.has(data.id),
|
|
|
+ 'not-create': tableMap.has(data.id) && tableMap.get(data.id).isCreate > 0
|
|
|
+ }">
|
|
|
+ {{ node.label }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="table-box">
|
|
|
+ <el-table :data="tableList" height="100%" border style="width: 100%;">
|
|
|
+ <el-table-column prop="excelTabName" label="清表名称" align="center">
|
|
|
+ <template #header>
|
|
|
+ <div style="display: flex;align-items: center;justify-content: center;">
|
|
|
+ <span style="padding-right: 4px;">清表名称</span>
|
|
|
+ <el-button type="text" icon="el-icon-sort" class="text-icon"
|
|
|
+ @click="$refs.tableSortRef.show(tableList)"></el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="elementTableName" label="元素表名称" align="center" />
|
|
|
+ <el-table-column prop="tableType" label="表单类型" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.tableType" placeholder="请选择">
|
|
|
+ <el-option v-for="item in tableTypeOption" :key="item.dictKey" :label="item.dictValue"
|
|
|
+ :value="item.dictKey">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="tableOwner" label="所属方" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.tableOwner" placeholder="请选择">
|
|
|
+ <el-option v-for="item in ownerTypeOption" :key="item.dictKey" :label="item.dictValue"
|
|
|
+ :value="item.dictKey">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="isCreate" label="是否允许创建" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tooltip :disabled="!scope.row.isCreate" :content="isCreateTypeOption[scope.row.isCreate]"
|
|
|
+ placement="top">
|
|
|
+ <div :class="['tag', scope.row.isCreate ? 'no' : 'yes']">
|
|
|
+ {{ scope.row.isCreate ? '否' : '是' }}
|
|
|
+ <i v-if="scope.row.isCreate" class="el-icon-warning"></i>
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="center" width="200">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-link type="danger" size="mini" style="margin: 0px" @click="delTable(scope.$index)">删除</el-link>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <span slot="footer" class="dialog-footer" style="display: flex; justify-content: center; align-items: center">
|
|
|
+ <el-button @click="cancel()">取 消</el-button>
|
|
|
+ <el-button style="margin-left: 30px" type="primary" @click="save()" :loading="saveBtnLoading">确 定</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+ <TableSort ref="tableSortRef" @confirm="sortConfirm"></TableSort>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { tabLazytree, tabLazytreeAll } from "@/api/exctab/excelmodel";
|
|
|
+import { getList, getWbsTreeExcelTab, saveBatchWbsTree } from "@/api/exctab/exceltab";
|
|
|
+import { getDictionary } from "@/api/system/dict";
|
|
|
+import TableSort from "@/components/table-sort/index.vue";
|
|
|
+export default {
|
|
|
+ name: 'ChooseExcelTable',
|
|
|
+ props: {
|
|
|
+ nodeId: String,
|
|
|
+ wbsId: String
|
|
|
+ },
|
|
|
+ components: { TableSort },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ tableDialogVisible: false,
|
|
|
+ excelTemplateOption: [], // 清表模版下拉列表数据
|
|
|
+ treeProps: {
|
|
|
+ label: "name",
|
|
|
+ children: "children",
|
|
|
+ isLeaf: "isLeaf",
|
|
|
+ },
|
|
|
+ selectedExcelTemplate: {}, //选中的清表模版
|
|
|
+ isShowSearch: false, // 是否显示搜索框
|
|
|
+ filterText: "",
|
|
|
+ isShowAllTree: false,
|
|
|
+ isShowLazyTree: false,
|
|
|
+ lazyTreeData: [],
|
|
|
+ allTreeData: [],
|
|
|
+ treeLoading: false,
|
|
|
+ expandedKeys: [],
|
|
|
+ tableList: [], // 清表表格数据
|
|
|
+ ownerTypeOption: [], // 所有者类型下拉列表数据
|
|
|
+ tableTypeOption: [], // 表单类型下拉列表数据
|
|
|
+ isCreateTypeOption: {
|
|
|
+ 0: "可以创建",
|
|
|
+ 1: "已存在元素表",
|
|
|
+ 2: "未创建元素表",
|
|
|
+ 3: "未上传清表"
|
|
|
+ }, // 是否允许创建Map
|
|
|
+ saveBtnLoading: false,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ tableMap() {
|
|
|
+ return new Map(this.tableList.map(t => [t.excelTabId, t]));
|
|
|
+ },
|
|
|
+ checkedSet() {
|
|
|
+ return new Set(this.tableList.map(t => t.excelTabId)) || new Set();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async show() {
|
|
|
+ // this.filterText = "";
|
|
|
+ // this.selectedExcelTemplate = {};
|
|
|
+ // this.isShowSearch = false;
|
|
|
+ // this.isShowAllTree = false;
|
|
|
+ // this.isShowLazyTree = false;
|
|
|
+ // this.lazyTreeData = [];
|
|
|
+ // this.allTreeData = [];
|
|
|
+ await this.getExcelTemplateOption();
|
|
|
+ this.tableDialogVisible = true;
|
|
|
+ this.ownerTypeOption = await this.getDictionaryData("owner_type");
|
|
|
+ this.tableTypeOption = await this.getDictionaryData("table_type");
|
|
|
+ },
|
|
|
+ async getExcelTemplateOption() {
|
|
|
+ const { data } = await getList(1, 1000, { parentId: 0 })
|
|
|
+ if (data.code === 200) {
|
|
|
+ this.excelTemplateOption = data.data.records
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getDictionaryData(key) {
|
|
|
+
|
|
|
+ const res = await getDictionary({ code: key })
|
|
|
+ return res.data.data.map((element) => ({ ...element, dictKey: Number(element.dictKey) }))
|
|
|
+ },
|
|
|
+ changeTemplate(templateId) {
|
|
|
+ // console.log(item, "item");
|
|
|
+ const item = this.excelTemplateOption.find((item) => item.id === templateId);
|
|
|
+ this.expandedKeys = [templateId]
|
|
|
+
|
|
|
+ this.selectedExcelTemplate = { ...item };
|
|
|
+ this.isShowLazyTree = false;
|
|
|
+ this.isShowAllTree = false;
|
|
|
+ this.filterText = "";
|
|
|
+ if (this.selectedExcelTemplate.name != "") {
|
|
|
+ this.lazyTreeData = [];
|
|
|
+ this.addTableData = [];
|
|
|
+ this.isShowSearch = false;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.isShowLazyTree = true;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async loadNode(node, resolve) {
|
|
|
+ //懒加载
|
|
|
+ console.log("loadNode", node);
|
|
|
+ if (node.level === 0) {
|
|
|
+ return resolve(await this.getLazyTree(0));
|
|
|
+ } else {
|
|
|
+ return resolve(await this.getLazyTree(node.data.id));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getLazyTree(parentId) {
|
|
|
+ //清表树信息
|
|
|
+ const { data: res } = await tabLazytree({
|
|
|
+ parentId: parentId,
|
|
|
+ modeId: this.selectedExcelTemplate.id
|
|
|
+ });
|
|
|
+ console.log(res);
|
|
|
+ if (res.code === 200 && res.msg === "操作成功") {
|
|
|
+ if (res.data.length > 0) {
|
|
|
+ this.isShowSearch = true;
|
|
|
+ res.data.forEach((val) => {
|
|
|
+ val.isLeaf = !val.hasChildren;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return res.data;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ treeFilter() {
|
|
|
+ if (this.filterText) {
|
|
|
+ this.isShowAllTree = true;
|
|
|
+ this.isShowLazyTree = false;
|
|
|
+ if (!this.allTreeData.length) {
|
|
|
+ this.treeLoading = true;
|
|
|
+ tabLazytreeAll({
|
|
|
+ modeId: this.selectedExcelTemplate.id,
|
|
|
+ name: "",
|
|
|
+ }).then((res) => {
|
|
|
+ this.treeLoading = false;
|
|
|
+ this.allTreeData = res.data.data;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.treeAll.filter(this.filterText);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$refs.treeAll.filter(this.filterText);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.isShowAllTree = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ filterNode(value, data) {
|
|
|
+ if (!value) return true;
|
|
|
+ return data.name.indexOf(value) !== -1;
|
|
|
+ },
|
|
|
+ clearInput() {
|
|
|
+ this.isShowAllTree = false;
|
|
|
+ this.isShowLazyTree = true;
|
|
|
+ },
|
|
|
+ handleNodeClickExcel(data, node) {
|
|
|
+ console.log(data, node);
|
|
|
+ if (data.hasChildren) return
|
|
|
+ if (this.tableList.some(item => item.excelTabId === data.id)) return
|
|
|
+ getWbsTreeExcelTab({ nodeId: this.nodeId, id: data.id }).then((res) => {
|
|
|
+ console.log(res);
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ this.tableList.push({ ...res.data.data, name: res.data.data.elementTableName });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ delTable(index) {
|
|
|
+ this.tableList.splice(index, 1)
|
|
|
+ },
|
|
|
+
|
|
|
+ sortConfirm(list) {
|
|
|
+ this.tableList = list
|
|
|
+ },
|
|
|
+
|
|
|
+ cancel() {
|
|
|
+ this.tableDialogVisible = false;
|
|
|
+ this.tableList = []
|
|
|
+ this.filterText = "";
|
|
|
+ this.selectedExcelTemplate = {};
|
|
|
+ this.isShowSearch = false;
|
|
|
+ this.isShowAllTree = false;
|
|
|
+ this.isShowLazyTree = false;
|
|
|
+ this.lazyTreeData = [];
|
|
|
+ this.allTreeData = [];
|
|
|
+ },
|
|
|
+ async save() {
|
|
|
+ if (this.tableList.length === 0) {
|
|
|
+ this.$message.warning("请选择表格后再提交")
|
|
|
+ return
|
|
|
+ } else if (this.tableList.some(el => el.isCreate)) {
|
|
|
+ this.$message.warning("存在不可创建表单,请检查后重试")
|
|
|
+ return
|
|
|
+ } else if (this.tableList.some(el => !el.tableOwner)) {
|
|
|
+ this.$message.warning("表单所属方数据不能为空,请选择后再提交")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.saveBtnLoading = true;
|
|
|
+ const { data } = await saveBatchWbsTree({
|
|
|
+ wbsId: this.wbsId,
|
|
|
+ nodeId: this.nodeId,
|
|
|
+ list: this.tableList
|
|
|
+ })
|
|
|
+ this.saveBtnLoading = false;
|
|
|
+ if (data.code === 200) {
|
|
|
+ this.$message.success("保存成功")
|
|
|
+ this.cancel()
|
|
|
+ this.$emit('confirm')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+::v-deep .excel-container {
|
|
|
+ height: 60vh !important;
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: grid;
|
|
|
+ gap: 20px;
|
|
|
+ grid-template-columns: calc(30% - 10px) calc(70% - 10px);
|
|
|
+
|
|
|
+ .tree-box {
|
|
|
+ min-height: 0;
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .scrollbar {
|
|
|
+ // flex: 1;
|
|
|
+ overflow: scroll;
|
|
|
+ // height: auto !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tree-node>.el-tree-node__children{
|
|
|
+ overflow: visible !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-box {
|
|
|
+ box-sizing: border-box;
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 全局样式文件 */
|
|
|
+::v-deep .excel-table-tree .el-tree-node {
|
|
|
+ .checked-bg {
|
|
|
+ background-color: #DCFCE7;
|
|
|
+ padding: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .not-create {
|
|
|
+ background-color: #FEE2E3;
|
|
|
+ padding: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ // /* 隐藏所有复选框 */
|
|
|
+ // .el-checkbox {
|
|
|
+ // display: none;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // /* 只有叶子节点才显示 */
|
|
|
+ // .is-leaf+.el-checkbox {
|
|
|
+ // display: inline-block;
|
|
|
+ // }
|
|
|
+}
|
|
|
+
|
|
|
+.tag {
|
|
|
+ display: block;
|
|
|
+ padding: 6px;
|
|
|
+ border-radius: 18px;
|
|
|
+ width: 60px;
|
|
|
+ margin: 0 auto;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &.yes {
|
|
|
+ background-color: #DCFCE7;
|
|
|
+ color: #16A34A
|
|
|
+ }
|
|
|
+
|
|
|
+ &.no {
|
|
|
+ background-color: #FEE2E3;
|
|
|
+ color: #E14247
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-icon-warning {
|
|
|
+ position: absolute;
|
|
|
+ top: 4px;
|
|
|
+ right: 10px;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|