index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. <template>
  2. <div class="user">
  3. <div class="tree">
  4. <div class="treeList">
  5. <div class="title commons-title">
  6. 组织架构
  7. </div>
  8. <div class="search">
  9. <el-input v-model="search" placeholder="请输入搜索内容" clearable @clear="search = ''" @keyup.enter="searchChange"></el-input>
  10. </div>
  11. <div class="box">
  12. <el-tree :data="treeData" ref="tree" node-key="deptId" @node-click="treeChange" default-expand-all :expand-on-click-node="false"
  13. :filter-node-method="filterNode">
  14. <template #default="{ node, data }">
  15. <div>{{data.deptName}}</div>
  16. </template>
  17. </el-tree>
  18. </div>
  19. </div>
  20. </div>
  21. <div class="content">
  22. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row :action-list="[
  23. {
  24. text: '添加用户',
  25. action: () => openModal(),
  26. },
  27. ]" @get-list="getList">
  28. <template #deptName="{ item }">
  29. <div style="width: 100%">
  30. <span v-for="(name,index) in item.deptNameList" :key="index">
  31. {{name}}
  32. <span v-if="index < item.deptNameList.length-1">=></span>
  33. </span>
  34. </div>
  35. </template>
  36. <template #status="{item}">
  37. <div style="width:100%">
  38. <span :style="{color:item.status==1?'red':''}">{{item.status==1?'停用':'启用'}}</span>
  39. </div>
  40. </template>
  41. </byTable>
  42. </div>
  43. <el-dialog :title="modalType == 'add' ? '添加用户' : '编辑用户'" v-if="dialogVisible" v-model="dialogVisible" width="50%" v-loading="loadingDialog">
  44. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="submit">
  45. <template #deptId>
  46. <div style="width: 100%">
  47. <el-tree-select v-model="formData.data.deptId" :data="deptList" check-strictly :render-after-expand="false" node-key="deptId"
  48. :props="defaultProps" style="width:100%" @change="handleDeptIdChange" />
  49. </div>
  50. </template>
  51. <template #account>
  52. <el-input style="width: 42%; margin-right: 10px" v-model="formData.data.userName" @change="changeUserName" placeholder="请输入用户名"></el-input>
  53. <el-input style="width: 42%; margin-right: 10px" v-model="formData.data.password" @change="changePassword" placeholder="密码"></el-input>
  54. <span style="color: #409eff; cursor: pointer" @click="newPassword">随机生成</span>
  55. </template>
  56. <template #purchaseScope>
  57. <div style="width:100%">
  58. <el-tree :data="productTreeData" show-checkbox node-key="id" :default-checked-keys="formData.data.purchaseRangeOne"
  59. :props="defaultPropsOne" ref="productTree">
  60. </el-tree>
  61. </div>
  62. </template>
  63. <template #detail>
  64. <div style="width:100%;padding-left:25px">
  65. <el-button type="primary" @click="handleAdd()" plain style="margin-bottom: 16px">添加</el-button>
  66. <el-table :data="formData.data.identityList" style="width: 100%;">
  67. <el-table-column label="职级" prop="identity">
  68. <template #default="{ row, $index }">
  69. <div style="width: 100%">
  70. <el-form-item :prop="'identityList.' + $index + '.identity'" :rules="rules.identity" :inline-message="true"
  71. class="margin-b-0 wid100">
  72. <el-select v-model="row.identity" placeholder="请选择" style="width: 100%">
  73. <el-option v-for="item in rankData" :key="item.value" :label="item.label" :value="item.value" />
  74. </el-select>
  75. </el-form-item>
  76. </div>
  77. </template>
  78. </el-table-column>
  79. <el-table-column label="部门" prop="deptId">
  80. <template #default="{ row, $index }">
  81. <div style="width: 100%">
  82. <el-form-item :prop="'identityList.' + $index + '.deptId'" :rules="rules.deptId" :inline-message="true" class="margin-b-0 wid100">
  83. <el-tree-select v-model="row.deptId" :data="deptListOne" check-strictly :render-after-expand="false" node-key="deptId"
  84. :props="defaultProps" style="width:100%" />
  85. </el-form-item>
  86. </div>
  87. </template>
  88. </el-table-column>
  89. <el-table-column label="操作" width="60" align="center" fixed="right">
  90. <template #default="{ $index }">
  91. <el-button type="primary" link @click="handleRemove($index)">删除</el-button>
  92. </template>
  93. </el-table-column>
  94. </el-table>
  95. </div>
  96. </template>
  97. </byForm>
  98. <template #footer>
  99. <el-button @click="dialogVisible = false" size="default">取 消</el-button>
  100. <el-button type="primary" @click="submitForm()" size="default">确 定</el-button>
  101. </template>
  102. </el-dialog>
  103. <el-dialog title="修改密码" v-if="roomDialogVisible" v-model="roomDialogVisible" width="500" v-loading="loading">
  104. <div>
  105. <el-input v-model="password" placeholder="请输入新密码" @change="changePassword2" />
  106. </div>
  107. <template #footer>
  108. <el-button @click="roomDialogVisible = false" size="default">取 消</el-button>
  109. <el-button type="primary" @click="submitPassword(password)" size="default" :loading="submitLoading">确 定</el-button>
  110. </template>
  111. </el-dialog>
  112. </div>
  113. </template>
  114. <script setup>
  115. import { computed, ref } from "vue";
  116. import byTable from "@/components/byTable/index";
  117. import { ElMessage, ElMessageBox } from "element-plus";
  118. import byForm from "@/components/byForm/index";
  119. import useUserStore from "@/store/modules/user";
  120. const { proxy } = getCurrentInstance();
  121. const defaultProps = {
  122. children: "children",
  123. label: "deptName",
  124. disabled: "disabled",
  125. };
  126. const defaultPropsOne = {
  127. children: "children",
  128. label: "name",
  129. };
  130. const deptList = ref([]);
  131. const deptListOne = ref([]);
  132. const rankData = ref([
  133. {
  134. label: "员工",
  135. value: 10,
  136. },
  137. {
  138. label: "主管",
  139. value: 20,
  140. },
  141. {
  142. label: "经理",
  143. value: 30,
  144. },
  145. {
  146. label: "总监",
  147. value: 40,
  148. },
  149. ]);
  150. const sourceList = ref({
  151. data: [],
  152. pagination: {
  153. total: 0,
  154. pageNum: 1,
  155. pageSize: 10,
  156. keyword: "",
  157. tenantId: proxy.useUserStore().user.tenantId,
  158. deptId: "",
  159. },
  160. });
  161. const loading = ref(false);
  162. const config = computed(() => {
  163. return [
  164. {
  165. attrs: {
  166. label: "部门",
  167. prop: "deptName",
  168. slot: "deptName",
  169. "min-width": 150,
  170. },
  171. },
  172. {
  173. attrs: {
  174. label: "姓名",
  175. prop: "nickName",
  176. align: "left",
  177. width: 120,
  178. },
  179. },
  180. // {
  181. // attrs: {
  182. // label: "英文名",
  183. // prop: "nickNameEn",
  184. // align: "left",
  185. // width: 150,
  186. // },
  187. // },
  188. {
  189. attrs: {
  190. label: "用户名",
  191. prop: "userName",
  192. width: 120,
  193. },
  194. },
  195. {
  196. attrs: {
  197. label: "系统用户",
  198. prop: "userType",
  199. width: 100,
  200. },
  201. render(userType) {
  202. return userType == 1 ? "是" : "否";
  203. },
  204. },
  205. {
  206. attrs: {
  207. label: "账号状态",
  208. prop: "status",
  209. slot: "status",
  210. width: 100,
  211. },
  212. render(status) {
  213. return status == 1 ? "停用" : "启用";
  214. },
  215. },
  216. {
  217. attrs: {
  218. label: "手机号",
  219. prop: "phonenumber",
  220. width: 180,
  221. },
  222. },
  223. {
  224. attrs: {
  225. label: "工号",
  226. prop: "jobNumber",
  227. width: 120,
  228. },
  229. },
  230. {
  231. attrs: {
  232. label: "操作",
  233. width: "180",
  234. align: "center",
  235. },
  236. renderHTML(row) {
  237. return [
  238. {
  239. attrs: {
  240. label: "修改密码",
  241. type: "primary",
  242. text: true,
  243. },
  244. el: "button",
  245. click() {
  246. userId.value = row.userId;
  247. password.value = "";
  248. roomDialogVisible.value = true;
  249. },
  250. },
  251. {
  252. attrs: {
  253. label: "修改",
  254. type: "primary",
  255. text: true,
  256. },
  257. el: "button",
  258. click() {
  259. getDtl(row);
  260. },
  261. },
  262. {
  263. attrs: {
  264. label: "删除",
  265. type: "danger",
  266. text: true,
  267. },
  268. el: "button",
  269. click() {
  270. ElMessageBox.confirm(
  271. "此操作将永久删除该数据, 是否继续?",
  272. "提示",
  273. {
  274. confirmButtonText: "确定",
  275. cancelButtonText: "取消",
  276. type: "warning",
  277. }
  278. ).then(() => {
  279. proxy
  280. .post(
  281. "/tenantUser/" + row.userId,
  282. {
  283. id: row.userId,
  284. },
  285. "delete"
  286. )
  287. .then(() => {
  288. ElMessage({
  289. message: "删除成功",
  290. type: "success",
  291. });
  292. getList();
  293. });
  294. });
  295. },
  296. },
  297. ];
  298. },
  299. },
  300. ];
  301. });
  302. const getList = async (req) => {
  303. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  304. loading.value = true;
  305. proxy.get("/tenantUser/list", sourceList.value.pagination).then((res) => {
  306. res.rows.map((item) => {
  307. item.deptName = item.dept ? item.dept.deptName : item.dept;
  308. });
  309. sourceList.value.data = res.rows;
  310. sourceList.value.pagination.total = res.total;
  311. setTimeout(() => {
  312. loading.value = false;
  313. }, 200);
  314. });
  315. };
  316. getList();
  317. const modalType = ref("add");
  318. const dialogVisible = ref(false);
  319. const loadingDialog = ref(false);
  320. const roleData = ref([]);
  321. const productTree = ref(null);
  322. const productTreeData = ref([]);
  323. const companyData = ref([]);
  324. const submit = ref(null);
  325. const isShowPurchaseAtt = ref(false);
  326. const formOption = reactive({
  327. inline: true,
  328. labelWidth: 100,
  329. itemWidth: 100,
  330. rules: [],
  331. });
  332. const formData = reactive({
  333. data: {},
  334. });
  335. const formConfig = computed(() => {
  336. return [
  337. {
  338. type: "title1",
  339. title: "基本信息",
  340. },
  341. {
  342. type: "slot",
  343. prop: "deptId",
  344. slotName: "deptId",
  345. label: "部门名称",
  346. },
  347. {
  348. type: "input",
  349. prop: "nickName",
  350. label: "姓名",
  351. itemWidth: 50,
  352. },
  353. {
  354. type: "input",
  355. prop: "nickNameEn",
  356. label: "英文名",
  357. itemWidth: 50,
  358. },
  359. {
  360. type: "slot",
  361. prop: "userName",
  362. slotName: "account",
  363. label: "账户信息",
  364. },
  365. {
  366. type: "select",
  367. label: "角色",
  368. prop: "roleIds",
  369. multiple: true,
  370. data: roleData.value,
  371. fn: (val) => {
  372. changeRoleId(val);
  373. },
  374. },
  375. {
  376. type: "select",
  377. label: "关联公司",
  378. prop: "companySet",
  379. multiple: true,
  380. clearable: false,
  381. data: companyData.value,
  382. },
  383. {
  384. type: "radio",
  385. prop: "userType",
  386. label: "系统用户",
  387. required: true,
  388. disabled: true,
  389. border: true,
  390. data: [
  391. {
  392. label: "是",
  393. id: 1,
  394. },
  395. {
  396. label: "否",
  397. id: 0,
  398. },
  399. ],
  400. itemWidth: 50,
  401. },
  402. {
  403. type: "select",
  404. label: "账号状态",
  405. prop: "status",
  406. multiple: false,
  407. data: [
  408. {
  409. label: "启用",
  410. value: "0",
  411. },
  412. {
  413. label: "停用",
  414. value: "1",
  415. },
  416. ],
  417. },
  418. {
  419. type: "select",
  420. label: "身份",
  421. prop: "identity",
  422. multiple: false,
  423. data: [
  424. {
  425. label: "职员",
  426. value: 10,
  427. },
  428. {
  429. label: "股东",
  430. value: 20,
  431. },
  432. ],
  433. itemWidth: 100,
  434. },
  435. {
  436. type: "input",
  437. prop: "phonenumber",
  438. label: "手机号",
  439. required: true,
  440. itemWidth: 50,
  441. itemType: "text",
  442. },
  443. {
  444. type: "input",
  445. prop: "jobNumber",
  446. label: "工号",
  447. required: true,
  448. itemWidth: 50,
  449. itemType: "text",
  450. },
  451. {
  452. type: "input",
  453. prop: "accountBank",
  454. label: "开户行",
  455. placeholder: "请输入开户行",
  456. itemWidth: 100,
  457. },
  458. {
  459. type: "input",
  460. prop: "accountName",
  461. label: "开户名",
  462. placeholder: "请输入开户名",
  463. itemWidth: 100,
  464. },
  465. {
  466. type: "input",
  467. prop: "accountNumber",
  468. label: "账号",
  469. placeholder: "请输入账号",
  470. itemWidth: 100,
  471. },
  472. {
  473. type: "slot",
  474. slotName: "purchaseScope",
  475. label: "采购范围",
  476. // placeholder: "请输入账号",
  477. itemWidth: 100,
  478. isShow: isShowPurchaseAtt.value,
  479. },
  480. {
  481. type: "title1",
  482. title: "职级明细",
  483. },
  484. {
  485. type: "slot",
  486. slotName: "detail",
  487. label: "",
  488. },
  489. ];
  490. });
  491. const rules = ref({
  492. deptId: [{ required: true, message: "请选择部门", trigger: "change" }],
  493. nickName: [{ required: true, message: "请输入姓名", trigger: "blur" }],
  494. userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  495. roleIds: [{ required: true, message: "请选择角色", trigger: "change" }],
  496. phonenumber: [{ required: true, message: "请输入手机号", trigger: "blur" }],
  497. companySet: [
  498. { required: true, message: "请选择关联公司", trigger: "change" },
  499. ],
  500. identity: [{ required: true, message: "请选择", trigger: "change" }],
  501. status: [{ required: true, message: "请选择账号状态", trigger: "change" }],
  502. });
  503. const changeRoleId = (val) => {
  504. if (val && val.length > 0) {
  505. for (let i = 0; i < roleData.value.length; i++) {
  506. const role = roleData.value[i];
  507. for (let j = 0; j < val.length; j++) {
  508. const roleId = val[j];
  509. if (role.id == roleId) {
  510. if (role.label.indexOf("采购") != -1) {
  511. isShowPurchaseAtt.value = true;
  512. return;
  513. }
  514. }
  515. }
  516. }
  517. isShowPurchaseAtt.value = false;
  518. } else {
  519. isShowPurchaseAtt.value = false;
  520. }
  521. };
  522. const arrayRecursion = (arr, definition) => {
  523. arr.forEach((item) => {
  524. item.definition = definition;
  525. if (item.children && item.children.length > 0) {
  526. arrayRecursion(item.children, definition);
  527. }
  528. });
  529. return arr;
  530. };
  531. const allData = ref([]);
  532. const getSubset = (list, data) => {
  533. for (let i = 0; i < list.length; i++) {
  534. if (list[i].children && list[i].children.length > 0) {
  535. getSubset(list[i].children, data);
  536. } else {
  537. data.push(list[i].id);
  538. }
  539. }
  540. return data;
  541. };
  542. const getUserList = () => {
  543. proxy
  544. .get(
  545. `/tenantRole/list?pageNum=1&pageSize=10000&tenantId=${sourceList.value.pagination.tenantId}`
  546. )
  547. .then((message) => {
  548. roleData.value = message.rows.map((item) => {
  549. return {
  550. ...item,
  551. id: item.roleId,
  552. label: item.roleName,
  553. disabled: false,
  554. };
  555. });
  556. });
  557. proxy
  558. .get("/tenantDept/list", {
  559. pageNum: 1,
  560. pageSize: 9999,
  561. keyword: "",
  562. tenantId: proxy.useUserStore().user.tenantId,
  563. type: 0,
  564. })
  565. .then((res) => {
  566. companyData.value = res.data.map((x) => ({
  567. ...x,
  568. label: x.deptName,
  569. value: x.deptId,
  570. }));
  571. });
  572. Promise.all([
  573. proxy.post("/productClassify/tree", {
  574. parentId: "",
  575. name: "",
  576. definition: "1",
  577. }),
  578. proxy.post("/productClassify/tree", {
  579. parentId: "",
  580. name: "",
  581. definition: "2",
  582. }),
  583. ]).then((res) => {
  584. if (res && res.length > 1) {
  585. res[1].forEach((x) => {
  586. x.id = x.id + "";
  587. });
  588. productTreeData.value = [
  589. {
  590. id: "-999",
  591. name: "全部",
  592. parentId: "",
  593. children: [
  594. {
  595. id: "-9",
  596. definition: "2",
  597. name: "物料",
  598. parentId: "-999",
  599. children: arrayRecursion(res[1], "2"),
  600. },
  601. {
  602. id: "-99",
  603. definition: "1",
  604. name: "产品",
  605. parentId: "-999",
  606. children: arrayRecursion(res[0], "1"),
  607. },
  608. ],
  609. },
  610. ];
  611. allData.value = getSubset(productTreeData.value, []);
  612. }
  613. });
  614. };
  615. getUserList();
  616. const openModal = () => {
  617. roleData.value[0].disabled = false;
  618. modalType.value = "add";
  619. formData.data = {
  620. userType: 1,
  621. tenantId: proxy.useUserStore().user.tenantId,
  622. companySet: [],
  623. purchaseRange: [],
  624. purchaseRangeOne: [],
  625. identity: 10,
  626. identityList: [],
  627. };
  628. loadingDialog.value = false;
  629. dialogVisible.value = true;
  630. };
  631. function findNodeById(treeData, nodeId) {
  632. // 遍历当前层级的所有节点
  633. for (let i = 0; i < treeData.length; i++) {
  634. let node = treeData[i];
  635. // 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
  636. if (node.deptId === nodeId) {
  637. return node;
  638. }
  639. // 如果当前节点有子节点,则递归调用当前函数继续查找子节点
  640. if (node.children && node.children.length > 0) {
  641. let foundNode = findNodeById(node.children, nodeId);
  642. // 如果在子节点中找到了目标节点,则返回找到的节点
  643. if (foundNode) {
  644. return foundNode;
  645. }
  646. }
  647. }
  648. // 如果遍历完所有节点仍未找到目标节点,则返回 null
  649. return null;
  650. }
  651. const findCompanyType = (val) => {
  652. const current = findNodeById(deptList.value, val);
  653. if (current && current.type == 0) {
  654. formData.data.companySet = [val];
  655. companyData.value = companyData.value.map((x) => ({
  656. ...x,
  657. disabled: val == x.value,
  658. }));
  659. } else {
  660. return findCompanyType(current.parentId);
  661. }
  662. };
  663. const handleDeptIdChange = (val) => {
  664. const current = findNodeById(deptList.value, val);
  665. if (current && current.type == 0) {
  666. formData.data.companySet = [val];
  667. companyData.value = companyData.value.map((x) => ({
  668. ...x,
  669. disabled: val == x.value,
  670. }));
  671. } else {
  672. findCompanyType(current.parentId);
  673. }
  674. };
  675. const noRepeat = (arr) => {
  676. var newArr = [...new Set(arr)];
  677. return newArr;
  678. };
  679. const submitForm = () => {
  680. submit.value.handleSubmit(() => {
  681. if (formData.data.password && formData.data.password.length < 5) {
  682. return ElMessage("密码长度不得低于五位");
  683. }
  684. const method = modalType.value == "add" ? "POST" : "PUT";
  685. if (formData.data.companySet && formData.data.companySet.length > 0) {
  686. formData.data.companySet = formData.data.companySet.join(",");
  687. }
  688. if (isShowPurchaseAtt.value) {
  689. let data = noRepeat(
  690. productTree.value
  691. .getHalfCheckedKeys()
  692. .concat(productTree.value.getCheckedKeys())
  693. );
  694. data = data.filter((x) => !["-999", "-99", "-9"].includes(x));
  695. formData.data.purchaseRange = data.join(",");
  696. } else {
  697. formData.data.purchaseRange = "";
  698. }
  699. proxy.post("/tenantUser", formData.data, method).then(() => {
  700. if (formData.data.password && formData.data.userId) {
  701. proxy
  702. .post(
  703. "/tenantUser/resetPwd",
  704. { password: formData.data.password, userId: formData.data.userId },
  705. "PUT"
  706. )
  707. .then();
  708. }
  709. ElMessage({
  710. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  711. type: "success",
  712. });
  713. // 更新业务公司数据
  714. proxy
  715. .post("/tenantUser/getUserCompanyList", {
  716. pageNum: 1,
  717. pageSize: 9999,
  718. })
  719. .then((res) => {
  720. proxy.useUserStore().allDict["list_company_data"] = res.map((x) => ({
  721. ...x,
  722. label: x.deptName,
  723. value: x.deptId,
  724. }));
  725. proxy.useUserStore().allDict["tree_company_data"] = proxy.handleTree(
  726. res,
  727. "deptId"
  728. );
  729. });
  730. dialogVisible.value = false;
  731. getList();
  732. });
  733. });
  734. };
  735. const getDtl = (row) => {
  736. if (row.userId == "1") {
  737. roleData.value[0].disabled = true;
  738. } else {
  739. roleData.value[0].disabled = false;
  740. }
  741. companyData.value = companyData.value.map((x) => ({
  742. ...x,
  743. disabled: row.companyId == x.value,
  744. }));
  745. dialogVisible.value = true;
  746. proxy.get(`/tenantUser/${row.userId}`).then((res) => {
  747. formData.data = {
  748. ...row,
  749. userType: 1,
  750. roleIds: res.roleIds,
  751. identityList: res.data.identityList,
  752. };
  753. if (res.data && res.data.purchaseRange) {
  754. formData.data.purchaseRange = [];
  755. formData.data.purchaseRangeOne = res.data.purchaseRange.split(",");
  756. formData.data.purchaseRangeOne = formData.data.purchaseRangeOne.filter(
  757. (item) => {
  758. return allData.value.some((i) => item == i);
  759. }
  760. );
  761. } else {
  762. formData.data.purchaseRangeOne = [];
  763. }
  764. if (!(res.data.identityList && res.data.identityList.length > 0)) {
  765. formData.data.identityList = [];
  766. }
  767. changeRoleId(res.roleIds);
  768. let companySetData = formData.data.companySet
  769. ? formData.data.companySet
  770. : "";
  771. if (companySetData) {
  772. formData.data.companySet = [
  773. ...new Set((row.companyId + "," + companySetData).split(",")),
  774. ];
  775. } else {
  776. formData.data.companySet = row.companyId.split(",");
  777. }
  778. modalType.value = "edit";
  779. });
  780. };
  781. const newPassword = () => {
  782. formData.data.password = generatePassword();
  783. };
  784. const generatePassword = () => {
  785. var length = 12,
  786. charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  787. password = "";
  788. for (var i = 0, n = charset.length; i < length; ++i) {
  789. password += charset.charAt(Math.floor(Math.random() * n));
  790. }
  791. return password;
  792. };
  793. const userId = ref("");
  794. const password = ref("");
  795. const roomDialogVisible = ref(false);
  796. const submitPassword = (password1) => {
  797. if (!password1) {
  798. ElMessage({
  799. message: "请输入新密码",
  800. type: "warning",
  801. });
  802. return;
  803. }
  804. if (password1.length < 5) {
  805. return ElMessage("密码长度不得低于五位");
  806. }
  807. proxy
  808. .post(
  809. "/tenantUser/resetPwd",
  810. {
  811. password: password1,
  812. userId: userId.value,
  813. },
  814. "PUT"
  815. )
  816. .then(() => {
  817. ElMessage({
  818. message: "重置成功",
  819. type: "success",
  820. });
  821. roomDialogVisible.value = false;
  822. password.value = "";
  823. });
  824. };
  825. const changeUserName = (val) => {
  826. formData.data.userName = val.trim();
  827. };
  828. const changePassword = (val) => {
  829. formData.data.password = val.trim();
  830. };
  831. const changePassword2 = (val) => {
  832. password.value = val.trim();
  833. };
  834. const treeData = ref([]);
  835. const search = ref("");
  836. const getTreeData = () => {
  837. proxy
  838. .get("/tenantDept/list", {
  839. pageNum: 1,
  840. pageSize: 9999,
  841. keyword: "",
  842. tenantId: proxy.useUserStore().user.tenantId,
  843. })
  844. .then((res) => {
  845. for (let i = 0; i < res.data.length; i++) {
  846. if (res.data[i] && res.data[i].type == 0) {
  847. res.data[i].disabled = true;
  848. }
  849. }
  850. treeData.value = proxy.handleTree(res.data, "deptId");
  851. deptList.value = proxy.handleTree(res.data, "deptId");
  852. let newData = proxy.deepClone(res.data);
  853. for (let i = 0; i < newData.length; i++) {
  854. if (newData[i] && newData[i].type == 3) {
  855. newData[i].disabled = true;
  856. }
  857. }
  858. deptListOne.value = proxy.handleTree(newData, "deptId");
  859. });
  860. };
  861. getTreeData();
  862. const searchChange = () => {
  863. proxy.$refs.tree.filter(search.value);
  864. };
  865. const getParents = (node, name, key) => {
  866. if (node.parent && node.parent.data[key]) {
  867. name += node.parent.data[key];
  868. return getParents(node.parent, name, key);
  869. }
  870. return name;
  871. };
  872. // 以下可实现搜索显示子节点
  873. const filterNode = (value, data, node) => {
  874. let names = getParents(node, node.data.deptName, "deptName");
  875. let isName = names.indexOf(value) !== -1;
  876. return !value || isName ? true : false;
  877. };
  878. const treeChange = (e, data) => {
  879. sourceList.value.pagination.deptId = e.deptId;
  880. getList();
  881. };
  882. const handleAdd = () => {
  883. formData.data.identityList.push({
  884. identity: "",
  885. deptId: "",
  886. });
  887. };
  888. const handleRemove = (index) => {
  889. formData.data.identityList.splice(index, 1);
  890. };
  891. </script>
  892. <style lang="scss" scoped>
  893. .user {
  894. padding: 10px;
  895. display: flex;
  896. justify-content: space-between;
  897. .tree {
  898. width: 300px;
  899. }
  900. .content {
  901. width: calc(100% - 310px);
  902. }
  903. }
  904. .treeList {
  905. display: block;
  906. height: 100%;
  907. background: #fff;
  908. padding: 10px 15px 15px;
  909. height: calc(100vh - 122px);
  910. .search {
  911. display: flex;
  912. margin-bottom: 20px;
  913. .el-input {
  914. // width: calc(100% - 70px);
  915. margin-right: 10px;
  916. text-align: center;
  917. }
  918. }
  919. // .searh,.title,.box{
  920. // padding-left:20px ;
  921. // }
  922. .box {
  923. padding-right: 0px;
  924. height: calc(100vh - 245px);
  925. overflow-y: auto;
  926. overflow-x: auto;
  927. .el-tree {
  928. // .el-tree-node__content {
  929. // display: block;
  930. // }
  931. .el-tree-node > .el-tree-node__children {
  932. overflow: visible;
  933. }
  934. }
  935. }
  936. }
  937. </style>