<template>
  <div class="user">
    <div class="tree">
      <div class="treeList">
        <div class="title commons-title">
          组织架构
        </div>
        <div class="search">
          <el-input v-model="search" placeholder="请输入搜索内容" clearable @clear="search = ''" @keyup.enter="searchChange"></el-input>
        </div>
        <div class="box">
          <el-tree :data="treeData" ref="tree" node-key="deptId" @node-click="treeChange" default-expand-all :expand-on-click-node="false"
                   :filter-node-method="filterNode">
            <template #default="{ node, data }">
              <div>{{data.deptName}}</div>
            </template>
          </el-tree>
        </div>
      </div>
    </div>
    <div class="content">
      <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row :action-list="[
        {
          text: '添加用户',
          action: () => openModal(),
        },
      ]" @get-list="getList">
        <template #deptName="{ item }">
          <div style="width: 100%">
            <span v-for="(name,index) in item.deptNameList" :key="index">
              {{name}}
              <span v-if="index < item.deptNameList.length-1">=></span>
            </span>
          </div>
        </template>

        <template #status="{item}">
          <div style="width:100%">
            <span :style="{color:item.status==1?'red':''}">{{item.status==1?'停用':'启用'}}</span>
          </div>
        </template>

      </byTable>
    </div>

    <el-dialog :title="modalType == 'add' ? '添加用户' : '编辑用户'" v-if="dialogVisible" v-model="dialogVisible" width="50%" v-loading="loadingDialog">
      <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
        <template #deptId>
          <div style="width: 100%">
            <el-tree-select v-model="formData.data.deptId" :data="deptList" check-strictly :render-after-expand="false" node-key="deptId"
                            :props="defaultProps" style="width:100%" @change="handleDeptIdChange" />
          </div>
        </template>
        <template #account>
          <el-input style="width: 42%; margin-right: 10px" v-model="formData.data.userName" @change="changeUserName" placeholder="请输入用户名"></el-input>
          <el-input style="width: 42%; margin-right: 10px" v-model="formData.data.password" @change="changePassword" placeholder="密码"></el-input>
          <span style="color: #409eff; cursor: pointer" @click="newPassword">随机生成</span>
        </template>

        <template #purchaseScope>
          <div style="width:100%">
            <el-tree :data="productTreeData" show-checkbox node-key="id" :default-checked-keys="formData.data.purchaseRangeOne"
                     :props="defaultPropsOne" ref="productTree">
            </el-tree>
          </div>
        </template>

        <template #detail>
          <div style="width:100%;padding-left:25px">
            <el-button type="primary" @click="handleAdd()" plain style="margin-bottom: 16px">添加</el-button>
            <el-table :data="formData.data.identityList" style="width: 100%;">
              <el-table-column label="职级" prop="identity">
                <template #default="{ row, $index }">
                  <div style="width: 100%">
                    <el-form-item :prop="'identityList.' + $index + '.identity'" :rules="rules.identity" :inline-message="true"
                                  class="margin-b-0 wid100">
                      <el-select v-model="row.identity" placeholder="请选择" style="width: 100%">
                        <el-option v-for="item in rankData" :key="item.value" :label="item.label" :value="item.value" />
                      </el-select>
                    </el-form-item>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="部门" prop="deptId">
                <template #default="{ row, $index }">
                  <div style="width: 100%">
                    <el-form-item :prop="'identityList.' + $index + '.deptId'" :rules="rules.deptId" :inline-message="true" class="margin-b-0 wid100">
                      <el-tree-select v-model="row.deptId" :data="deptListOne" check-strictly :render-after-expand="false" node-key="deptId"
                                      :props="defaultProps" style="width:100%" />
                    </el-form-item>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="60" align="center" fixed="right">
                <template #default="{ $index }">
                  <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </template>

      </byForm>
      <template #footer>
        <el-button @click="dialogVisible = false" size="default">取 消</el-button>
        <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
      </template>
    </el-dialog>

    <el-dialog title="修改密码" v-if="roomDialogVisible" v-model="roomDialogVisible" width="500" v-loading="loading">
      <div>
        <el-input v-model="password" placeholder="请输入新密码" @change="changePassword2" />
      </div>
      <template #footer>
        <el-button @click="roomDialogVisible = false" size="default">取 消</el-button>
        <el-button type="primary" @click="submitPassword(password)" size="default" :loading="submitLoading">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, ref } from "vue";
import byTable from "@/components/byTable/index";
import { ElMessage, ElMessageBox } from "element-plus";
import byForm from "@/components/byForm/index";
import useUserStore from "@/store/modules/user";

const { proxy } = getCurrentInstance();

const defaultProps = {
  children: "children",
  label: "deptName",
  disabled: "disabled",
};
const defaultPropsOne = {
  children: "children",
  label: "name",
};
const deptList = ref([]);
const deptListOne = ref([]);
const rankData = ref([
  {
    label: "员工",
    value: 10,
  },
  {
    label: "主管",
    value: 20,
  },
  {
    label: "经理",
    value: 30,
  },
  {
    label: "总监",
    value: 40,
  },
]);
const sourceList = ref({
  data: [],
  pagination: {
    total: 0,
    pageNum: 1,
    pageSize: 10,
    keyword: "",
    tenantId: proxy.useUserStore().user.tenantId,
    deptId: "",
  },
});
const loading = ref(false);
const config = computed(() => {
  return [
    {
      attrs: {
        label: "部门",
        prop: "deptName",
        slot: "deptName",
        "min-width": 150,
      },
    },
    {
      attrs: {
        label: "姓名",
        prop: "nickName",
        align: "left",
        width: 120,
      },
    },
    // {
    //   attrs: {
    //     label: "英文名",
    //     prop: "nickNameEn",
    //     align: "left",
    //     width: 150,
    //   },
    // },
    {
      attrs: {
        label: "用户名",
        prop: "userName",
        width: 120,
      },
    },
    {
      attrs: {
        label: "系统用户",
        prop: "userType",
        width: 100,
      },
      render(userType) {
        return userType == 1 ? "是" : "否";
      },
    },
    {
      attrs: {
        label: "账号状态",
        prop: "status",
        slot: "status",
        width: 100,
      },
      render(status) {
        return status == 1 ? "停用" : "启用";
      },
    },
    {
      attrs: {
        label: "手机号",
        prop: "phonenumber",
        width: 180,
      },
    },
    {
      attrs: {
        label: "工号",
        prop: "jobNumber",
        width: 120,
      },
    },
    {
      attrs: {
        label: "操作",
        width: "180",
        align: "center",
      },
      renderHTML(row) {
        return [
          {
            attrs: {
              label: "修改密码",
              type: "primary",
              text: true,
            },
            el: "button",
            click() {
              userId.value = row.userId;
              password.value = "";
              roomDialogVisible.value = true;
            },
          },
          {
            attrs: {
              label: "修改",
              type: "primary",
              text: true,
            },
            el: "button",
            click() {
              getDtl(row);
            },
          },
          {
            attrs: {
              label: "删除",
              type: "danger",
              text: true,
            },
            el: "button",
            click() {
              ElMessageBox.confirm(
                "此操作将永久删除该数据, 是否继续?",
                "提示",
                {
                  confirmButtonText: "确定",
                  cancelButtonText: "取消",
                  type: "warning",
                }
              ).then(() => {
                proxy
                  .post(
                    "/tenantUser/" + row.userId,
                    {
                      id: row.userId,
                    },
                    "delete"
                  )
                  .then(() => {
                    ElMessage({
                      message: "删除成功",
                      type: "success",
                    });
                    getList();
                  });
              });
            },
          },
        ];
      },
    },
  ];
});

const getList = async (req) => {
  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  loading.value = true;
  proxy.get("/tenantUser/list", sourceList.value.pagination).then((res) => {
    res.rows.map((item) => {
      item.deptName = item.dept ? item.dept.deptName : item.dept;
    });
    sourceList.value.data = res.rows;
    sourceList.value.pagination.total = res.total;
    setTimeout(() => {
      loading.value = false;
    }, 200);
  });
};

getList();
const modalType = ref("add");
const dialogVisible = ref(false);
const loadingDialog = ref(false);
const roleData = ref([]);
const productTree = ref(null);
const productTreeData = ref([]);
const companyData = ref([]);
const submit = ref(null);
const isShowPurchaseAtt = ref(false);
const formOption = reactive({
  inline: true,
  labelWidth: 100,
  itemWidth: 100,
  rules: [],
});
const formData = reactive({
  data: {},
});
const formConfig = computed(() => {
  return [
    {
      type: "title1",
      title: "基本信息",
    },
    {
      type: "slot",
      prop: "deptId",
      slotName: "deptId",
      label: "部门名称",
    },
    {
      type: "input",
      prop: "nickName",
      label: "姓名",
      itemWidth: 50,
    },
    {
      type: "input",
      prop: "nickNameEn",
      label: "英文名",
      itemWidth: 50,
    },
    {
      type: "slot",
      prop: "userName",
      slotName: "account",
      label: "账户信息",
    },
    {
      type: "select",
      label: "角色",
      prop: "roleIds",
      multiple: true,
      data: roleData.value,
      fn: (val) => {
        changeRoleId(val);
      },
    },
    {
      type: "select",
      label: "关联公司",
      prop: "companySet",
      multiple: true,
      clearable: false,
      data: companyData.value,
    },
    {
      type: "radio",
      prop: "userType",
      label: "系统用户",
      required: true,
      disabled: true,
      border: true,
      data: [
        {
          label: "是",
          id: 1,
        },
        {
          label: "否",
          id: 0,
        },
      ],
      itemWidth: 50,
    },
    {
      type: "select",
      label: "账号状态",
      prop: "status",
      multiple: false,
      data: [
        {
          label: "启用",
          value: "0",
        },
        {
          label: "停用",
          value: "1",
        },
      ],
    },
    {
      type: "select",
      label: "身份",
      prop: "identity",
      multiple: false,
      data: [
        {
          label: "职员",
          value: 10,
        },
        {
          label: "股东",
          value: 20,
        },
      ],
      itemWidth: 100,
    },

    {
      type: "input",
      prop: "phonenumber",
      label: "手机号",
      required: true,
      itemWidth: 50,
      itemType: "text",
    },
    {
      type: "input",
      prop: "jobNumber",
      label: "工号",
      required: true,
      itemWidth: 50,
      itemType: "text",
    },

    {
      type: "input",
      prop: "accountBank",
      label: "开户行",
      placeholder: "请输入开户行",
      itemWidth: 100,
    },
    {
      type: "input",
      prop: "accountName",
      label: "开户名",
      placeholder: "请输入开户名",
      itemWidth: 100,
    },
    {
      type: "input",
      prop: "accountNumber",
      label: "账号",
      placeholder: "请输入账号",
      itemWidth: 100,
    },
    {
      type: "slot",
      slotName: "purchaseScope",
      label: "采购范围",
      // placeholder: "请输入账号",
      itemWidth: 100,
      isShow: isShowPurchaseAtt.value,
    },
    {
      type: "title1",
      title: "职级明细",
    },
    {
      type: "slot",
      slotName: "detail",
      label: "",
    },
  ];
});
const rules = ref({
  deptId: [{ required: true, message: "请选择部门", trigger: "change" }],
  nickName: [{ required: true, message: "请输入姓名", trigger: "blur" }],
  userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  roleIds: [{ required: true, message: "请选择角色", trigger: "change" }],
  phonenumber: [{ required: true, message: "请输入手机号", trigger: "blur" }],
  companySet: [
    { required: true, message: "请选择关联公司", trigger: "change" },
  ],
  identity: [{ required: true, message: "请选择", trigger: "change" }],
  status: [{ required: true, message: "请选择账号状态", trigger: "change" }],
});

const changeRoleId = (val) => {
  if (val && val.length > 0) {
    for (let i = 0; i < roleData.value.length; i++) {
      const role = roleData.value[i];
      for (let j = 0; j < val.length; j++) {
        const roleId = val[j];
        if (role.id == roleId) {
          if (role.label.indexOf("采购") != -1) {
            isShowPurchaseAtt.value = true;
            return;
          }
        }
      }
    }
    isShowPurchaseAtt.value = false;
  } else {
    isShowPurchaseAtt.value = false;
  }
};

const arrayRecursion = (arr, definition) => {
  arr.forEach((item) => {
    item.definition = definition;
    if (item.children && item.children.length > 0) {
      arrayRecursion(item.children, definition);
    }
  });
  return arr;
};

const allData = ref([]);
const getSubset = (list, data) => {
  for (let i = 0; i < list.length; i++) {
    if (list[i].children && list[i].children.length > 0) {
      getSubset(list[i].children, data);
    } else {
      data.push(list[i].id);
    }
  }
  return data;
};

const getUserList = () => {
  proxy
    .get(
      `/tenantRole/list?pageNum=1&pageSize=10000&tenantId=${sourceList.value.pagination.tenantId}`
    )
    .then((message) => {
      roleData.value = message.rows.map((item) => {
        return {
          ...item,
          id: item.roleId,
          label: item.roleName,
          disabled: false,
        };
      });
    });

  proxy
    .get("/tenantDept/list", {
      pageNum: 1,
      pageSize: 9999,
      keyword: "",
      tenantId: proxy.useUserStore().user.tenantId,
      type: 0,
    })
    .then((res) => {
      companyData.value = res.data.map((x) => ({
        ...x,
        label: x.deptName,
        value: x.deptId,
      }));
    });

  Promise.all([
    proxy.post("/productClassify/tree", {
      parentId: "",
      name: "",
      definition: "1",
    }),
    proxy.post("/productClassify/tree", {
      parentId: "",
      name: "",
      definition: "2",
    }),
  ]).then((res) => {
    if (res && res.length > 1) {
      res[1].forEach((x) => {
        x.id = x.id + "";
      });
      productTreeData.value = [
        {
          id: "-999",
          name: "全部",
          parentId: "",
          children: [
            {
              id: "-9",
              definition: "2",
              name: "物料",
              parentId: "-999",
              children: arrayRecursion(res[1], "2"),
            },
            {
              id: "-99",
              definition: "1",
              name: "产品",
              parentId: "-999",
              children: arrayRecursion(res[0], "1"),
            },
          ],
        },
      ];
      allData.value = getSubset(productTreeData.value, []);
    }
  });
};
getUserList();
const openModal = () => {
  roleData.value[0].disabled = false;
  modalType.value = "add";
  formData.data = {
    userType: 1,
    tenantId: proxy.useUserStore().user.tenantId,
    companySet: [],
    purchaseRange: [],
    purchaseRangeOne: [],
    identity: 10,
    identityList: [],
  };
  loadingDialog.value = false;
  dialogVisible.value = true;
};
function findNodeById(treeData, nodeId) {
  // 遍历当前层级的所有节点
  for (let i = 0; i < treeData.length; i++) {
    let node = treeData[i];
    // 如果当前节点的 ID 匹配目标节点的 ID，则返回当前节点
    if (node.deptId === nodeId) {
      return node;
    }
    // 如果当前节点有子节点，则递归调用当前函数继续查找子节点
    if (node.children && node.children.length > 0) {
      let foundNode = findNodeById(node.children, nodeId);
      // 如果在子节点中找到了目标节点，则返回找到的节点
      if (foundNode) {
        return foundNode;
      }
    }
  }
  // 如果遍历完所有节点仍未找到目标节点，则返回 null
  return null;
}

const findCompanyType = (val) => {
  const current = findNodeById(deptList.value, val);
  if (current && current.type == 0) {
    formData.data.companySet = [val];
    companyData.value = companyData.value.map((x) => ({
      ...x,
      disabled: val == x.value,
    }));
  } else {
    return findCompanyType(current.parentId);
  }
};

const handleDeptIdChange = (val) => {
  const current = findNodeById(deptList.value, val);
  if (current && current.type == 0) {
    formData.data.companySet = [val];
    companyData.value = companyData.value.map((x) => ({
      ...x,
      disabled: val == x.value,
    }));
  } else {
    findCompanyType(current.parentId);
  }
};

const noRepeat = (arr) => {
  var newArr = [...new Set(arr)];
  return newArr;
};

const submitForm = () => {
  submit.value.handleSubmit(() => {
    if (formData.data.password && formData.data.password.length < 5) {
      return ElMessage("密码长度不得低于五位");
    }
    const method = modalType.value == "add" ? "POST" : "PUT";
    if (formData.data.companySet && formData.data.companySet.length > 0) {
      formData.data.companySet = formData.data.companySet.join(",");
    }
    if (isShowPurchaseAtt.value) {
      let data = noRepeat(
        productTree.value
          .getHalfCheckedKeys()
          .concat(productTree.value.getCheckedKeys())
      );
      data = data.filter((x) => !["-999", "-99", "-9"].includes(x));
      formData.data.purchaseRange = data.join(",");
    } else {
      formData.data.purchaseRange = "";
    }
    proxy.post("/tenantUser", formData.data, method).then(() => {
      if (formData.data.password && formData.data.userId) {
        proxy
          .post(
            "/tenantUser/resetPwd",
            { password: formData.data.password, userId: formData.data.userId },
            "PUT"
          )
          .then();
      }
      ElMessage({
        message: modalType.value == "add" ? "添加成功" : "编辑成功",
        type: "success",
      });
      // 更新业务公司数据
      proxy
        .post("/tenantUser/getUserCompanyList", {
          pageNum: 1,
          pageSize: 9999,
        })
        .then((res) => {
          proxy.useUserStore().allDict["list_company_data"] = res.map((x) => ({
            ...x,
            label: x.deptName,
            value: x.deptId,
          }));
          proxy.useUserStore().allDict["tree_company_data"] = proxy.handleTree(
            res,
            "deptId"
          );
        });

      dialogVisible.value = false;
      getList();
    });
  });
};

const getDtl = (row) => {
  if (row.userId == "1") {
    roleData.value[0].disabled = true;
  } else {
    roleData.value[0].disabled = false;
  }
  companyData.value = companyData.value.map((x) => ({
    ...x,
    disabled: row.companyId == x.value,
  }));
  dialogVisible.value = true;
  proxy.get(`/tenantUser/${row.userId}`).then((res) => {
    formData.data = {
      ...row,
      userType: 1,
      roleIds: res.roleIds,
      identityList: res.data.identityList,
    };
    if (res.data && res.data.purchaseRange) {
      formData.data.purchaseRange = [];
      formData.data.purchaseRangeOne = res.data.purchaseRange.split(",");
      formData.data.purchaseRangeOne = formData.data.purchaseRangeOne.filter(
        (item) => {
          return allData.value.some((i) => item == i);
        }
      );
    } else {
      formData.data.purchaseRangeOne = [];
    }
    if (!(res.data.identityList && res.data.identityList.length > 0)) {
      formData.data.identityList = [];
    }
    changeRoleId(res.roleIds);
    let companySetData = formData.data.companySet
      ? formData.data.companySet
      : "";
    if (companySetData) {
      formData.data.companySet = [
        ...new Set((row.companyId + "," + companySetData).split(",")),
      ];
    } else {
      formData.data.companySet = row.companyId.split(",");
    }
    modalType.value = "edit";
  });
};
const newPassword = () => {
  formData.data.password = generatePassword();
};
const generatePassword = () => {
  var length = 12,
    charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
    password = "";
  for (var i = 0, n = charset.length; i < length; ++i) {
    password += charset.charAt(Math.floor(Math.random() * n));
  }
  return password;
};
const userId = ref("");
const password = ref("");
const roomDialogVisible = ref(false);
const submitPassword = (password1) => {
  if (!password1) {
    ElMessage({
      message: "请输入新密码",
      type: "warning",
    });
    return;
  }
  if (password1.length < 5) {
    return ElMessage("密码长度不得低于五位");
  }
  proxy
    .post(
      "/tenantUser/resetPwd",
      {
        password: password1,
        userId: userId.value,
      },
      "PUT"
    )
    .then(() => {
      ElMessage({
        message: "重置成功",
        type: "success",
      });
      roomDialogVisible.value = false;
      password.value = "";
    });
};
const changeUserName = (val) => {
  formData.data.userName = val.trim();
};
const changePassword = (val) => {
  formData.data.password = val.trim();
};
const changePassword2 = (val) => {
  password.value = val.trim();
};

const treeData = ref([]);
const search = ref("");
const getTreeData = () => {
  proxy
    .get("/tenantDept/list", {
      pageNum: 1,
      pageSize: 9999,
      keyword: "",
      tenantId: proxy.useUserStore().user.tenantId,
    })
    .then((res) => {
      for (let i = 0; i < res.data.length; i++) {
        if (res.data[i] && res.data[i].type == 0) {
          res.data[i].disabled = true;
        }
      }
      treeData.value = proxy.handleTree(res.data, "deptId");
      deptList.value = proxy.handleTree(res.data, "deptId");
      let newData = proxy.deepClone(res.data);
      for (let i = 0; i < newData.length; i++) {
        if (newData[i] && newData[i].type == 3) {
          newData[i].disabled = true;
        }
      }
      deptListOne.value = proxy.handleTree(newData, "deptId");
    });
};
getTreeData();

const searchChange = () => {
  proxy.$refs.tree.filter(search.value);
};

const getParents = (node, name, key) => {
  if (node.parent && node.parent.data[key]) {
    name += node.parent.data[key];
    return getParents(node.parent, name, key);
  }
  return name;
};
// 以下可实现搜索显示子节点
const filterNode = (value, data, node) => {
  let names = getParents(node, node.data.deptName, "deptName");
  let isName = names.indexOf(value) !== -1;
  return !value || isName ? true : false;
};

const treeChange = (e, data) => {
  sourceList.value.pagination.deptId = e.deptId;
  getList();
};

const handleAdd = () => {
  formData.data.identityList.push({
    identity: "",
    deptId: "",
  });
};

const handleRemove = (index) => {
  formData.data.identityList.splice(index, 1);
};
</script>

<style lang="scss" scoped>
.user {
  padding: 10px;
  display: flex;
  justify-content: space-between;
  .tree {
    width: 300px;
  }
  .content {
    width: calc(100% - 310px);
  }
}
.treeList {
  display: block;
  height: 100%;
  background: #fff;
  padding: 10px 15px 15px;
  height: calc(100vh - 122px);

  .search {
    display: flex;
    margin-bottom: 20px;
    .el-input {
      // width: calc(100% - 70px);
      margin-right: 10px;
      text-align: center;
    }
  }
  // .searh,.title,.box{
  //   padding-left:20px ;
  // }
  .box {
    padding-right: 0px;
    height: calc(100vh - 245px);
    overflow-y: auto;
    overflow-x: auto;
    .el-tree {
      // .el-tree-node__content {
      //   display: block;
      // }

      .el-tree-node > .el-tree-node__children {
        overflow: visible;
      }
    }
  }
}
</style>
