<template>
  <el-dialog
    v-loading="loading"
    :title="title"
    :center="true"
    align="left"
    top="5vh"
    width="1040px"
    :close-on-click-modal="false"
    :visible.sync="showModelThis"
    element-loading-text="拼命加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0.8)"
    @close="showModelThis = false"
  >
    <el-card style="margin-top: -20px">
      <el-row :gutter="10">
        <el-form
          ref="ruleForm"
          :model="ruleForm"
          status-icon
          :size="'mini'"
          :rules="rulesThis"
          label-width="80px"
          class="demo-ruleForm"
        >
          <el-col :span="9">
            <el-form-item label="角色名称" prop="role_name">
              <el-input
                v-model="ruleForm.role_name"
                :disabled="isDetail"
                maxlength="50"
                placeholder="角色名称"
              />
            </el-form-item>
          </el-col>
          <el-col :span="9">
            <el-form-item
              label="关键字段权限"
              prop="private_field"
              label-width="110px"
            >
              <el-checkbox-group
                v-model="ruleForm.private_field"
                :disabled="isDetail"
                placeholder="关键字段权限"
              >
                <el-checkbox :label="'1'">成本价</el-checkbox>
                <el-checkbox :label="'2'">销售价</el-checkbox>
                <el-checkbox :label="'3'">毛利率</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="角色等级" prop="level">
              <el-select
                v-model="ruleForm.level"
                filterable
                :disabled="isDetail"
                placeholder="请选择角色等级"
                style="width: 100%"
              >
                <el-option
                  v-for="item in roleLevel"
                  :key="'ruleid' + item.code"
                  :label="item.name"
                  :value="item.code"
                />
              </el-select>
            </el-form-item>
          </el-col>

          <div class="quanxian-main">
            <div class="quanxian-title">
              <span style="color: #ff8888">*</span
              ><span
                style="
                  font-size: 14px;
                  color: #606266;
                  line-height: 40px;
                  padding: 0 12px 0 0;
                  font-weight: 700;
                "
                >功能权限</span
              >
            </div>
            <div class="rule-view">
              <div class="rule-list">
                <el-row
                  v-for="(item, index) in actionList"
                  :key="'menu' + item.id + index"
                >
                  <el-col
                    v-if="item.child && item.child.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.child"
                        :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"
                              :disabled="isDetail"
                              v-if="
                                subItem &&
                                subItem.private &&
                                subItem.private.length === 2
                              "
                              v-model="subItem.is_private_change"
                            >
                              <el-radio-button
                                :disabled="isDetail"
                                v-for="(radioN, ri) in subItem.private"
                                :key="radioN.label + ri"
                                :label="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="isDetail"
                                :indeterminate="indeterminateCheck(subItem)"
                                @change="
                                  handleCheckAllChange(
                                    $event,
                                    index,
                                    item,
                                    subIndex
                                  )
                                "
                                >功能全选</el-checkbox
                              >
                            </div>
                            <div class="checkItem">
                              <el-checkbox-group
                                v-model="subItem.checkList"
                                :disabled="isDetail"
                                @change="
                                  handleCheckedGroupChange(
                                    $event,
                                    index,
                                    item,
                                    subIndex
                                  )
                                "
                              >
                                <template v-for="children in subItem.action">
                                  <el-checkbox
                                    :disabled="isDetail"
                                    :key="'checkItem' + children.id"
                                    :label="children.id"
                                    @change="
                                      handleCheckedChange(
                                        $event,
                                        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="isDetail"
                                :indeterminate="indeterminateField(subItem)"
                                @change="
                                  handleFieldAllChange(
                                    $event,
                                    index,
                                    item,
                                    subIndex
                                  )
                                "
                                >字段全选</el-checkbox
                              >
                            </div>
                            <div class="checkItem">
                              <el-checkbox-group
                                v-model="subItem.fieldList"
                                :disabled="isDetail"
                                @change="
                                  handleFieldGroupChange(
                                    $event,
                                    index,
                                    item,
                                    subIndex
                                  )
                                "
                              >
                                <template
                                  v-for="children in subItem.action_data"
                                >
                                  <el-checkbox
                                    :key="'FieldItem' + children.id"
                                    :label="children.id"
                                    :disabled="isDetail"
                                    @change="
                                      handleFieldChange(
                                        $event,
                                        children.id,
                                        index,
                                        subIndex,
                                        item
                                      )
                                    "
                                    >{{ children.field_name }}</el-checkbox
                                  >
                                </template>
                              </el-checkbox-group>
                            </div>
                          </div>
                        </template>
                      </div>
                    </div>
                  </el-col>
                </el-row>
              </div>
            </div>
          </div>
        </el-form>
        <el-col :span="24" style="text-align: right">
          <el-button
            v-if="!isDetail"
            type="primary"
            :size="'mini'"
            @click="submitForm"
            >保 存
          </el-button>
          <el-button @click="showModelThis = false" :size="'mini'">{{
            isDetail ? "关 闭" : "取 消"
          }}</el-button>
        </el-col>
      </el-row>
    </el-card>
  </el-dialog>
</template>
<script>
import asyncRequest from "@/apis/service/interest/role";
import roleLevel from "@/assets/js/roleLevel";
import { isChinese, isEmoticon } from "@/utils/validate";
import resToken from "@/mixins/resToken";
export default {
  name: "Role",
  props: ["showModel", "id", "isDetail"],
  mixins: [resToken],
  data() {
    const validatename = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("角色名称不能为空！"));
      } else {
        if (value.lenght < 2 || value.lenght > 10) {
          callback(new Error("角色名称规则为2~10位汉字！"));
        } else if (!isChinese(value)) {
          callback(new Error("角色名称规则为2~10位汉字！"));
        } else if (isEmoticon(value)) {
          callback(new Error("角色名称规则为2~10位汉字！"));
        } else {
          callback();
        }
      }
    };
    return {
      loading: false,
      title: "添加角色",
      private_data: [], //私有数据菜单ID
      showModelThis: this.showModel,
      roleLevel: roleLevel,
      ruleForm: {
        role_name: "",
        level: "1",
        private_field: [],
      },
      action_data: [], // 字段数据
      action: [], // 功能数据
      // 当前角色
      roleActive: {
        rules: [],
      },
      // 角色列表
      roleList: [],
      // 功能权限列表
      ruleList: [],
      dataList: [],
      actionList: [],
      rulesThis: this.rules,
      rules: {
        private_field: [
          {
            type: "array",
            required: true,
            message: "请选择关键字段权限",
            trigger: "change",
          },
        ],
        role_name: [
          {
            required: true,
            validator: validatename,
            trigger: "blur",
          },
        ],
        level: [
          { required: true, message: "请选择角色等级", trigger: "change" },
        ],
      },
    };
  },
  computed: {
    indeterminateCheck() {
      return (item) => {
        // 选中子节点的数量
        const selectItemLength = item.action.filter(
          (filitem) =>
            item.checkList.findIndex((finditem) => finditem === filitem.id) > -1
        ).length;
        // 未选中子节点的数量
        const noSlectItemLength = item.action.filter(
          (filitem) =>
            item.checkList.findIndex((finditem) => finditem === 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;
      };
    },
  },
  watch: {
    showModel: function (val) {
      this.showModelThis = val;
      if (val) {
        this.initForm();
      }
    },
    showModelThis(val) {
      if (!val) {
        this.$emit("cancel");
      }
    },
  },
  methods: {
    // 全选/全不选
    handleCheckAllChange(checkAll, index, item, subIndex) {
      this.actionList[index].child[subIndex].checkAll = checkAll;
      this.$set(this.actionList, index, item);
      this.actionList[index].child[subIndex].action.forEach((element) => {
        const findindex = this.actionList[index].child[
          subIndex
        ].checkList.findIndex((findItem) => findItem === element.id);
        if (checkAll && findindex == -1) {
          this.actionList[index].child[subIndex].checkList.push(element.id);
        } else if (!checkAll && findindex > -1) {
          this.actionList[index].child[subIndex].checkList.splice(findindex, 1);
        }
      });
    },
    // 全选/全不选
    handleFieldAllChange(fieldAll, index, item, subIndex) {
      this.actionList[index].child[subIndex].fieldAll = fieldAll;
      this.$set(this.actionList, index, item);
      this.actionList[index].child[subIndex].action_data.forEach((element) => {
        const findindex = this.actionList[index].child[
          subIndex
        ].fieldList.findIndex((findItem) => findItem === element.id);
        if (fieldAll && findindex == -1) {
          this.actionList[index].child[subIndex].fieldList.push(element.id);
        } else if (!fieldAll && findindex > -1) {
          this.actionList[index].child[subIndex].fieldList.splice(findindex, 1);
        }
      });
    },
    // 复选框组内的选中/不选中
    handleCheckedGroupChange(event, index, item, subIndex) {
      this.actionList[index].child[subIndex].checkAll = this.actionList[
        index
      ].child[subIndex].action.every(
        (evitem) =>
          this.actionList[index].child[subIndex].checkList.findIndex(
            (finditem) => finditem === evitem.id
          ) > -1
      );
      this.$set(this.actionList, index, item);
    },
    // 复选框组内的选中/不选中
    handleFieldGroupChange(event, index, item, subIndex) {
      this.actionList[index].child[subIndex].fieldAll = this.actionList[
        index
      ].child[subIndex].action_data.every(
        (evitem) =>
          this.actionList[index].child[subIndex].fieldList.findIndex(
            (finditem) => finditem === 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].child[subIndex].checkList.indexOf(id) == -1 &&
          this.actionList[index].child[subIndex].checkList.push(id);
      } else {
        const find = this.actionList[index].child[subIndex].checkList.findIndex(
          (e) => e == id
        );
        if (find > -1) {
          this.actionList[index].child[subIndex].checkList.splice(find, 1);
        }
        this.actionList[index].child[subIndex].checkAll = false;
      }
      this.$set(this.actionList, index, item);
    },
    // 单项复选框选中/不选中
    handleFieldChange(checked, id, index, subIndex, item) {
      // console.log(checked, id, index, subIndex);
      if (checked) {
        // 选中时检查pid的选中状态
        this.actionList[index].child[subIndex].fieldList.indexOf(id) == -1 &&
          this.actionList[index].child[subIndex].fieldList.push(id);
      } else {
        const find = this.actionList[index].child[subIndex].fieldList.findIndex(
          (e) => e == id
        );
        if (find > -1) {
          this.actionList[index].child[subIndex].fieldList.splice(find, 1);
        }
        this.actionList[index].child[subIndex].fieldAll = false;
      }
      this.$set(this.actionList, index, item);
      // console.log(this.actionList[index].child[subIndex]);
    },

    async initForm() {
      this.loading = true;
      if (this.id === "add") {
        this.title = "添加角色";
        // this.ruleForm.isAdmin = 0;
        this.rulesThis = this.rules;
        await this.resetForm();
        await this.initActionList();
        this.loading = false;
      } else {
        if (this.isDetail) {
          this.title = "角色";
          this.rulesThis = {};
        } else {
          this.title = "修改角色";
          this.rulesThis = this.rules;
        }
        await this.resetForm();
        await this.initActionList();
        await this.initData();
        this.loading = false;
      }
    },
    async initData() {
      const res = await asyncRequest.detail({ roleid: this.id });
      if (res && res.code === 0 && res.data) {
        let resD = res.data;
        resD.private_field =
          resD.private_field === "" ? [] : resD.private_field;
        this.ruleForm = resD;

        if (resD.action && resD.action.length > 0) {
          this.action = resD.action;
        } else {
          this.action = [];
        }
        if (resD.action_data && resD.action_data.length > 0) {
          this.action_data = resD.action_data;
        } else {
          this.action_data = [];
        }
        if (resD.private_data === "") {
          resD.private_data = [];
        }
        if (resD.private_data && resD.private_data.length > 0) {
          this.private_data = resD.private_data;
        } else {
          this.private_data = [];
        }
        const arr = JSON.parse(JSON.stringify(this.actionList));
        arr.map((x) => {
          if (x.child && x.child.length > 0) {
            x.child.map((y) => {
              if (y.action && y.action.length > 0) {
                y.action.map((z) => {
                  const Aindex = this.action.findIndex((a) => a === z.id);
                  if (Aindex !== -1) {
                    y.checkList.push(this.action[Aindex]);
                  }
                  return z;
                });
                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) => a === z.id);
                  if (Bindex !== -1) {
                    y.fieldList.push(this.action_data[Bindex]);
                  }
                  return z;
                });
                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) => a === y.id);
                if (Cindex !== -1) {
                  y.is_private_change = "1";
                } else {
                  y.is_private_change = "0";
                }
              } else {
                y.is_private_change = "0";
              }
              return y;
            });
          }
          return x;
        });

        this.actionList = arr;
      } else if (res && res.code >= 100 && res.code <= 104) {
        await this.logout();
      } else {
        this.$message.warning(res.message);
      }
    },
    async initActionList() {
      const res = await asyncRequest.actionList({});
      if (res && res.code === 0) {
        const list = res.data;
        let arr = list.filter((item) => item.child && item.child.length > 0);
        arr = arr.map((x) => {
          x.child.map((y) => {
            y.checkAll = false;
            y.checkList = [];
            y.fieldAll = false;
            y.fieldList = [];
            y.is_private_change = "0";
            if (y.is_private === "0") {
              y.private = [];
            } else {
              y.private = [
                {
                  id: "0",
                  label: "公有数据",
                },
                {
                  id: "1",
                  label: "私有数据",
                },
              ];
            }
            return y;
          });
          return x;
        });

        this.actionList = arr;
      } else if (res && res.code >= 100 && res.code <= 104) {
        await this.logout();
      } else {
        this.$message.warning(res.message);
      }
    },
    async resetForm() {
      // 重置
      await this.$nextTick(() => {
        if (this.$refs.ruleForm) {
          this.$refs.ruleForm.resetFields();
          this.$refs.ruleForm.clearValidate();
          this.ruleForm = {
            role_name: "",
            private_field: [],
            level: "1",
          };
        }
      });
    },
    async submitForm() {
      await this.$refs.ruleForm.validate(async (valid) => {
        if (valid) {
          if (this.loading) {
            return;
          }
          this.action_data = []; // 字段数据
          this.action = []; // 功能数据
          let arr = [];
          this.actionList.forEach((x) => {
            x.child.forEach((y) => {
              this.action_data.push(...y.fieldList);
              this.action.push(...y.checkList);
              if (y.is_private_change === "1") {
                arr.push(y.id);
              }
            });
          });
          // this.action_data.length === 0 ||和字段
          if (this.action.length === 0) {
            this.$message.warning("请选择功能!");
          } else {
            this.loading = true;
            const model = {
              roleid: this.id,
              role_name: this.ruleForm.role_name,
              private_field: JSON.parse(
                JSON.stringify(this.ruleForm.private_field)
              ),
              level: this.ruleForm.level,
              action: this.action,
              action_data: this.action_data,
              private_data: arr,
            };
            console.log(this.ruleForm.private_field);
            console.log(model);
            let res = {};
            if (this.id === "add") {
              delete model["roleid"];
              res = await asyncRequest.add(model);
            } else {
              res = await asyncRequest.update(model);
            }
            this.loading = false;
            if (res && res.code === 0) {
              const title = this.id === "add" ? "添加成功" : "修改成功";
              this.$notify.success({
                title,
                message: "",
              });
              this.showModelThis = false;
              // 刷新
              this.$emit("refresh");
            } else if (res && res.code >= 100 && res.code <= 104) {
              await this.logout();
            } else {
              this.$message.warning(res.message);
            }
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
  },
};
</script>

   <style lang="scss" scoped>
.role {
  .quanxian-main {
    width: 100%;
    display: flex;
    .quanxian-title {
      width: 84px;
      position: relative;
      padding: 8px 0 0 7px;
    }

    .rule-view {
      width: calc(100% - 84px);
      position: relative;
      height: 550px;
      overflow-y: scroll;
      border-top: 1px solid #dfe6ec;
      border-left: 1px solid #dfe6ec;
      // 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;
      //       }
      //     }
      //   }
      // }
    }
  }
}
</style>
