<template>
  <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="permissionList">
    <div class="permissionList_tree">
      <div class="permissionList_tree_head flex">
        <div class="permissionList_tree_head_list">名称</div>
        <div class="permissionList_tree_head_list">类型</div>
        <div class="permissionList_tree_head_list">行权限</div>
        <div class="permissionList_tree_head_list">操作</div>
      </div>
      <div class="permissionList_tree_body">
        <el-scrollbar style="height: 100%" :horizontal="false">
          <el-tree ref="tree" :data="data" show-checkbox node-key="apiid" default-expand-all :expand-on-click-node="false" @check="checkChange">
            <template slot-scope="{node,data}">
              <div class="custom-tree-node flex">
                <div class="custom-tree-node-list">{{data.apiname}}</div>
                <div class="custom-tree-node-list">{{data.apitype}}</div>
                <div class="custom-tree-node-list">
                  <el-tooltip class="item" effect="dark" :content="data.filterset" placement="top">
                    <div class="tmsg">{{ data.filterset }}</div>
                  </el-tooltip>
                </div>
                <div class="custom-tree-node-list">
                  <template v-if="data.apitype != '参数'">
                    <el-button size="mini" type="text" @click="details(node, data)">行权限</el-button>
                  </template>
                </div>
              </div>
            </template>
          </el-tree>
        </el-scrollbar>
      </div>
    </div>
    <div class="permissionList_dialog">
      <!--高级查询-->
      <PublicPageDialog dialog-title="行权限" dialogSize="600px" :dialog-drawer="advancedDrawer" @handleClose="advancedDrawer = false" @handleSubmit="advancedTable('advancedDialogForm')">
        <AdvancedQuery ref="advancedDialogForm" :select-options="selectOptions" :ad-list="false" :ad-dep="adDep" @getAdvancedQueryData="getAdvancedQueryData" />
      </PublicPageDialog>
    </div>
  </div>
</template>

<script>
import PublicPageDialog from '@/components/PublicPageDialog'
import AdvancedQuery from '@/components/AdvancedQuery'
import { mapGetters } from 'vuex'
import { listToTree } from '@/utils/validate'
import { Query, newData, modifyData, moveData, getAuthorization, authorization } from "@/api/webApi"
import { formatChange } from '@/utils/validate'

export default {
  name: 'Permissionlist',
  props: {
    listMap: {
      type: Object,
      default: () => new Object()
    },
    treeMap: {
      type: Object,
      default: () => new Object()
    }
  },
  components: { PublicPageDialog, AdvancedQuery },
  data () {
    return {
      advancedDrawer: false,
      loading: false,
      ischeck: false,
      data: [],
      defaultProps: {
        children: 'children',
        label: 'pagename'
      },
      defaultKeys: [],
      nodeKey: 'apiid',
      adDep: 1,
      dataKey: 'pagename',
      checkDatas: [],
      queryItem: {},
      tableKey: '',
      rowData: {},
      selectOptions: [],
      queryId: 9,
      allAuthData: [],
    }
  },
  watch: {
    listMap: {
      handler (row) {
        if (Object.keys(row).length) {
          const queryItem = _.cloneDeep(row)
          if (queryItem.children) delete queryItem.children
          this.queryItem = queryItem
          this.restDataRow(queryItem)
        }
      },
      deep: true,
      immediate: true
    },
    treeMap: {
      handler (obj) {
        if (Object.keys(obj).length) {
          const { serviceid, pagename } = obj
          this.queryAllAuthData(serviceid, pagename)
        }
      },
      deep: true,
      immediate: true
    }
  },
  computed: {
    ...mapGetters(['authArrs'])
  },
  methods: {
    async queryAllAuthData (serviceid, pagename) {
      this.loading = true
      const datacontent = { filter: { 1: 1 } }
      try {
        const { code, returnData } = await Query({
          serviceid,
          datacontent,
          event: '0',
          page: 1,
          size: 9999,
        });
        if (code == 0 && returnData?.length) {
          returnData.forEach(item => {
            item.pagename = item.apiname
            item.pagecode = item.apiid
          })
          this.allAuthData = _.cloneDeep(returnData)
          this.setAuthData([], returnData)
        } else {
          this.$message.error(`获取${pagename}数据失败`);
        }
      } catch (error) {
        this.$message.error(`获取${pagename}数据失败`);
      }
      this.loading = false;
    },
    disableTreeData (arr = []) {
      if (!arr.length) return
      const alldata = _.cloneDeep(arr)
      const isdata = _.cloneDeep(this.authArrs)
      const nodata = this.findRepetData(alldata, isdata)
      if (nodata?.length) {
        alldata.map(item => {
          nodata.map(ci => {
            if (item.apiid == ci.apiid) {
              item.disabled = true
            }
          })
        })
      }
      return alldata
    },
    restDataRow (queryItem = this.queryItem) {
      this.ischeck = true
      this.checkDatas = []
      this.$refs.tree.setCheckedKeys([])
      this.queryTreeData(queryItem, '权限')
    },
    //高级查询-提交
    advancedTable (refName) {
      this.$refs[refName].advancedQueryHandler()
    },
    getAdvancedQueryData (dataRules) {
      const ndata = this.checkDatas?.at(-1)
      const nitem = ndata.filter(item => item.apiid == this.rowData.apiid)
      const { appid } = this.queryItem
      const { apiid, columnlist = '', filterset = '' } = nitem[0]
      const rowData = {
        appid,
        apiid,
        columnlist,
        filterset
      }
      rowData.filterset = JSON.stringify(dataRules)
      this.sendCheckData('edit', [rowData])
      this.advancedDrawer = false
    },
    formatRowAuth (nstr, arr) {
      if (!nstr || !arr) return []
      const nitem = JSON.parse(nstr)
      const tableValues = [...arr]
      if (nitem?.length && tableValues?.length) {
        const htmls = []
        const ndatas = [...nitem]
        tableValues.map(({ pagename, pagecode }) => {
          ndatas.map(({ column, comparator, connector, value }) => {
            if (pagecode == column) {
              const comparatorfh = comparator == '=' ? '等于' : '不等于'
              const connectorfh = connector == 'and' ? '并且' : connector == 'or' ? '或者' : ''
              const str = pagename + comparatorfh + value + connectorfh
              htmls.push(str)
            }
          })
        })
        return htmls
      }
    },
    //打开行权限
    details (node, data) {
      if (!this.ischeck) {
        this.$message.error('请先选中左边的权限树后再操作')
        this.$refs.tree.setCheckedKeys([])
        return
      }
      if (!this.checkDatas.length) {
        this.$message.error('请先勾选权限后再操作')
        return
      }
      const ndata = _.cloneDeep(data)
      const { apiid } = ndata
      const nitem = this.checkDatas?.at(-1).filter(item => item.apiid == apiid)
      if (!nitem.length) {
        this.$message.error('请先勾选权限后再操作')
        return
      }
      this.adDep = Math.random()
      this.rowData = ndata
      const rowDataChild = _.cloneDeep(ndata.children)
      rowDataChild.forEach(item => {
        item.isfiltercolumn = true
        item.pagename = item.apiname
        item.pagecode = item.apiid
      })
      this.$store.dispatch('auth/changeAuthMsg', rowDataChild)
      if (data.selectcolumnmsg) {
        this.selectOptions = JSON.parse(data.selectcolumnmsg)
      }
      this.advancedDrawer = true
    },
    //初始化数据
    setAuthData (arrs = [], returnData = [], flag = false) {
      const narrs = _.cloneDeep(arrs)
      const ndata = _.cloneDeep(returnData)
      if (narrs.length) {
        ndata.map(item => {
          narrs.map(ci => {
            if (item.apiid == ci.apiid && ci.filterset) {
              const tableColumnArrs = ndata.filter(item => item['superiorid'] == ci.apiid)
              const htmls = this.formatRowAuth(ci.filterset, tableColumnArrs)
              item.selectcolumnmsg = ci.filterset
              item.filterset = htmls.join('') || ''
            }
          })
        })
      }
      const alldata = this.disableTreeData(ndata)
      const treeMenu = flag ? listToTree([...ndata], 'superiorid', 'apiid') : listToTree([...alldata], 'superiorid', 'apiid')
      this.data = treeMenu
    },
    //勾选已有权限
    checkAuthData (ndata) {
      const returnData = _.cloneDeep(ndata)
      if (ndata?.length) {
        const ids = []
        ndata.map(({ apiid }) => {
          ids.push(apiid)
        })
        this.$refs.tree.setCheckedKeys(ids)
        const treeDatas = this.$refs.tree.getCheckedNodes().concat(this.$refs.tree.getHalfCheckedNodes())
        const res = this.findRepetData(treeDatas, returnData)
        if (res?.length) {
          res.map((item) => {
            if (item.apiid) {
              this.$refs.tree.setChecked(item.apiid, false, false);
            }
          })
        }
        this.checkDatas.push(ndata)
      }
    },
    //获取当前用户组/用户已有权限
    async queryTreeData (dataContent, pagename) {
      this.loading = true
      try {
        const { appid } = dataContent
        const { code, returnData } = await Query({
          serviceid: 9,
          datacontent: {
            appid
          },
          event: '0',
          page: 1,
          size: 9999,
        });
        if (code == 0) {
          const ndata = _.cloneDeep(returnData)
          this.setAuthData(ndata, this.allAuthData, true)
          this.$nextTick(() => {
            this.checkAuthData(ndata)
          })
        } else {
          this.$message.error(`获取${pagename}数据失败`);
        }
      } catch (error) {
        console.log(error)
        this.$message.error(`获取${pagename}数据失败`);
      }
      this.loading = false;
    },
    checkChange () {
      if (!this.ischeck) {
        this.$message.error('请先选中左边的权限树后再操作')
        this.$refs.tree.setCheckedKeys([])
        return
      }
      const checks = this.$refs.tree.getCheckedNodes() //选中
      const halfchecks = this.$refs.tree.getHalfCheckedNodes() //半选中
      const allchecks = [...checks, ...halfchecks]
      this.checkDatas.push(allchecks)
      this.isAddorDel()
    },
    isAddorDel () {
      const ndatas = _.cloneDeep(this.checkDatas)
      if (ndatas.length == 1) {
        this.sendCheckData('add', ndatas[0])
      } else {
        const [nitems1, nitems2] = [ndatas.at(-1), ndatas.at(-2)]
        if (nitems1.length > nitems2.length) {
          const res = this.findRepetData(nitems1, nitems2)
          this.sendCheckData('add', res)
        } else {
          const res = this.findRepetData(nitems1, nitems2)
          this.sendCheckData('del', res)
        }
      }
    },
    findRepetData (nitems1, nitems2) {
      const key = 'apiid'
      const res = [...nitems1, ...nitems2].filter(
        (item) =>
          !(
            nitems1.some((p) => item[key] == p[key]) &&
            nitems2.some((c) => item[key] == c[key])
          )
      )
      return res
    },
    //发送新增编辑删除数据
    sendCheckData (types, data) {
      const event = types == 'add' ? 1 : types == 'edit' ? 2 : 3
      const querys = []
      const items = _.cloneDeep(data)
      const { appid, type } = this.queryItem
      if (types == 'edit') {
        items.map(item => {
          if (item.children) delete item.children
        })
        const params = {
          serviceid: this.queryId,
          datacontent: [
            {
              filter: {
                apiid: items[0].apiid
              },
              value: items[0]
            }
          ],
          event,
        }
        type == 1 ? params.datacontent[0].filter.userid = items[0].userid : params.datacontent[0].filter.usergroupid = items[0].usergroupid
        querys.push(modifyData(params))
      } else {
        items.map(item => {
          if (item.children) delete item.children
          const { apiid, applicationpermissionsid = null } = item
          const params = {
            serviceid: this.queryId,
            datacontent: {
              appid,
              apiid,
              applicationpermissionsid,
              columnlist: null,
              filterset: null
            },
            event
          }
          event == 1 ? querys.push(newData(params)) : querys.push(moveData(params))
        })
      }
      this.getAnscyData(querys, types)
    },
    //获取异步数据
    async getAnscyData (allResult, types) {
      if (!allResult.length) return
      this.loading = true
      const results = await Promise.allSettled(allResult)
      results.map((item) => {
        const { status, value } = item
        if (status == 'fulfilled') {
          const { code } = value
          if (code == 0) {
            if (types == 'edit') this.restDataRow()
            this.$message.success('操作成功')
          } else {
            this.$message.error('操作失败')
          }
        } else {
          this.$message.error('网络错误')
        }
      })
      this.loading = false
    }
  }
}
</script>

<style lang="scss" scoped>
.permissionList {
  height: 100%;
  &_tree {
    height: 100%;
    &_head {
      height: 42px;
      line-height: 42px;
      background-color: #f0f6ff;
      font-size: 16px;
      font-size: 600;
      &_list {
        padding: 0 20px;
        width: 25%;
      }
    }
    ::v-deep &_body {
      height: calc(100% - 52px);
      .el-scrollbar__wrap {
        overflow-x: hidden;
      }
      .is-horizontal {
        display: none;
      }
      .el-tree-node {
        &__content {
          height: 49px;
          border-top: 1px solid #d6d4d4;
        }
      }
      .custom-tree-node {
        width: 100%;
        line-height: 28px;
        &-list {
          padding-right: 20px;
          width: 25%;
          &:last-child {
            padding-right: 0;
          }
        }
        .tmsg {
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }
      }
    }
  }
}
</style>