Source/plt-web/plt-web-ui/src/views/modelingMenu/ui/formDefine/components/formDialog.vue
@@ -30,12 +30,15 @@
              <div style="display: flex;justify-content: center">
                <span style="display: flex;align-items: center; margin-right: 5px;">
                 <p class="tableTopLabel">名称:</p>
                 <el-input v-model="topForm.viName" placeholder="请输入内容" size="mini"></el-input>
                 <el-input v-model="topForm.viName" placeholder="请输入名称" size="mini"></el-input>
                </span>
                <span style="display: flex;align-items: center; margin-right: 5px;">
                 <p class="tableTopLabel">查询模板名称:</p>
                 <el-input v-model="form.itemQtName" placeholder="请输入查询模板名称" size="mini"></el-input>
                  <el-select v-model="topForm.itemQtName" placeholder="请选择查询模板" size="mini">
                    <el-option v-for="(item,index) in searchQtNameList" :key="index" :label="item.qtName"
                               :value="item.qtName"></el-option>
                  </el-select>
                </span>
                <span style="display: flex;align-items: center; margin-right: 5px;">
@@ -72,28 +75,25 @@
                        <el-button icon="el-icon-edit" plain size="mini" style="height: 28px;"
                                   type="primary"></el-button>
                      </div>
                      <el-input
                        v-if="item.itemType === 'textarea' || item.itemType === 'richtext' || item.itemType === 'webeditor'"
                        v-model="item.value"
                        :placeholder="item.text"
                        :rows="2"
                        type="textarea">
                        :placeholder="item.text">
                      </el-input>
                      <el-input-number v-if="item.itemType === 'number'" v-model="item.value" :max="99999"
                                       :min="1"></el-input-number>
                      <el-input-number v-if="item.itemType === 'number'" v-model="item.value" :max="99999" :min="1"
                                       size="mini"></el-input-number>
                      <el-input v-if="item.itemType === 'password'" v-model="input" placeholder="请输入密码"
                                show-password></el-input>
                      <el-radio v-if="item.itemType === 'radio'" v-model="item.value"></el-radio>
                      <el-checkbox v-if="item.itemType === 'checkbox'" v-model="item.value"></el-checkbox>
                      <el-select v-if="item.itemType === 'select' || item.itemType === 'multiselect'"
                                 v-model="item.value" :disabled="true" placeholder="请选择" size="mini">
                                 v-model="item.value" :disabled="false" placeholder="请选择" size="mini">
                      </el-select>
                      <el-date-picker
                        v-if="item.itemType === 'date' || item.itemType === 'datetime'"
                        v-model="item.value"
                        :placeholder="item.itemType === 'date' ? '请选择日期' : '请选择日期时间'"
                        class="formItemMargin"
                        type="date">
                      </el-date-picker>
@@ -105,6 +105,7 @@
                         step: '00:15',
                         end: '18:30'
                         }"
                        class="formItemMargin"
                        placeholder="选择时间">
                      </el-time-select>
                      <el-button v-if="item.itemType === 'file'"
@@ -129,7 +130,8 @@
              </el-button>
              <el-button icon="el-icon-plus" plain size="small" type="primary" @click="addCustomClickHandler">添加自定义组件
              </el-button>
              <el-button icon="el-icon-zoom-in" plain size="small" type="primary">预览</el-button>
              <el-button icon="el-icon-zoom-in" plain size="small" type="primary" @click="checkViewHandler">预览
              </el-button>
            </div>
          </basic-container>
        </el-main>
@@ -138,15 +140,20 @@
          <basic-container>
            <div style="height: 660px; overflow-y: auto;padding-right: 10px">
              <h3>设置</h3>
              <h4 style="color: red">属性设置信息后需单击右下角应用按钮进行应用</h4>
              <el-form ref="form" :model="form" :rules="rules" label-position="left" label-width="85px">
                <el-row style="border-bottom: 1px solid #878585;padding-bottom: 10px">
                  <el-col :span="24">
                    <el-form-item label="使用字段">
                      <div style="display: flex">
                      <div style="display: flex;align-items: center">
                        <el-input v-model="form.text" :readonly="true" placeholder="请输入使用字段" size="mini"></el-input>
                        <el-checkbox v-model="form.itemIsEditable" style="margin-left: 5px; margin-right: 5px">只读
                        <el-checkbox v-model="form.itemIsEditable" false-label="0"
                                     style="margin-left: 5px; margin-right: 5px"
                                     true-label="1">只读
                        </el-checkbox>
                        <el-checkbox v-model="form.itemIsRequired" style="margin-left: 5px;margin-right: 0px">必填
                        <el-checkbox v-model="form.itemIsRequired" false-label="0"
                                     style="margin-left: 5px;margin-right: 0px"
                                     true-label="1">必填
                        </el-checkbox>
                      </div>
                    </el-form-item>
@@ -240,7 +247,9 @@
                    <el-form-item label="权限控制">
                      <div style="display: flex;align-items: center">
                        <el-input v-model="form.itemRight" placeholder="请输入内容" size="mini"></el-input>
                        <el-button plain size="mini" style="margin-left: 3px" type="success">选择</el-button>
                        <el-button plain size="mini" style="margin-left: 3px" type="success" @click="authClickHandler">
                          选择
                        </el-button>
                      </div>
                    </el-form-item>
                  </el-col>
@@ -408,7 +417,7 @@
      append-to-body="true"
      class="avue-dialog"
      title="表单"
      width="40%"
      width="50%"
      @close="closeCustomDialog">
      <el-form ref="form" :model="customForm" :rules="rules" label-position="left" label-width="85px">
        <el-row style="border-bottom: 1px solid #878585;padding-bottom: 10px">
@@ -436,7 +445,7 @@
          <el-col :span="12">
            <el-form-item class="rightLabel" label="显示类型">
              <el-select v-model="customForm.itemType" placeholder="请选择类型" size="mini">
              <el-select v-model="customForm.itemType" placeholder="请选择类型" size="mini" @change="customItemTypeChange">
                <el-option v-for="(item,index) in showSelectList" :key="index" :label="item.label"
                           :value="item.value"></el-option>
              </el-select>
@@ -513,10 +522,12 @@
          </el-col>
          <el-col :span="24">
            <el-form-item label="权限控制">
            <el-form-item label="属性权限">
              <div style="display: flex;align-items: center">
                <el-input v-model="customForm.itemRight" placeholder="请输入内容" size="mini"></el-input>
                <el-button plain size="mini" style="margin-left: 3px" type="success">选择</el-button>
                <el-button plain size="mini" style="margin-left: 3px" type="success" @click="customAuthClickHandler">
                  选择
                </el-button>
              </div>
            </el-form-item>
          </el-col>
@@ -602,7 +613,8 @@
                  :show-header="false"
                  border
                  stripe
                  style="width: 100%">
                  style="width: 100%"
                  @row-click="customOptionTableClick">
                  <el-table-column
                    align="center"
                    label="名称"
@@ -625,7 +637,9 @@
                <el-button plain size="mini" style="margin-right: 5px" type="success"
                           @click="optionAddClickHandler('dialog')">添加
                </el-button>
                <el-button plain size="mini" style="margin-left: 5px" type="danger">删除</el-button>
                <el-button plain size="mini" style="margin-left: 5px" type="danger"
                           @click="optionDeleteClickHandler('dialog')">删除
                </el-button>
              </div>
            </el-form-item>
          </el-col>
@@ -668,12 +682,140 @@
         <el-button type="primary" @click="customSaveHandler">确 定</el-button>
    </span>
    </el-dialog>
    <!-- 添加自定义组件选择属性池属性对话框  -->
    <el-dialog
      v-dialogDrag
      :visible.sync="customAttrVisible"
      append-to-body="true"
      class="avue-dialog"
      title="选择属性"
      width="50%">
      <avue-crud
        ref="userCrud"
        :data="customAttrData"
        :option="customAttrOption"
        :page.sync="page"
        :table-loading="customAttrLoading"
        @row-click="customAttrRowClickHandler"
      >
      </avue-crud>
      <span slot="footer" class="dialog-footer">
         <el-button @click="customAttrVisible = false">取 消</el-button>
         <el-button type="primary" @click="customAttrSaveHandler">确 定</el-button>
    </span>
    </el-dialog>
    <!-- 预览  -->
    <el-dialog
      v-dialogDrag
      :visible.sync="checkViewVisible"
      append-to-body="true"
      class="avue-dialog"
      title="预览"
      width="60%">
      <div style="height: 600px">
        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
          <el-row>
            <el-col v-for="(item,index) in formList" :key="index" :span="topForm.columnNumber">
              <el-form-item :label="item.itemName + ':'" style="padding-left: 5px">
                <el-input
                  v-if="item.itemType === 'text' ||
                         item.itemType === 'custom' ||
                         item.itemType === 'customform'||
                         item.itemType === 'hidden' ||
                         item.itemType === 'specialCharacter'"
                  v-model="item.value" :placeholder="item.text"
                  size="mini"></el-input>
                <div v-if="item.itemType === 'textbtn'" style="display: flex;align-items: center">
                  <el-input v-model="item.value" :placeholder="item.text" size="mini"></el-input>
                  <el-button icon="el-icon-edit" plain size="mini" style="height: 28px;"
                             type="primary"></el-button>
                </div>
                <el-input
                  v-if="item.itemType === 'textarea' || item.itemType === 'richtext' || item.itemType === 'webeditor'"
                  v-model="item.value"
                  :placeholder="item.text">
                </el-input>
                <el-input-number v-if="item.itemType === 'number'" v-model="item.value" :max="99999" :min="1"
                                 size="mini"></el-input-number>
                <el-input v-if="item.itemType === 'password'" v-model="input" placeholder="请输入密码"
                          show-password></el-input>
                <el-radio v-if="item.itemType === 'radio'" v-model="item.value"></el-radio>
                <el-checkbox v-if="item.itemType === 'checkbox'" v-model="item.value"></el-checkbox>
                <el-select v-if="item.itemType === 'select' || item.itemType === 'multiselect'"
                           v-model="item.value" placeholder="请选择" size="mini">
                  <el-option v-for="(i,k) in item.itemKeyValueList" :key="l" :label="i.value"
                             :value="i.key"></el-option>
                </el-select>
                <el-date-picker
                  v-if="item.itemType === 'date' || item.itemType === 'datetime'"
                  v-model="item.value"
                  :placeholder="item.itemType === 'date' ? '请选择日期' : '请选择日期时间'"
                  type="date">
                </el-date-picker>
                <el-time-select
                  v-if="item.itemType === 'time'"
                  v-model="item.value"
                  :picker-options="{
                         start: '08:30',
                         step: '00:15',
                         end: '18:30'
                         }"
                  placeholder="选择时间">
                </el-time-select>
                <el-button v-if="item.itemType === 'file'"
                           v-model="item.value" plain size="mini" type="primary">
                  上传文件
                </el-button>
                <el-button v-if="item.itemType === 'multiFile'"
                           v-model="item.value" plain size="mini" type="primary">
                  多文件上传
                </el-button>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </el-dialog>
    <el-dialog
      v-dialogDrag
      :visible.sync="authVisible"
      append-to-body="true"
      class="avue-dialog"
      title="权限控制-人员列表"
      width="60%"
      @close="authDialogClose">
      <div style="height: 650px">
        <div style="height: 600px;">
          <avue-tree :key="refresh" ref="authTree" v-model="treeAuthForm" :data="treeAuthData" :option="treeAuthOption"
                     @check-change="treeAuthCheckChange">
              <span slot-scope="{ node, data }" class="el-tree-node__label">
           <span style="font-size: 15px">
              <i class="el-icon-s-promotion"></i>
                {{ (node || {}).label }}
            </span>
          </span>
          </avue-tree>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
         <el-button @click="authDialogClose">取 消</el-button>
         <el-button type="primary" @click="authDialogSaveHandler">确 定</el-button>
    </span>
    </el-dialog>
  </el-dialog>
</template>
<script>
import {getTreeAttributes, savePortalVI} from "@/api/UI/formDefine/api";
import {getObjTypeQTs, getTreeAttributes, savePortalVI, refPersonOrgTree} from "@/api/UI/formDefine/api";
import {gridAttribute} from "@/api/modeling/attributePool/api";
import func from "@/util/func";
import basicOption from "@/util/basic-option";
export default {
  name: "formDialog",
@@ -695,6 +837,87 @@
  },
  data() {
    return {
      authType: 'default',
      refresh: Math.random(),
      treeAuthOption: {
        multiple: true,
        height: 'auto',
        menu: false,
        addBtn: false,
        defaultExpandAll: true,
        lazy: true,
        props: {
          label: 'text',
          value: 'oid',
          children: 'childNodes',
        },
        treeLoad: (node, resolve) => {
          const params = {
            'conditionMap[dataType]': node.data.data,
            'conditionMap[parentId]': node.data.data,
            'conditionMap[orgType]': 'all'
          }
          refPersonOrgTree(node.level === 0 ? {} : params).then(res => {
            resolve(res.data.treeData.map(item => {
              return {
                ...item,
                id: item.id,
                name: item.name,
                leaf: item.leaf
              }
            }))
          })
        }
      },
      treeAuthData: [],
      treeAuthForm: {},
      authVisible: false,
      searchQtNameList: [],
      customAttrRow: {},
      customAttrOption: {
        ...basicOption,
        calcHeight: -60,
        addBtn: false,
        editBtn: false,
        delBtn: false,
        menu: false,
        refreshBtn: false,
        highlightCurrentRow: true,
        selection: false,
        column: [
          {
            label: '属性名',
            prop: 'id',
            sortable: true,
          },
          {
            label: '标签',
            prop: 'name',
            sortable: true,
          },
          {
            label: '类型',
            prop: 'attributeDataTypeText',
            sortable: true,
            width: 100
          },
          {
            label: '默认值',
            prop: 'defaultValue',
            sortable: true,
            width: 120
          },
          {
            label: '描述',
            prop: 'description',
            overHidden: true,
          },
        ]
      },
      customAttrData: [],
      customAttrLoading: false,
      customAttrVisible: false,
      checkViewVisible: false,
      optionObj: {
        optionName: '',
        optionValue: ''
@@ -829,7 +1052,11 @@
          children: 'children',
        },
      },
      treeData: []
      treeData: [],
      optionRow: {},
      customOptionRow: {},
      optionCurrentIndex: 0,
      customOptionCurrentIndex: 0
    }
  },
  computed: {
@@ -837,7 +1064,6 @@
      const types = ['radio', 'checkbox', 'select'];
      return types.includes(this.form.itemType); // 展示
    },
    itemStyleTypeStatus() {
      const types = ['hidden', 'webeditor', 'radio', 'checkbox'];
      return !types.includes(this.form.itemType); // 不展示
@@ -877,6 +1103,7 @@
          this.treeLoading = false;
        }
      })
      this.getSearchSelectList();
    },
    // 开始拖拽树节点事件
@@ -892,7 +1119,11 @@
      const params = {
        text: data.text,
        oid: data.oid,
        itemType: 'text'
        itemType: 'text',
        itemName: data.data.name,
        itemCols: "1",
        itemIsEditable: "0",
        itemIsRequired: "0",
      }
      const isDuplicate = this.formList.some(item => item.text === data.text);
@@ -908,8 +1139,8 @@
      this.activeItem = item;
      this.activeItemIndex = index;
      this.form = {...item};
      // console.log(item,index);
      this.topForm.position = index += 1;
      // this.$forceUpdate();
    },
    // 设置显示行数
@@ -977,7 +1208,7 @@
        this.$message.error('请选择一条数据进行删除');
        return;
      }
      this.formList = this.formList.filter(item => item.text != this.activeItem.text);
      this.formList = this.formList.filter(item => item.text !== this.activeItem.text);
      this.activeItem = {};
      this.form = {};
    },
@@ -1011,7 +1242,11 @@
    // 选项表格行点击
    optionTableClick(row) {
      console.log(row);
      this.optionRow = row;
    },
    customOptionTableClick(row) {
      this.customOptionRow = row;
    },
    // 选项添加
@@ -1042,15 +1277,20 @@
      const params = {
        key: optionObj.optionName,
        value: optionObj.optionValue
        value: optionObj.optionValue,
        index: val === 'dialog' ? this.customOptionCurrentIndex++ : this.optionCurrentIndex++
      };
      itemKeyValueList.push(params);
    },
    // 选项删除
    optionDeleteClickHandler() {
    optionDeleteClickHandler(val) {
      if (val === 'dialog') {
        this.customForm.itemKeyValueList.splice(this.customOptionRow.index,1);
      } else {
        this.form.itemKeyValueList.splice(this.optionRow.index,1);
      }
    },
    // 添加自定义组件
@@ -1061,17 +1301,17 @@
    // 保存按钮
    saveClickHandler() {
      if (!this.topForm.viName) {
        this.$message.error('名称不能为空');
        this.$message.error('表单名称不能为空');
        return;
      }
      if (this.formList.length <= 0) {
        this.$message.error('页面不能为空');
        this.$message.error('页面定义不能为空');
        return;
      }
      this.formList = this.formList.map(item => {
        return {
          ...item,
          itemField: item.text // 将itemField赋值为text,因为忘记父组件为什么在编辑回填时把itemField赋值为text了
          itemField: item.text // 将itemField重新赋值为text,因为忘记当时在父组件编辑回填方法里为什么把itemField赋值为text了
        };
      });
      const params = {
@@ -1083,18 +1323,17 @@
        viType: 1, // 视图类型
        viTypeText: "表单", // 视图中文名称
        prm: {
          formQtName: '', // 查询模板名称
          formQtName: this.topForm.itemQtName, // 查询模板名称
          showCols: this.topForm.showColumn,
          prmItemList: this.formList
        },
      }
      console.log(params);
      savePortalVI(params).then(res => {
        console.log(res);
        if(res.data.code === 200){
        if (res.data.code === 200) {
          this.$message.success(res.data.obj);
          this.visible = false;
          this.closeDialog();
          this.$emit('updataTable');
        }
      })
      // this.visible = false;
@@ -1108,14 +1347,14 @@
      }
      if (!this.form.text) {
        this.$message.error('请在右侧选择数据后进行操作!');
        return;
      }
      const targetObject = this.formList.find(item => item.text === this.form.text);
    },
      if (targetObject) {
        targetObject.itemType = val;
    // 自定义组件修改显示类型
    customItemTypeChange(val) {
      if (val) {
        this.customClearFormBottom();
      }
      this.form.itemType = val;
    },
    // 自定义组件保存
@@ -1126,6 +1365,11 @@
      }
      if (!this.customForm.itemType) {
        this.$message.error('请选择显示类型');
        return;
      }
      const status = this.formList.some(item => item.text === this.customForm.text);
      if (status) {
        this.$message.error('请检查是否添加相同项');
        return;
      }
      this.formList.push(this.customForm);
@@ -1148,24 +1392,116 @@
      this.form.itemListTable = this.form.itemListTxt = this.form.itemListVal = this.form.itemStyle = "";
    },
    // 自定义组件清空不同类型表单下方绑定值
    customClearFormBottom() {
      this.customOptionObj = {};
      this.customForm.itemKeyValueList = [];
      this.customForm.itemListTable = this.customForm.itemListTxt = this.customForm.itemListVal = this.customForm.itemStyle = "";
    },
    // 自定义表单使用字段表格行点击
    customAttrRowClickHandler(row) {
      this.customAttrRow = row;
    },
    // 自定义表单使用字段选择
    customTextHandler() {
      this.customAttrVisible = true;
      this.customAttrLoading = true
      gridAttribute().then(res => {
        const data = res.data.data;
        this.customAttrData = data;
        this.customAttrLoading = false;
      }).catch(err => {
        this.$message.error(err)
      });
    },
    // 自定义表单使用字段保存
    customAttrSaveHandler() {
      if (func.isEmptyObject(this.customAttrRow)) {
        this.$message.error('请选择一条数据进行保存');
        return;
      }
      this.customForm.text = this.customAttrRow.id;
      this.customAttrVisible = false;
    },
    // 右侧表单应用按钮
    asideFormHandler() {
      if (!this.form.text) {
        this.$message.error('请添加一条数据进行保存!');
        return;
      }
      this.formList = this.formList.map(item =>
        item.text === this.form.text ? this.form : item
      );
      this.$message.success('应用成功');
    },
    customClearFormBottom() {
      this.optionObj = {};
      this.form.itemKeyValueList = [];
      this.form.itemListTable = "";
      this.form.itemListTxt = "";
      this.form.itemListVal = "";
      this.form.itemStyle = "";
    // 预览按钮
    checkViewHandler() {
      this.checkViewVisible = true;
    },
    // 查询模板下拉接口查询
    getSearchSelectList() {
      getObjTypeQTs({btName: this.treeRadio === '0' ? this.TreeNodeRow.id : this.TreeNodeRow.name}).then(res => {
        this.searchQtNameList = res.data.data;
      })
    },
    // 权限选择按钮
    authClickHandler() {
      this.authVisible = true;
    },
    // 自定义表单选择权限
    customAuthClickHandler() {
      this.authVisible = true;
      this.authType = 'attr';
    },
    // 权限树对话框关闭
    authDialogClose() {
      this.authVisible = false;
      this.refresh = Math.random(); // 刷新左侧树
    },
    // 权限控制保存
    authDialogSaveHandler() {
      const filterList = ['root', 'user', 'role', 'department']
      const data = this.$refs.authTree.getCheckedNodes().filter(item => !filterList.includes(item.oid));
      if (!data || data.length <= 0) {
        this.$message.error('请检查是否勾选子节点');
        return;
      }
      const resultMap = {};
      data.forEach(item => {
        const key = item.parentBtmName;
        if (!resultMap[key]) {
          resultMap[key] = []; // 初始化数组
        }
        resultMap[key].push(item.parentBtmName === 'user' ? item.data.userName : item.data.name);
      });
      // 组装字符串
      const resultString = Object.entries(resultMap).map(([key, oids]) => {
        return `${key}=${oids.join(',')}`; // 用 , 连接同一类型的 oid
      }).join('&&'); // 最后用 && 连接不同类型
      if (this.authType === 'attr') {
        this.customForm.itemRight = resultString;
      } else {
        this.form.itemRight = resultString;
      }
      this.authDialogClose();
    }
  }
}
</script>
@@ -1204,4 +1540,8 @@
  font-size: 14px
}
//.formItemMargin {
//  margin: 10px 0 10px 0;
//}
</style>