<template>
  <div class="action" v-loading="loading">
    <div
      class="action_show_box"
      v-if=" powers.some((i) => i == '001')"
    >
      <ul class="role-list fl">
        <p class="role-list__title">角色列表</p>
        <p
          v-if="roleList.length == 0"
          style="line-height: 60px; text-align: center; color: #909399"
        >
          暂无数据
        </p>

        <li
          v-for="(item, index) in roleList"
          :key="'role' + index"
          class="role-list__item"
          :class="{ active: item.id == roleActive.id }"
          @click="!isBtnDisabled && switchRoleHandle(item)"
        >
          {{ item.role_name }}
          <i v-if="isBtnDisabled && item.id == roleActive.id" class="el-icon-loading" />
        </li>
      </ul>


      <div class="rule-view fr">
        <div class="rule-list" v-if="roleList.length > 0">
          <el-row v-for="(item, index) in actionList" :key="'menu' + item.id + index">
            <el-col v-if="item.children && item.children.length > 0" class="ffff" :span="24">
              <div class="ftitle">
                <span>{{ item.menu_name }}</span>
              </div>
              <div class="fbody">
                <div
                  class="fbody-item"
                  v-for="(subItem, subIndex) in item.children"
                  :key="'yemian' + subItem.id + subIndex"
                >
                  <template
                    v-if="
                      !(
                        subItem.action &&
                        subItem.action.length === 0 &&
                        subItem.action_data &&
                        subItem.action_data.length === 0
                      )
                    "
                  >
                    <div class="stitle">
                      <span class="_h2">{{ subItem.menu_name }}</span>
                      <el-radio-group
                        style="margin: 0 0 0 20px"
                        size="mini"
                        v-if="subItem && subItem.private && subItem.private.length === 2"
                        v-model="subItem.is_private_change"
                      >
                        <el-radio-button
                          v-for="(radioN, ri) in subItem.private"
                          :key="radioN.label + ri"
                          :label="String(radioN.id)"
                          >{{ radioN.label }}</el-radio-button
                        >
                      </el-radio-group>
                    </div>
                    <div
                      class="scheck"
                      v-if="subItem.action && subItem.action.length > 0"
                    >
                      <div class="checkAll">
                        <el-checkbox
                          v-model="subItem.checkAll"
                          :disabled="!powers.some((i) => i == '001')"
                          :indeterminate="indeterminateCheck(subItem)"
                          @change="handleCheckAllChange($event, index, item, subIndex)"
                          >功能全选</el-checkbox
                        >
                      </div>
                      <div class="checkItem">
                        <el-checkbox-group
                          v-model="subItem.checkList"
                          :disabled="!powers.some((i) => i == '001')"
                          @change="
                            handleCheckedGroupChange($event, index, item, subIndex)
                          "
                        >
                          <template v-for="children in subItem.action">
                            <el-checkbox
                              :disabled="!powers.some((i) => i == '001')"
                              :label="String(children.id)"
                              :key="'checkItem' + children.id"
                              @change="
                                handleCheckedChange(
                                  $event,
                                  String(children.id),
                                  index,
                                  subIndex,
                                  item
                                )
                              "
                              >{{ children.action_name }}</el-checkbox
                            >
                          </template>
                        </el-checkbox-group>
                      </div>
                    </div>
                    <div
                      class="sfield"
                      v-if="subItem.action_data && subItem.action_data.length > 0"
                    >
                      <div class="checkAll">
                        <el-checkbox
                          v-model="subItem.fieldAll"
                          :disabled="!powers.some((i) => i == '001')"
                          :indeterminate="indeterminateField(subItem)"
                          @change="handleFieldAllChange($event, index, item, subIndex)"
                          >字段全选</el-checkbox
                        >
                      </div>
                      <div class="checkItem">
                        <el-checkbox-group
                          v-model="subItem.fieldList"
                          :disabled="!powers.some((i) => i == '001')"
                          @change="handleFieldGroupChange($event, index, item, subIndex)"
                        >
                          <template v-for="children in subItem.action_data">
                            <el-checkbox
                              :label="String(children.id)"
                              :disabled="!powers.some((i) => i == '001')"
                              :key="'FieldItem' + children.id"
                              @change="
                                handleFieldChange(
                                  $event,
                                  String(children.id),
                                  index,
                                  subIndex,
                                  item
                                )
                              "
                              >{{ children.field_name }}</el-checkbox
                            >
                          </template>
                        </el-checkbox-group>
                      </div>
                    </div>
                  </template>
                </div>
              </div>
            </el-col>
          </el-row>
        </div>

        <p
          v-else
          style="line-height: 60px;margin-top: 50px ;text-align: center; color: #909399"
        >
          暂无数据
        </p>
      </div>

      <div class="rule-bottom fr" v-if="roleList.length > 0">
        <el-button
          size="small"
          type="primary"
          v-if="powers.some((i) => i == '001')"
          :disabled="isBtnDisabled"
          @click="save()"
          >提 交</el-button
        >
      </div>
    </div>

    <div v-else>
      <no-auth></no-auth>
    </div>
  </div>
</template>
<script>
import asyncRequest from "@/apis/service/system/action";
import resToken from "@/mixins/resToken";

export default {
  name: "Action",
  mixins: [resToken],
  data() {
    return {
      ruleForm: {},
      // 按钮是否可点击
      isBtnDisabled: true,
      // 当前角色
      roleActive: {},
      actionChange: [],
      // 角色列表
      roleList: [],
      rules: [],
      // 功能权限列表
      actionList: [],
      action_data: [], // 字段数据
      action: [], // 功能数据
      private_data: [], //私有数据菜单ID
      private_field: [],
      loading:false
    };
  },
  computed: {
    powers() {
      const tran =
        this.$store.getters.btnList.find((i) => i.menu_route == "action") || {};
      const { action } = tran ?? {};
      return action ?? [];
    },
    indeterminateCheck() {
      return (item) => {
        // 选中子节点的数量
        const selectItemLength = item.action.filter(
          (filitem) =>
            item.checkList.findIndex((finditem) => finditem === String(filitem.id)) > -1
        ).length;
        // 未选中子节点的数量
        const noSlectItemLength = item.action.filter(
          (filitem) =>
            item.checkList.findIndex((finditem) => finditem === String(filitem.id)) == -1
        ).length;
        // // 当前节点的index
        // 存在选中子节点且存在未选中子节点为中间态
        return selectItemLength > 0 && noSlectItemLength > 0;
      };
    },
    indeterminateField() {
      return (item) => {
        // 选中子节点的数量
        const selectItemLength = item.action_data.filter(
          (filitem) =>
            item.fieldList.findIndex((finditem) => finditem === filitem.id) > -1
        ).length;
        // 未选中子节点的数量
        const noSlectItemLength = item.action_data.filter(
          (filitem) =>
            item.fieldList.findIndex((finditem) => finditem === filitem.id) == -1
        ).length;
        // // 当前节点的index
        // 存在选中子节点且存在未选中子节点为中间态
        return selectItemLength > 0 && noSlectItemLength > 0;
      };
    },
  },
  mounted() {
    this.initactionList();
  },

  methods: {
    recursionFilterActionList(list) {
      const _list = []
      for (let i = 0; i < list.length; i++) {
        const item = list[i]

        if (item.level !== 1) _list.push(item)
        if (item.children && item.children.length > 0) item.children = this.recursionFilterActionList(item.children)
      }
      return _list
    },
    // 全选/全不选
    handleCheckAllChange(checkAll, index, item, subIndex) {
      this.actionList[index].children[subIndex].checkAll = checkAll;
      this.$set(this.actionList, index, item);
      this.actionList[index].children[subIndex].action.forEach((element) => {
        const findindex = this.actionList[index].children[subIndex].checkList.findIndex(
          (findItem) => findItem === String(element.id)
        );
        if (checkAll && findindex == -1) {
          this.actionList[index].children[subIndex].checkList.push(String(element.id));
        } else if (!checkAll && findindex > -1) {
          this.actionList[index].children[subIndex].checkList.splice(findindex, 1);
        }
      });
    },
    // 全选/全不选
    handleFieldAllChange(fieldAll, index, item, subIndex) {
      this.actionList[index].children[subIndex].fieldAll = fieldAll;
      this.$set(this.actionList, index, item);
      this.actionList[index].children[subIndex].action_data.forEach((element) => {
        const findindex = this.actionList[index].children[subIndex].fieldList.findIndex(
          (findItem) => findItem === String(element.id)
        );
        if (fieldAll && findindex == -1) {
          this.actionList[index].children[subIndex].fieldList.push(String(element.id));
        } else if (!fieldAll && findindex > -1) {
          this.actionList[index].children[subIndex].fieldList.splice(findindex, 1);
        }
      });
    },
    // 复选框组内的选中/不选中
    handleCheckedGroupChange(event, index, item, subIndex) {
      // console.log(event, index, subIndex);
      this.actionList[index].children[subIndex].checkAll = this.actionList[index].children[
        subIndex
      ].action.every(
        (evitem) =>
          this.actionList[index].children[subIndex].checkList.findIndex(
            (finditem) => finditem === String(evitem.id)
          ) > -1
      );
      this.$set(this.actionList, index, item);
    },
    // 复选框组内的选中/不选中
    handleFieldGroupChange(event, index, item, subIndex) {
      this.actionList[index].children[subIndex].fieldAll = this.actionList[index].children[
        subIndex
      ].action_data.every(
        (evitem) =>
          this.actionList[index].children[subIndex].fieldList.findIndex(
            (finditem) => finditem === String(evitem.id)
          ) > -1
      );
      this.$set(this.actionList, index, item);
    },

    // 单项复选框选中/不选中

    handleCheckedChange(checked, id, index, subIndex, item) {
      // console.log(checked, id, index, subIndex);
      if (checked) {
        // 选中时检查pid的选中状态
        this.actionList[index].children[subIndex].checkList.indexOf(String(id)) == -1 &&
          this.actionList[index].children[subIndex].checkList.push(String(id));
      } else {
        const find = this.actionList[index].children[subIndex].checkList.findIndex(
          (e) => e == id
        );
        if (find > -1) {
          this.actionList[index].children[subIndex].checkList.splice(find, 1);
        }
        this.actionList[index].children[subIndex].checkAll = false;
      }
      this.$set(this.actionList, index, item);
      // console.log(this.actionList[index].children[subIndex]);
    },
    // 单项复选框选中/不选中
    handleFieldChange(checked, id, index, subIndex, item) {
      // console.log(checked, id, index, subIndex);
      if (checked) {
        // 选中时检查pid的选中状态
        this.actionList[index].children[subIndex].fieldList.indexOf(String(id)) == -1 &&
          this.actionList[index].children[subIndex].fieldList.push(String(id));
      } else {
        const find = this.actionList[index].children[subIndex].fieldList.findIndex(
          (e) => e == id
        );
        if (find > -1) {
          this.actionList[index].children[subIndex].fieldList.splice(find, 1);
        }
        this.actionList[index].children[subIndex].fieldAll = false;
      }
      this.$set(this.actionList, index, item);
      // console.log(this.actionList[index].children[subIndex]);
    },
    // 切换角色
    switchRoleHandle(item) {
      this.roleActive = Object.assign({}, item);
      this.$nextTick(async () => {
        await this.refreshRoleDetail(String(item.id));
      });
    },
    // 保存
    async save() {
      this.action_data = []; // 字段数据
      this.action = []; // 功能数据
      let arr = [];
      this.actionList.forEach((x) => {
        x.children.forEach((y) => {
          this.action_data.push(...y.fieldList);
          this.action.push(...y.checkList);
          if (String(y.is_private_change) === "1") {
            arr.push(String(y.id));
          }
        });
      });

      // this.action_data.length === 0 || 和字段
      if (this.action.length === 0) {
        this.$message.warning("请选择功能!");
      } else {
        const model = {
          role_id: this.roleActive.id,
          action: this.action,
        };

        const loadding = this.$loading();
        const res = await asyncRequest.update(model);
        if (res && res.code === 1) {
          this.$notify.success({
            title: "保存成功！",
            message: "",
          });
        }
        loadding.close();
      }
    },
    // 刷新角色详情
    async refreshRoleDetail(roleid) {
      this.isBtnDisabled = true;

      const res = await asyncRequest.detail({ role_id: roleid });

      if (res && res.code === 1 && res.data) {
        let resD = res.data
        this.action = Array.isArray(res.data) ? res.data : res.data.action
        this.ruleForm = resD;
        this.refreshRoleCheckAllStatus();
      } 

      console.log(this.isBtnDisabled)

      this.isBtnDisabled = false;
    },
    // 初始化功能权限列表
    async initactionList() {
      this.loading = true
      const res = await asyncRequest.actionList({});
      if (res && res.code === 1 && res.data) {
        this.rules = this.recursionFilterActionList(res.data);
        await this.initRoleList();
      }

      this.loading = false;
    },
    // 初始化角色列表
    async initRoleList() {
      const res = await asyncRequest.getRole({});
      if (res && res.code === 1 && res.data) {
        this.roleList = [].concat(res.data);
        if (this.roleList.length > 0) {
          await this.switchRoleHandle(this.roleList[0]);
        }
      }
    },
    // 刷新选择状态
    refreshRoleCheckAllStatus() {
      const list = JSON.parse(JSON.stringify(this.rules));
      let arr = list.filter((item) => item.children && item.children.length > 0);
      arr = arr.map((x) => {
        x.children.map((y) => {
          y.checkAll = false;
          y.checkList = [];
          y.fieldAll = false;
          y.fieldList = [];
          y.is_private_change = "0";
          if (String(y.is_private) === "0") {
            y.private = [];
          } else {
            y.private = [
              {
                id: "0",
                label: "公有数据",
              },
              {
                id: "1",
                label: "私有数据",
              },
            ];
          }
          return y;
        });
        return x;
      });
      this.actionList = arr;
      this.actionList.forEach((x, xi) => {
        if (x.children && x.children.length > 0) {
          x.children.forEach((y, yi) => {
            let id = y.id;
            if (y.action && y.action.length > 0) {
              y.action.forEach((z) => {
                const Aindex = this.action.findIndex((a) => String(a) === String(z.id));
                if (Aindex !== -1) {
                  y.checkList.push(this.action[Aindex]);
                }
                if (y.action.length === y.checkList.length) {
                  y.checkAll = true;
                }
              });
            }
            if (y.action_data && y.action_data.length > 0) {
              y.action_data.map((z) => {
                const Bindex = this.action_data.findIndex((a) => String(a) === String(z.id));
                if (Bindex !== -1) {
                  y.fieldList.push(this.action_data[Bindex]);
                }
              });
              if (y.action_data.length === y.fieldList.length) {
                y.fieldAll = true;
              }
            }
            if (y.private && y.private.length === 2) {
              let Cindex = this.private_data.findIndex((a) => String(a) === String(y.id));
              if (Cindex !== -1) {
                y.is_private_change = "1";
              } else {
                y.is_private_change = "0";
              }
            } else {
              y.is_private_change = "0";
            }
          });
        }

        console.log(this.actionList)
        this.$set(this.actionList, xi, x);
      });
    },
  },
};
</script>
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
.action {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;

  .action_show_box {
    // position: relative;
    // height: calc(100% - 50px);
    // min-height: calc(100% - 50px);

    display: relative;
    width: 100%;
    height: calc(100vh - 50px);
    overflow: hidden;
    text-align: left;
    //左侧
    .role-list {
      height: 100%;
      overflow-y: auto;
      width: 200px;
      padding: 8px 16px;
      min-height: 100%;
      flex-shrink: 0;
      border-right: 2px solid #dfe6ec;
      @include scrollBar();
      &::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        height: 100%;
        width: 2px;
        background-color: #e4e7ed;
        z-index: 1;
      }
      .role-list__title {
        color: #b4b6c0;
        line-height: 32px;
      }
      .role-list__item {
        position: relative;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        height: 32px;
        line-height: 32px;
        padding-left: 8px;
        color: rgb(48, 49, 51);
        cursor: pointer;
        i {
          position: absolute;
          right: 0;
          line-height: 32px;
        }
      }
      .role-list__item.active {
        color: #6954f0;
        background: #f7f7f7;
      }
    }
    //右侧
    .rule-view {
      height: calc(100% - 50px);
      width: calc(100% - 200px);
      overflow-y: auto;
      @include scrollBar();
      // padding: 0 0 0 16px;
      .ffff {
        width: 100%;
        display: flex;
        align-items: stretch;
        .ftitle {
          width: 110px;
          text-align: center;
          border-right: 1px solid #dfe6ec;
          border-bottom: 1px solid #dfe6ec;
          padding: 12px 14px;
          display: flex;
          align-items: center;
          span {
            display: inline-block;
            width: 100%;
            font-size: 17px;
            text-align: center;
            color: #97a8be;
          }
        }
        .fbody {
          width: calc(100% - 110px);
          .fbody-item {
            border-right: 1px solid #dfe6ec;
            border-bottom: 1px solid #dfe6ec;

            .stitle {
              padding: 18px 18px 12px 18px;
              border-bottom: 1px dashed #dfe6ec;
              font-size: 14px;
              color: #97a8be;
              ._h2 {
                display: inline-block;
                // width: 100px;
              }
            }
            .scheck {
              padding: 15px 0 10px 0;
              display: flex;
              width: 100%;
              .checkAll {
                width: 140px;
                text-align: right;
                padding: 0 35px 0 0;
              }
              .checkItem {
                width: calc(100% - 140px);
              }
            }
            .sfield {
              padding: 0 0 10px 0;
              display: flex;
              width: 100%;
              .checkAll {
                width: 140px;
                text-align: right;
                padding: 0 35px 0 0;
              }
              .checkItem {
                width: calc(100% - 140px);
              }
            }
          }
        }
        // .rule-list {
        //   height: 100%;
        //   overflow-y: auto;
        //   padding: 0 0 80px 0;
        //   .rule-title {
        //     .title {
        //       font-size: 20px;
        //       color: #333;
        //     }
        //     .desc {
        //       margin: 10px 0;
        //       font-size: 12px;
        //       color: #999;
        //     }
        //   }
        //   .rule-item {
        //     .title {
        //       margin: 30px 30px 10px 0;
        //       font-size: 18px;
        //       padding-bottom: 12px;
        //       border-bottom: 1px solid #eee;
        //       color: #333;
        //       .el-checkbox {
        //         margin-left: 10px;
        //       }
        //     }
        //     .el-checkbox-group {
        //       margin: 10px 30px 30px 0;
        //       .el-checkbox {
        //         line-height: 30px;
        //       }
        //       .children-checkbox-hr {
        //         margin: 8px 0;
        //         border: none;
        //         border-top: 2px dotted #eee;
        //       }
        //     }
        //   }
        // }
      }
    }
    .rule-bottom {
      padding: 10px 18px 8px 0;
      background: #fff;
      width: calc(100% - 200px);
      position: absolute;
      text-align: right;
      bottom: 0;
      right: 0;
      &::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        height: 2px;
        width: 100%;
        background-color: #e4e7ed;
        z-index: 1;
      }
    }
  }
}
</style>
