EmployeeManage.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <template>
  2. <div class="SippliersList">
  3. <Toptitle title="员工管理">
  4. <slot name="titleButton">
  5. <Button @click="exportData()" type="primary" style="margin-right: 10px"
  6. >批量导出</Button
  7. >
  8. <Button
  9. type="primary"
  10. @click="handleEmployeeEdit(1, '')"
  11. style="margin-right:10px;"
  12. >新增员工</Button
  13. >
  14. </slot>
  15. </Toptitle>
  16. <div class="content">
  17. <div class="content_left">
  18. <Tree
  19. :data="treeData"
  20. select-node
  21. children-key="sub"
  22. style="width:100%;"
  23. @on-select-change="handleTreeSelect"
  24. class="demo-tree-render"
  25. ></Tree>
  26. </div>
  27. <div class="content_right">
  28. <div class="content_right_topform">
  29. <Form
  30. :label-width="90"
  31. :model="searchData"
  32. style="display:flex;justify-content:space-between;"
  33. >
  34. <div>
  35. <FormItem label="员工姓名:">
  36. <Input
  37. type="text"
  38. size="small"
  39. clearable
  40. v-model="searchData.title"
  41. style="width: 150px"
  42. placeholder="请输入姓名"
  43. />
  44. </FormItem>
  45. <FormItem label="部门类别:">
  46. <Select
  47. v-model="searchData.type"
  48. style="width: 150px"
  49. clearable
  50. filterable
  51. placeholder="请选择部门类别"
  52. size="small"
  53. >
  54. <Option
  55. v-for="item in departmentTypeList"
  56. :key="item.value"
  57. :label="item.label"
  58. :value="item.value"
  59. />
  60. </Select>
  61. </FormItem>
  62. <FormItem>
  63. <Button
  64. type="primary"
  65. size="small"
  66. @click="initData(searchData)"
  67. style="margin-right:10px;"
  68. >搜索</Button
  69. >
  70. </FormItem>
  71. </div>
  72. </Form>
  73. <div class="content_right_topfrom_btn"></div>
  74. </div>
  75. <div class="content_right_content">
  76. <div class="content_right_content_btn"></div>
  77. <div class="content_right_content_table">
  78. <Table
  79. :columns="tableColumns"
  80. border
  81. :loading="tableLoading"
  82. :data="tableData"
  83. >
  84. <template slot="setSlot" slot-scope="{ row, index }">
  85. <a style="margin:0 5px" @click="handleSet(2, row, index)"
  86. >编辑</a
  87. >
  88. <a
  89. style="margin:0 5px;color:red"
  90. @click="handleSet(3, row, index)"
  91. >删除</a
  92. >
  93. </template>
  94. </Table>
  95. <div class="content_right_content_page">
  96. <Page
  97. :page-size-opts="[10, 20, 30, 40, 100]"
  98. @on-page-size-change="changeSize"
  99. @on-change="changePage"
  100. :current="pageIndex"
  101. :total="total"
  102. show-sizer
  103. :page-size="pageSize"
  104. />
  105. </div>
  106. </div>
  107. </div>
  108. </div>
  109. </div>
  110. <Modal
  111. v-model="showModal"
  112. :title="type == 1 ? '新增员工' : '编辑员工'"
  113. @on-ok="handleModalOk"
  114. @on-cancel="showModal = false"
  115. >
  116. <div class="modal_content">
  117. <div class="modal_content_label">
  118. <span>ID: </span>
  119. <div style="width: 220px">
  120. {{ employeeForm.id || "自动生成" }}
  121. </div>
  122. </div>
  123. <div class="modal_content_label">
  124. <span>员工姓名: </span>
  125. <Input
  126. type="text"
  127. size="small"
  128. placeholder="请输入"
  129. v-model="employeeForm.nickname"
  130. style="width: 220px"
  131. />
  132. </div>
  133. <div class="modal_content_label">
  134. <span>手机号: </span>
  135. <Input
  136. type="text"
  137. size="small"
  138. placeholder="请输入"
  139. v-model="employeeForm.mobile"
  140. style="width: 220px"
  141. />
  142. </div>
  143. <div class="modal_content_label">
  144. <span>部门: </span>
  145. <Select
  146. size="small"
  147. placeholder="请选择"
  148. width="220px"
  149. clearable
  150. v-model="employeeForm.depart_code"
  151. style="width: 220px"
  152. >
  153. <Option
  154. v-for="item in departmentList"
  155. :key="item.code"
  156. :label="item.title"
  157. :value="item.code"
  158. />
  159. </Select>
  160. </div>
  161. <div class="modal_content_label">
  162. <span>部门类别: </span>
  163. <Select
  164. size="small"
  165. placeholder="请选择"
  166. v-model="employeeForm.type"
  167. clearable
  168. style="width: 220px"
  169. >
  170. <Option
  171. v-for="item in departmentTypeList"
  172. :key="item.value"
  173. :label="item.label"
  174. :value="item.value"
  175. />
  176. </Select>
  177. </div>
  178. <div class="modal_content_label">
  179. <span>是否登录系统: </span>
  180. <div style="width: 220px">
  181. <RadioGroup v-model="employeeForm.is_bind">
  182. <Radio :label="1">是</Radio>
  183. <Radio :label="0">否</Radio>
  184. </RadioGroup>
  185. </div>
  186. </div>
  187. <div class="modal_content_label" v-show="employeeForm.is_bind">
  188. <span>绑定人员: </span>
  189. <div style="width: 220px">
  190. <Select
  191. size="small"
  192. placeholder="请选择"
  193. v-model="employeeForm.sys_user_id"
  194. clearable
  195. style="width: 220px"
  196. >
  197. <Option
  198. v-for="item in userList"
  199. :key="item.id"
  200. :label="item.nickname"
  201. :value="item.id"
  202. />
  203. </Select>
  204. </div>
  205. </div>
  206. </div>
  207. </Modal>
  208. </div>
  209. </template>
  210. <script>
  211. // 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
  212. // 例如:import 《组件名称》 from '《组件路径》';
  213. export default {
  214. name: "EmployeeManage",
  215. components: {},
  216. props: {},
  217. // import引入的组件需要注入到对象中才能使用
  218. data() {
  219. // 这里存放数据
  220. return {
  221. type: "",
  222. partsNameList: [],
  223. treeData: [
  224. {
  225. title: "员工分类",
  226. expand: true,
  227. sub: [],
  228. render: (h, { root, node, data }) => {
  229. return h(
  230. "span",
  231. {
  232. style: {
  233. display: "inline-block",
  234. width: "100%",
  235. },
  236. },
  237. [
  238. h("span", [
  239. h("Icon", {
  240. props: {
  241. type: "ios-folder-outline",
  242. },
  243. style: {
  244. marginRight: "8px",
  245. },
  246. }),
  247. h("span", data.title),
  248. ]),
  249. ]
  250. );
  251. },
  252. },
  253. ],
  254. buttonProps: {
  255. type: "default",
  256. size: "small",
  257. },
  258. tableColumns: [
  259. {
  260. title: "序号",
  261. type: "index",
  262. key: "id",
  263. align: "center",
  264. minWidth: 90,
  265. },
  266. { title: "员工姓名", key: "nickname", align: "center", minWidth: 110 },
  267. { title: "手机号", key: "mobile", align: "center", minWidth: 150 },
  268. {
  269. title: "部门类别",
  270. key: "type",
  271. align: "center",
  272. minWidth: 100,
  273. render: (h, params) => {
  274. return h(
  275. "span",
  276. {},
  277. params.row.type == 1
  278. ? "制单人"
  279. : params.row.type == 2
  280. ? "业务员"
  281. : "车间人员"
  282. );
  283. },
  284. },
  285. {
  286. title: "是否登录系统",
  287. key: "is_bind",
  288. align: "center",
  289. minWidth: 150,
  290. render: (h, params) => {
  291. const { row } = params;
  292. return h("span", {}, row.is_bind == 1 ? "是" : "否");
  293. },
  294. },
  295. {
  296. title: "操作",
  297. key: "code",
  298. align: "center",
  299. minWidth: 120,
  300. slot: "setSlot",
  301. },
  302. ],
  303. tableData: [],
  304. tableLoading: false,
  305. pageIndex: 1,
  306. pageSize: 10,
  307. total: 0,
  308. searchData: {
  309. nickname: "",
  310. type: "",
  311. code: "",
  312. },
  313. suppliersTypeTitle: "",
  314. suppliersTypeId: "",
  315. showModal: false,
  316. employeeForm: {
  317. id: "",
  318. nickname: "",
  319. mobile: "",
  320. depart_code: "",
  321. is_blind: "",
  322. },
  323. departmentList: [],
  324. departmentTypeList: [
  325. { label: "制单人", value: 1 },
  326. { label: "业务员", value: 2 },
  327. { label: "车间人员", value: 3 },
  328. ],
  329. userList: [],
  330. type: null,
  331. };
  332. },
  333. // 生命周期 - 创建完成(可以访问当前this实例)
  334. created() {
  335. this.axios({
  336. method: "get",
  337. url: "/api/user",
  338. })
  339. .then((res) => {
  340. this.userList = res.data.data;
  341. })
  342. .catch((err) => {});
  343. this.axios({
  344. method: "get",
  345. url: "/api/employee_depart_list",
  346. })
  347. .then((res) => {
  348. this.treeData[0].sub = res.data;
  349. this.handleDepartment(res.data);
  350. })
  351. .catch((err) => {});
  352. },
  353. // 生命周期 - 挂载完成(可以访问DOM元素)
  354. mounted() {
  355. this.initData(this.searchData);
  356. },
  357. methods: {
  358. async exportData() {
  359. const res = await this.axios("/api/employee_export");
  360. if (res.code == 200) {
  361. let url = `${this.$store.state.ip}/api/storage/${res.data.file}`;
  362. location.href = url;
  363. }
  364. },
  365. initData(row) {
  366. this.tableLoading = true;
  367. this.axios({
  368. method: "get",
  369. url: "/api/employee_list",
  370. params: {
  371. ...row,
  372. page_index: this.pageIndex,
  373. page_size: this.pageSize,
  374. },
  375. })
  376. .then((res) => {
  377. this.tableLoading = false;
  378. this.tableData = res.data;
  379. })
  380. .catch((err) => {});
  381. },
  382. handleSet(type, row, index) {
  383. // 2编辑 3删除
  384. switch (type) {
  385. case 2:
  386. this.employeeForm = JSON.parse(JSON.stringify(row));
  387. this.handleEmployeeEdit(type, row);
  388. break;
  389. case 3:
  390. this.$Modal.confirm({
  391. title: "确认删除?",
  392. content: "此操作无法恢复,请确认!",
  393. onOk: () => {
  394. this.axios({
  395. method: "post",
  396. url: "/api/employee_del",
  397. data: {
  398. id: row.id,
  399. },
  400. })
  401. .then((res) => {
  402. this.$Message.success(res.msg);
  403. this.initData();
  404. })
  405. .catch((err) => {});
  406. },
  407. onCancel: () => {},
  408. });
  409. break;
  410. }
  411. },
  412. append(data) {
  413. const children = data.children || [];
  414. children.push({
  415. code: this.form.code,
  416. title: this.form.title,
  417. expand: true,
  418. });
  419. this.$set(data, "children", children);
  420. },
  421. remove(root, node, data) {
  422. if (node.children && node.children.length > 0) {
  423. this.$Message.error("有子集时不可删除");
  424. } else {
  425. const parentKey = root.find((el) => el === node).parent;
  426. const parent = root.find((el) => el.nodeKey === parentKey).node;
  427. const index = parent.children.indexOf(data);
  428. parent.children.splice(index, 1);
  429. }
  430. },
  431. handleModalOk() {
  432. let url = "";
  433. this.type == 1
  434. ? (url = "/api/employee_add")
  435. : (url = "/api/employee_edit");
  436. this.axios({
  437. method: "post",
  438. url,
  439. data: {
  440. ...this.employeeForm,
  441. },
  442. })
  443. .then((res) => {
  444. this.$Message.success(res.msg);
  445. this.initData();
  446. })
  447. .catch((err) => {});
  448. },
  449. handleTreeSelect(arr, row) {
  450. console.log("row :>> ", row);
  451. this.searchData.code = row.code;
  452. this.suppliersTypeTitle = row.title;
  453. this.suppliersTypeId = row.id;
  454. this.initData(this.searchData);
  455. },
  456. changeSize(e) {
  457. this.pageSize = e;
  458. this.initData(this.searchData);
  459. },
  460. changePage(e) {
  461. this.pageIndex = e;
  462. this.initData(this.searchData);
  463. },
  464. handleEmployeeEdit(type, item) {
  465. this.type = type;
  466. if (type == 1) {
  467. this.employeeForm = {
  468. id: "",
  469. nickname: "",
  470. mobile: "",
  471. depart_code: "",
  472. is_blind: "",
  473. sys_user_id: "",
  474. };
  475. }
  476. this.showModal = true;
  477. },
  478. handleDepartment(list) {
  479. list.forEach((element) => {
  480. if (element.sub && element.sub.length > 0) {
  481. return this.handleDepartment(element.sub);
  482. } else {
  483. this.departmentList.push(element);
  484. }
  485. });
  486. },
  487. },
  488. // 监听属性 类似于data概念
  489. computed: {},
  490. // 监控data中的数据变化
  491. watch: {},
  492. beforeCreate() {}, // 生命周期 - 创建之前
  493. beforeMount() {}, // 生命周期 - 挂载之前
  494. beforeUpdate() {}, // 生命周期 - 更新之前
  495. updated() {}, // 生命周期 - 更新之后
  496. beforeDestroy() {}, // 生命周期 - 销毁之前
  497. destroyed() {}, // 生命周期 - 销毁完成
  498. activated() {}, // 如果页面有keep-alive缓存功能,这个函数会触发
  499. };
  500. </script>
  501. <style lang="scss" scoped>
  502. .content {
  503. width: 100%;
  504. display: flex;
  505. justify-content: space-between;
  506. padding-top: 30px;
  507. .content_left {
  508. width: 15%;
  509. height: 60vh;
  510. border-right: 1px solid #515a6e;
  511. }
  512. .content_right {
  513. width: 83%;
  514. .content_right_topform {
  515. /deep/.ivu-form {
  516. display: flex;
  517. justify-content: flex-start;
  518. flex-wrap: wrap;
  519. }
  520. /deep/.ivu-form-item {
  521. display: inline-block;
  522. width: 250px;
  523. }
  524. .content_right_topfrom_btn {
  525. display: flex;
  526. justify-content: flex-end;
  527. }
  528. }
  529. .content_right_content {
  530. .content_right_content_btn {
  531. display: flex;
  532. justify-content: flex-end;
  533. margin-bottom: 20px;
  534. }
  535. .content_right_content_table {
  536. }
  537. .content_right_content_page {
  538. display: flex;
  539. justify-content: center;
  540. padding-top: 20px;
  541. }
  542. }
  543. }
  544. }
  545. .demo-tree-render {
  546. width: 100%;
  547. }
  548. .modal_content {
  549. .modal_content_label {
  550. display: flex;
  551. justify-content: space-around;
  552. align-items: center;
  553. padding: 10px 0;
  554. span {
  555. width: 100px;
  556. }
  557. }
  558. }
  559. </style>