<template>
  <div id="form-1">
    <el-row>
      <el-col :span="24" class="main">
        <el-form :model="form" :rules="rules" ref="form" label-width="100px">
          <el-form-item label="名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入名称"></el-input>
          </el-form-item>
          <el-form-item label="简介" prop="brief">
            <el-input v-model="form.brief" placeholder="请输入简介"></el-input>
          </el-form-item>
          <el-form-item label="角色编码" prop="code">
            <el-input v-model="form.code" placeholder="请输入角色编码"></el-input>
          </el-form-item>
          <el-form-item label="菜单" prop="menu">
            <div><el-checkbox v-model="allMenu" @change="treeDisabled">所有权限</el-checkbox></div>
            <el-tree
              :data="menuList"
              show-checkbox
              default-expand-all
              node-key="path"
              ref="tree"
              highlight-current
              :props="defaultProps"
              :expand-on-click-node="false"
              @check="nodeSelect"
            >
              <template #default="{ node, data }">
                <span class="custom-tree-node">
                  <span>{{ data.name }}</span>
                  <span>
                    <el-button type="text" size="mini" @click="toUpdateRole(node, data)"> 修改权限 </el-button>
                  </span>
                </span>
              </template>
            </el-tree>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" size="mini" @click="onSubmit('form')">确定</el-button>
            <el-button type="danger" size="mini" @click="toReset('form')">取消</el-button>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <el-dialog append-to-body :visible.sync="show" title="权限分配">
      <el-form>
        <el-form-item label="权限控制">
          <el-radio-group v-model="operaData.mode" @change="operaModelSelect">
            <el-radio label="allow">全部允许</el-radio>
            <el-radio label="refuse">全部禁止</el-radio>
            <el-radio :label="undefined">自定义</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="权限选择">
          <el-checkbox-group v-model="operaData.opera" @change="operaSelect">
            <el-checkbox v-for="i in opera" :key="i.code" :label="i.code">{{ i.zh }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="saveOpera">保存权限</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import { mapState, createNamespacedHelpers } from 'vuex';
export default {
  name: 'form-1',
  props: { form: { type: Object }, menuList: { type: Array }, typeList: { type: Array } },
  components: {},
  data: function () {
    return {
      rules: {
        // name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
      },
      defaultProps: {
        children: 'children',
        label: 'name',
        disabled: true,
      },
      allMenu: false,
      show: false,
      opera: [],
      operaData: {
        menu_id: '',
        mode: '',
        opera: [],
      },
    };
  },
  created() {},
  methods: {
    toUpdateRole(node, data) {
      if (!node.checked) {
        this.$message.warning('您没有使用此菜单,无需设置权限');
        return;
      }
      const { path: id, config = [] } = data;
      if (config.length <= 0) {
        this.$message.warning('该页面没有可操作事务,无需设置权限');
        return;
      }
      this.$set(this, 'opera', config);
      const menuConfig = this.form.menu[id];
      let obj;
      if (!menuConfig) {
        obj = { mode: '', opera: [], menu_id: id };
      } else {
        const { opera, mode } = menuConfig;
        obj = { menu_id: id, opera, mode };
      }
      this.$set(this, 'operaData', obj);
      this.show = true;
    },
    // 所有权限,直接修改form
    treeDisabled(data) {
      let keys = this.$refs.tree.getCheckedKeys();
      for (const key of keys) {
        this.$refs.tree.setChecked(key, false, true);
      }
      if (data) {
        this.form.menu = { mode: 'all' };
      }
    },
    // 节点选择直接同步到form中
    nodeSelect(data, { checkedKeys }) {
      if (checkedKeys.length <= 0) return;
      this.allMenu = false;
      const menu = _.get(this.form, 'menu', {});
      const newMenu = { mode: 'select' };
      // 原有设置的菜单id
      let keys = Object.keys(menu);
      // 过滤掉mode key,这东西不用管
      keys = keys.filter((f) => f === 'mode');
      for (const key of keys) {
        // 找下 原key是否还在现在的已选择列表中
        const r = checkedKeys.find((f) => f === key);
        // 不在:说明被取消了,应该删除
        if (!r) continue;
        // 还在,那就直接把它拿出来放到新的里面
        newMenu[key] = menu[key];
      }
      // 在过滤一次,查看新加的
      for (const id of checkedKeys) {
        if (newMenu[id]) continue;
        newMenu[id] = { opera: [] };
      }
      this.$set(this.form, 'menu', newMenu);
    },
    onSubmit(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$emit('onSubmit', { data: this.form });
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    toReset(formName) {
      this.$refs[formName].resetFields();
      this.$emit('toReset');
    },
    getOneLevelMenus(menus) {
      if (!menus) menus = _.cloneDeep(this.menuList);
      const arr = [];
      for (const menu of menus) {
        const { children, ...others } = menu;
        arr.push(others);
        if (children) {
          const cArr = this.getOneLevelMenus(children);
          arr.push(...cArr);
        }
      }
      return arr;
    },
    operaModelSelect(data) {
      if (data) this.operaData.opera = [];
    },
    operaSelect(data) {
      if (data.length > 0) {
        this.operaData.mode = undefined;
      }
    },
    saveOpera() {
      let dup = _.cloneDeep(this.operaData);
      const { menu_id: id, ...operas } = dup;
      this.form.menu[id] = operas;
      this.show = false;
    },
  },
  computed: {
    ...mapState(['user']),
  },
  metaInfo() {
    return { title: this.$route.meta.title };
  },
  watch: {
    form: {
      deep: true,
      immediate: true,
      handler(val) {
        const menu = _.get(val, 'menu');
        if (!menu) return;
        const { mode } = menu;
        this.$nextTick(() => {
          const keys = this.$refs.tree.getCheckedKeys();
          for (const key of keys) {
            this.$refs.tree.setChecked(key, false, true);
          }
        });

        if (mode === 'all') {
          this.allMenu = true;
          return;
        } else {
          this.allMenu = false;
          let keys = Object.keys(menu);
          keys = keys.filter((f) => f !== 'mode');
          this.$nextTick(() => {
            for (const key of keys) {
              this.$refs.tree.setChecked(key, true);
            }
          });
        }
      },
    },
  },
};
</script>

<style lang="less" scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
