<template>
    <span class="pages">
        <ed-dialog :close-on-press-escape="true" :fullscreen="fullscreen" :visible.sync="dialogVisible" title="视图属性管理">
            <span slot="footer" class="dialog-footer">
                <el-button type="primary" @click="saveControlInfo">保 存</el-button>
                <el-button type="primary" @click="dialogVisible = false">关 闭</el-button>
            </span>

            <el-row :gutter="20" class="es-row">
                <el-col :span="5" class="es-row--col">
                    <el-card class="es-box-card">
                        <div slot="header" class="es-box-card--header">
                            <div>视图列表</div>
                            <div class="tab">
                                <el-button icon="el-icon-document-copy" size="small" type="text"
                                           @click="copyViewOpenDialog">复制</el-button>
                                <el-button icon="el-icon-refresh" size="small" type="text"
                                           @click="reloadAll">刷新</el-button>
                                <el-button icon="el-icon-plus" size="small" type="text" @click="addView">添加</el-button>
                            </div>
                        </div>
                      <el-menu class="es-menu" default-active="0">
                        <el-menu-item v-for="(item, index) in viewRecord" :key="index" :index="String(index)"
                                      class="es-menu-item" @click.native="clickViewName(item)">
                          <p>{{ `${item.viewName} (${item.viewGroup})` }}</p>
                          <div class="es-menu-item--operate">
                            <el-popconfirm :title="`确定删除视图【${item.viewName}】?`" @confirm="deleteView(item)">
                                <el-button v-if="!item.notDelete" slot="reference" size="small" type="text"
                                           @click.native.stop>删除</el-button>
                            </el-popconfirm>
                            <el-button v-if="!item.notDelete" size="small" type="text"
                                       @click.native.stop="updateView(item)">修改</el-button>
                          </div>
                        </el-menu-item>
                      </el-menu>
                    </el-card>
                </el-col>
                <el-col :span="19" class="es-row--col">
                  <ed-table-editor v-model="controlRecords" :columns="tableColumns" :rules="controlRules" height="450px"
                                   :loading="loading"
                                   is-drag row-key="controlName"
                                   size="small" title="控件信息">
                    <template #extra>
                      <el-button icon="el-icon-bottom" size="small" type="text" @click="pullControl">拉取</el-button>
                      <el-button icon="el-icon-folder" size="small" type="text" @click="saveControlInfo">保存</el-button>
                      <el-button icon="el-icon-plus" size="small" type="text" @click="addControl(addControlMaxLength)">添加</el-button>
                      <el-button v-show="changeAddControlFlag" icon="el-icon-edit" size="small" type="text"
                                 @click="clickInsertControlButton">插入</el-button>
                      <el-input v-show="!changeAddControlFlag" ref="insertControlInput"
                                v-model="insertControlRow"
                                :placeholder="`请输入要插入的行:1~${addControlMaxLength}`"
                                oninput="value=value.replace(/[^0-9]/g,'')"
                                @blur="cancelInsertControlRow"
                                @keyup.enter.native="addControl(insertControlRow)"/>
                    </template>

                    <template v-slot:operate="{ self, row}">
                      <el-button type="text" @click="addControlProps(row)">属性</el-button>
                      <el-button type="text" @click="deleteControlInfo(row)">删除</el-button>
                    </template>
                  </ed-table-editor>
                </el-col>
            </el-row>
        </ed-dialog>
        <el-dialog :destroy-on-close="true" :visible.sync="addViewDialogVisible" center title="新增视图" width="30%">
            <el-form ref="addNewViewFormRef" :model="addNewViewForm" label-position="right" label-width="80px">
                <el-form-item :rules="[{ required: true, message: '视图名称不能为空' }]" label="视图名称" prop="viewName">
                    <el-input v-model="addNewViewForm.viewName" placeholder="请输入视图名称"></el-input>
                </el-form-item>
                <el-form-item :rules="[{ required: true, message: '分组名称不能为空' }]" label="分组名称" prop="viewGroup">
                    <el-input v-model="addNewViewForm.viewGroup" placeholder="请输入分组名称"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="addViewDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="saveNewView">确 定</el-button>
            </span>
        </el-dialog>
        <el-dialog :destroy-on-close="true" :title="copyViewTitle" :visible.sync="copyViewDialogVisible" center
                   width="30%">
            <el-form ref="copyNewViewFormRef" :model="copyNewViewForm" label-position="right" label-width="80px">
                <el-form-item :rules="[{ required: true, message: '视图名称不能为空' }]" label="视图名称" prop="viewName">
                    <el-input v-model="copyNewViewForm.viewName" placeholder="请输入视图名称"></el-input>
                </el-form-item>
                <el-form-item :rules="[{ required: true, message: '分组名称不能为空' }]" label="分组名称" prop="viewGroup">
                    <el-input v-model="copyNewViewForm.viewGroup" placeholder="请输入分组名称"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="copyViewDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="copyCurrentView">确 定</el-button>
            </span>
        </el-dialog>
        <ControlViews ref="controlProps"/>
    </span>
</template>
<script>
import ds            from '../../../../api/ds'
import Vue           from 'vue';
import {controlType} from '../../../../utils/setting'
import ControlViews  from './ControlViews'

export default {
  components: {ControlViews},
  data() {
    return {
      tableValue: [],
      tableColumns: [
        {
          prop: 'controlName',
          label: "虚拟列",
          align: "center",
          width: "240px",
          children: {
            tags: "el-select",
            attrs: {
              size: "small",
              placeholder: "请选择虚拟列",
              filterable: true,
              allowCreate: true,
              defaultFirstOption: true
            },
            options: []
          },
          change: this.handleChange
        },
        {
          prop: 'controlType',
          label: "控件类型",
          align: "center",
          width: "150px",
          children: {
            tags: "el-select",
            attrs: {
              size: "small",
              clearable: true,
              filterable: true,
              placeholder: "请选择控件"
            },
            options: controlType
          },
        },
        {
          prop: 'label',
          label: "标签",
          align: "center",
          width: "150px",
          children: {
            tags: "ed-input-pop",
            attrs: {
              size: "small",
              placeholder: "请输入标签"
            },
          }
        },
        {
          prop: 'isRequired',
          label: "必输",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        },
        {
          prop: 'isQuery',
          label: "查询项",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        },
        {
          prop: 'isAccurateQuery',
          label: "精确查询",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        },
        {
          prop: 'isInput',
          label: "录入项",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        },
        {
          prop: 'isShow',
          label: "列表展示",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        }, {
          prop: 'isVirtual',
          label: "虚拟列",
          align: "center",
          width: "auto",
          children: {
            size: "small",
            tags: "el-switch",
          }
        }
      ],
      tabPosition: 'left',
      dialogVisible: false,
      fullscreen: true,
      currentDataSource: {}, //当前数据源
      viewRecord: [], //视图列表
      currentView: {id: 'default', viewName: '默认视图'}, //默认选中视图
      controlRecords: [], //视图对应控件列表
      controlColumns: {
        controlName: [],
        controlType: controlType
      }, //控件字段属性
      loading: false,
      controlRules: {
        controlName: {message: '请选择虚拟列'},
        controlType: {message: '请选择控件'},
        label: {message: '请输入标签'}
      }, //控件属性输入规则
      addViewDialogVisible: false, //添加视图modal标识
      addNewViewForm: {}, //添加视图form
      copyViewDialogVisible: false, //复制视图modal标识
      copyViewTitle: '复制视图',
      copyNewViewForm: {}, //复制视图form
      changeAddControlFlag: true, //点击插入控件标识
      insertControlRow: null, //插入控件输入框值
      originalColumns: [
        {
          label: 'id(主键)',
          value: 'id',
          text: '主键'
        }, {
          label: 'creator(创建人)',
          value: 'creator',
          text: '创建人'
        }, {
          label: 'org_code(机构编号)',
          value: 'org_code',
          text: '机构编号'
        }, {
          label: 'org_id(机构ID)',
          value: 'org_id',
          text: '机构ID'
        }, {
          label: 'create_time(创建时间)',
          value: 'create_time',
          text: '创建时间'
        }, {
          label: 'update_time(更新时间)',
          value: 'update_time',
          text: '更新时间'
        }, {
          label: 'updater(更新人)',
          value: 'updater',
          text: '更新人'
        }, {
          label: 'deleted(是否删除)',
          value: 'deleted',
          text: '是否删除'
        }, {
          label: 'tenant_id(租户编号)',
          value: 'tenant_id',
          text: '租户编号'
        }]
    }
  },
  watch: {
    controlRecords: {
      handler(nVal, oVal) {
        if (nVal && nVal.length > 0) {
          nVal.map((item, i) => item.orderNum = i + 1)
        }
      },
      deep: true,
      immediate: true
    }
  },
  computed: {
    addControlMaxLength() {
      return this.controlRecords.length + 1
    }
  },
  methods: {
    showModal(record) {
      this.init()
      this.currentDataSource = record
      this.reloadAll()
      this.initFieldOptions();
      this.dialogVisible = true
    },
    init() {
      this.currentView = {id: 'default', viewName: '默认视图'}
      this.cancelInsertControlRow()
    },
    //刷新
    reloadAll() {
      this.showViewInfo()
      this.showControlInfo(this.currentView)
    },
    //添加视图
    addView() {
      Vue.delete(this.addNewViewForm, 'id')
      this.addViewDialogVisible = true
    },
    //修改视图
    updateView(item) {
      this.addNewViewForm = Object.assign({}, item)
      this.addViewDialogVisible = true
    },
    //保存新增的视图
    saveNewView() {
      this.$refs.addNewViewFormRef.validate((valid) => {
        if (valid) {
          ds.addViewModel({
            dataSourceId: this.currentDataSource.id,
            viewInfos: [this.addNewViewForm]
          }).then(res => {
            if (res.success) {
              this.$message.success("保存成功")
              this.showViewInfo()
              this.addNewViewForm = {}
              this.addViewDialogVisible = false
            } else {
              this.$message.warning(res.msg)
            }
          })

        } else {
          return false;
        }
      })
    },
    deleteView(item) {
      ds.deleteViewModel({id: item.id}).then(res => {
        this.$message.success(res.msg)
        this.showViewInfo()
      })
    },
    //查询视图列表
    showViewInfo() {
      ds.controlInfoViewList({dataSourceId: this.currentDataSource.id}).then(res => {
        if (res.success) {
          this.viewRecord = res.data.map(item => {
            return {
              ...item,
              shadow: 'hover'
            }
          })
          this.viewRecord.unshift({
            id: 'default',
            viewName: '默认视图',
            viewGroup: 'default',
            notDelete: true,
            shadow: 'always'
          })
          this.changeViewShadow(this.currentView)
        } else {
          this.$message.warning(res.msg)
        }
      })
    },
    //查询选中的视图控件列表信息
    showControlInfo(view) {
      this.controlRecords.splice(0, this.controlRecords.length)
      if (view.id) {
        this.loading = true
        ds.listControlInfo({dataSourceId: this.currentDataSource.id, viewId: view.id}).then(res => {
          if (res.success) {
            res.data.map(t => {
              this.controlRecords.push(t)
            })
          } else {
            this.$message.warning(res.msg)
          }
        }).finally(() => {
          this.loading = false
        })
      } else {
        this.$message.warning('请先保存视图')
      }
    },
    //点击视图card
    clickViewName(currentView) {
      this.changeViewShadow(currentView)
      if (this.currentView.id != currentView.id) {
        this.showControlInfo(currentView)
        this.currentView = currentView
      } else {//获取当前视图ID
        this.$message.success(currentView.id)
      }
    },
    //切换视图
    changeViewShadow(currentView) {
      this.viewRecord = this.viewRecord.map(item => {
        if (item.id == currentView.id) {
          return {
            ...item,
            shadow: 'always'
          }
        } else {
          return {
            ...item,
            shadow: 'hover'
          }
        }
      })
    },
    //控件信息移动
    handleBlurOrderNum(record) {
      if (this.controlRecords.length > 0) {
        let current = this.controlRecords.find(item => item.id == record.id)
        let currentIndex = this.controlRecords.findIndex(item => item.id == record.id);
        let newIndex = parseInt(record.orderNum);
        this.controlRecords.splice(currentIndex, 1)
        if (newIndex > this.controlRecords.length) {
          this.controlRecords.push(current)
        } else {
          this.controlRecords.splice((newIndex <= 0 ? 1 : newIndex) - 1, 0, current)
        }
        this.orderControlRecords()
      }
    },
    //控件排序
    orderControlRecords() {
      this.controlRecords = this.controlRecords.map((item, index) => {
        return {
          ...item,
          orderNum: index + 1
        }
      })
    },
    //初始化虚拟列下拉列表
    async initFieldOptions() {
      const res = await ds.listFieldInfo({dataSourceId: this.currentDataSource.id})
      if (res.success) {
        this.tableColumns.map(columns => {
          if (columns.prop === 'controlName') {
            columns.children.options = res.data.map(item => {
              return {
                label: `${item.fieldName}(${item.remark})`,
                value: item.fieldName,
                text: item.remark
              }
            }).concat(this.originalColumns)
          }
        })

        this.controlColumns.controlName = res.data.map(item => {
          return {
            label: `${item.fieldName}(${item.remark})`,
            value: item.fieldName,
            text: item.remark
          }
        }).concat(this.originalColumns)
      } else {
        this.$message.error(res.msg)
      }
    },
    //添加控件属性
    addControl(command) {
      if (command > this.addControlMaxLength) {
        command = this.addControlMaxLength
      }
      this.controlRecords.splice(command - 1, 0, {
        orderNum: command,
        isVirtual: true,
        isRequired: false,
        isQuery: false,
        isAccurateQuery: false,
        isInput: false,
        isShow: true
      })
      this.orderControlRecords()
      this.cancelInsertControlRow()
    },
    handleChange(col, val, row, index) {
      if (col.prop === 'controlName') {
        let selectObj = this.controlColumns.controlName.filter(item => item.value === val);
        row.label = selectObj && selectObj[0] ? selectObj[0].text : val
        row.fieldInfo = selectObj && selectObj[0] ? selectObj[0].value : val
      }
      this.checkControleInfo([row])
    },

    //点击插入按钮
    clickInsertControlButton() {
      this.changeAddControlFlag = false;
      this.$nextTick(() => {
        this.$refs.insertControlInput.focus();
      })
    },
    //取消插入输入框
    cancelInsertControlRow() {
      this.changeAddControlFlag = true;
      this.insertControlRow = null
    },
    //检查table中填写的数据
    checkControleInfo(records) {
      let result = true;
      records.forEach((item, index) => {
        for (const rule in this.controlRules) {
          if (!item[rule]) {
            result = false;
            this.$set(records[index], `${rule}Error`, true)
          } else {
            this.$set(records[index], `${rule}Error`, false)
          }
        }
      })
      //判断是否添加了重复字段
      if (records.length == 1 && this.controlRecords.length > 1) {
        let double = this.controlRecords.filter(t => t.controlName == records[0].controlName);
        if (double.length > 1) {
          result = false;
          this.$set(records[0], 'controlNameError', true)
        } else {
          this.$set(records[0], 'controlNameError', false)
        }
      } else if (records.length > 1 && this.controlRecords.length > 1) {
        let i = 0
        const pre = this.controlRecords.reduce((pre, cur) => {
          if (pre[cur.controlName]) {
            pre[cur.controlName].push(i)
          } else {
            pre[cur.controlName] = [i]
          }
          i++;
          return pre
        }, {})
        for (let t in pre) {
          if (pre[t].length > 1) {
            result = false;
            pre[t].forEach(k => {
              this.$set(records[k], 'controlNameError', true)
            })
          } else {
            this.$set(records[pre[t][0]], 'controlNameError', false)
          }
        }
      }
      return result;
    },
    //保存控件信息
    saveControlInfo() {
      //检查表单
      if (this.controlRecords.length == 0) {
        return
      }
      let check = this.checkControleInfo(this.controlRecords)
      if (!check) {
        this.$message.error("请检查必填项")
      } else {
        this.loading = true;
        ds.saveControlModel({
          dataSourceId: this.currentDataSource.id,
          viewId: this.currentView.id,
          controlInfos: this.controlRecords
        }).then(res => {
          if (res.success) {
            this.showControlInfo(this.currentView)
            this.$message.success(res.msg)
          } else {
            this.$message.error(res.msg)
          }
        }).finally(() => {
          this.loading = false;
        })
      }
    },
    //删除控件信息
    deleteControlInfo(record) {
      let currentIndex = this.controlRecords.findIndex(item => item.orderNum == record.orderNum);
      this.controlRecords.splice(currentIndex, 1)
      if (record.id) {
        this.loading = true;
        ds.deleteControlInfo({id: record.id}).then(res => {
          this.$message.success(res.msg)
        }).finally(() => {
          this.loading = false;
        })
      }
      this.orderControlRecords()
    },
    //控件信息查询属性
    addControlProps(record) {
      let check = this.checkControleInfo([record]);
      if (!check) {
        return;
      }
      if (!record.id) {
        let currentIndex = this.controlRecords.findIndex(item => item.orderNum == record.orderNum);
        this.loading = true;
        ds.saveControlModel({
          dataSourceId: this.currentDataSource.id,
          viewId: this.currentView.id,
          controlInfos: [record]
        }).then(res => {
          if (res.success) {
            this.controlRecords.splice(currentIndex, 1, res.data[0])
            this.openControlProps(res.data[0])
          } else {
            this.$message.error(res.msg)
          }
        }).finally(() => {
          this.loading = false;
        })
      } else {
        this.openControlProps(record)
      }
    },
    //打开属性框
    openControlProps(currentRow) {
      this.$refs.controlProps.showModal(currentRow)
    },
    pullControl() {
      const arr = ['id', 'creator', 'createTime', 'updater', 'updateTime', 'deleted', 'tenantId', 'orgCode', 'orgId']
      for (let field of this.controlColumns.controlName) {
        let exist = false
        for (let control of this.controlRecords) {
          if (control.fieldInfo == field.value) {
            exist = true
            break
          }
        }
        if (exist) {
          continue
        }
        let controlType = 'input'
        if (arr.indexOf(field.value) === -1) {
          this.controlRecords.push({
            fieldInfo: field.value,
            controlName: field.value,
            controlType: controlType,
            label: field.text,
            isVirtual: true,
            isRequired: false,
            isQuery: true,
            isAccurateQuery: false,
            isInput: false,
            isShow: true,
            orderNum: this.controlRecords.length + 1
          })
        }
      }
    },
    copyViewOpenDialog() {
      this.copyViewTitle = "复制视图-" + this.currentView.viewName;
      this.copyViewDialogVisible = true;
      this.copyNewViewForm = this.currentView;
    },
    copyCurrentView() {
      this.$refs.copyNewViewFormRef.validate((valid) => {
        if (valid) {
          ds.copyViewModel({
            dataSourceId: this.currentDataSource.id,
            viewInfos: [this.copyNewViewForm]
          }).then(res => {
            if (res.success) {
              this.$message.success("复制成功")
              this.showViewInfo()
              this.copyNewViewForm = {}
              this.copyViewDialogVisible = false
            } else {
              this.$message.warning(res.msg)
            }
          })
        } else {
          return false;
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.cardview {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .tab {
    display: flex;
    justify-content: flex-end;
  }

}

.float-right-class {
  float: right
}

.border-shadow {
  min-height: 400px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
}

.el-button--small {
  padding: 3px 0px;
}

.view-list-card.is-always-shadow {
  background-color: rgb(225, 243, 216);
}

.pages :deep(.el-dialog) {
  max-width: 100% !important;
  max-height: 100% !important;
}

.el-dropdown-link {
  color: #409EFF;
  cursor: pointer;
  font-size: 12px;
}

.is-error {
  :deep(.el-input__inner) {
    border-color: red;
  }
}
</style>
