index.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. <template>
  2. <div class="app-container">
  3. <el-row :gutter="20">
  4. <!--部门数据-->
  5. <el-col :span="2" :xs="24">
  6. <div class="head-container">
  7. <el-input
  8. v-model="deptName"
  9. placeholder="请输入部门名称"
  10. clearable
  11. size="small"
  12. prefix-icon="el-icon-search"
  13. style="margin-bottom: 20px"
  14. />
  15. </div>
  16. <div class="head-container">
  17. <el-tree
  18. :data="deptOptions"
  19. :props="defaultProps"
  20. :expand-on-click-node="false"
  21. :filter-node-method="filterNode"
  22. ref="tree"
  23. node-key="id"
  24. default-expand-all
  25. highlight-current
  26. @node-click="handleNodeClick"
  27. />
  28. </div>
  29. </el-col>
  30. <!--用户数据-->
  31. <el-col :span="22" :xs="24">
  32. <el-form
  33. :model="queryParams"
  34. ref="queryForm"
  35. size="small"
  36. :inline="true"
  37. v-show="showSearch"
  38. label-width="68px"
  39. >
  40. <el-form-item label="用户昵称" prop="nickName">
  41. <el-input
  42. v-model="queryParams.nickName"
  43. placeholder="请输入用户昵称"
  44. clearable
  45. style="width: 240px"
  46. @keyup.enter.native="handleQuery"
  47. />
  48. </el-form-item>
  49. <el-form-item label="工号" prop="jobNumber">
  50. <el-input
  51. v-model="queryParams.jobNumber"
  52. placeholder="请输入工号"
  53. clearable
  54. style="width: 240px"
  55. @keyup.enter.native="handleQuery"
  56. />
  57. </el-form-item>
  58. <el-form-item label="职位" prop="roleId">
  59. <el-select
  60. v-model="queryParams.roleId"
  61. placeholder="请选择职位"
  62. clearable
  63. style="width: 240px"
  64. >
  65. <el-option
  66. v-for="item in roleOptions"
  67. :key="item.roleId"
  68. :label="item.roleName"
  69. :value="item.roleId"
  70. />
  71. </el-select>
  72. </el-form-item>
  73. <el-form-item label="兼职全职" prop="fullJob">
  74. <el-select
  75. v-model="queryParams.fullJob"
  76. placeholder="兼职/全职"
  77. clearable
  78. style="width: 240px"
  79. >
  80. <el-option
  81. v-for="dict in dict.type.sys_user_fulljob"
  82. :key="dict.value"
  83. :label="dict.label"
  84. :value="dict.value"
  85. />
  86. </el-select>
  87. </el-form-item>
  88. <el-form-item label="公司" prop="companyId">
  89. <el-select
  90. v-model="queryParams.companyId"
  91. placeholder="请选择公司"
  92. clearable
  93. style="width: 240px"
  94. >
  95. <el-option
  96. v-for="item in company"
  97. :key="item.deptId"
  98. :label="item.deptName"
  99. :value="item.deptId"
  100. />
  101. </el-select>
  102. </el-form-item>
  103. <!-- <el-form-item label="手机号码" prop="phonenumber">
  104. <el-input
  105. v-model="queryParams.phonenumber"
  106. placeholder="请输入手机号码"
  107. clearable
  108. style="width: 240px"
  109. @keyup.enter.native="handleQuery"
  110. />
  111. </el-form-item> -->
  112. <el-form-item label="状态" prop="status">
  113. <el-select
  114. v-model="queryParams.status"
  115. placeholder="用户状态"
  116. clearable
  117. style="width: 240px"
  118. >
  119. <el-option
  120. v-for="dict in dict.type.sys_normal_disable"
  121. :key="dict.value"
  122. :label="dict.label"
  123. :value="dict.value"
  124. />
  125. </el-select>
  126. </el-form-item>
  127. <el-form-item label="创建时间">
  128. <el-date-picker
  129. v-model="dateRange"
  130. style="width: 240px"
  131. value-format="yyyy-MM-dd"
  132. type="daterange"
  133. range-separator="-"
  134. start-placeholder="开始日期"
  135. end-placeholder="结束日期"
  136. ></el-date-picker>
  137. </el-form-item>
  138. <el-form-item label="数量排序" prop="projectQuantitySort">
  139. <el-select
  140. v-model="queryParams.projectQuantitySort"
  141. placeholder="项目数排序"
  142. clearable
  143. style="width: 240px"
  144. >
  145. <el-option
  146. v-for="item in sortList"
  147. :key="item.value"
  148. :label="item.label"
  149. :value="item.value"
  150. />
  151. </el-select>
  152. </el-form-item>
  153. <el-form-item label="时长排序" prop="durationSort">
  154. <el-select
  155. v-model="queryParams.durationSort"
  156. placeholder="时长排序"
  157. clearable
  158. style="width: 240px"
  159. >
  160. <el-option
  161. v-for="item in sortList"
  162. :key="item.value"
  163. :label="item.label"
  164. :value="item.value"
  165. />
  166. </el-select>
  167. </el-form-item>
  168. <el-form-item>
  169. <el-button
  170. type="primary"
  171. icon="el-icon-search"
  172. size="mini"
  173. @click="handleQuery"
  174. >搜索</el-button
  175. >
  176. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
  177. >重置</el-button
  178. >
  179. </el-form-item>
  180. </el-form>
  181. <el-row :gutter="10" class="mb8">
  182. <el-col :span="1.5">
  183. <el-button
  184. type="primary"
  185. plain
  186. icon="el-icon-plus"
  187. size="mini"
  188. @click="handleAdd"
  189. v-hasPermi="['system:user:add']"
  190. >新增</el-button
  191. >
  192. </el-col>
  193. <el-col :span="1.5">
  194. <el-button
  195. type="success"
  196. plain
  197. icon="el-icon-edit"
  198. size="mini"
  199. :disabled="single"
  200. @click="handleUpdate"
  201. v-hasPermi="['system:user:edit']"
  202. >修改</el-button
  203. >
  204. </el-col>
  205. <el-col :span="1.5">
  206. <el-button
  207. type="danger"
  208. plain
  209. icon="el-icon-delete"
  210. size="mini"
  211. :disabled="multiple"
  212. @click="handleDelete"
  213. v-hasPermi="['system:user:remove']"
  214. >删除</el-button
  215. >
  216. </el-col>
  217. <el-col :span="1.5">
  218. <el-button
  219. type="info"
  220. plain
  221. icon="el-icon-upload2"
  222. size="mini"
  223. @click="handleImport"
  224. v-hasPermi="['system:user:import']"
  225. >导入</el-button
  226. >
  227. </el-col>
  228. <el-col :span="1.5">
  229. <el-button
  230. type="warning"
  231. plain
  232. icon="el-icon-download"
  233. size="mini"
  234. @click="handleExport"
  235. v-hasPermi="['system:user:export']"
  236. >导出</el-button
  237. >
  238. </el-col>
  239. <right-toolbar
  240. :showSearch.sync="showSearch"
  241. @queryTable="getList"
  242. :columns="columns"
  243. ></right-toolbar>
  244. </el-row>
  245. <el-table
  246. v-loading="loading"
  247. :data="userList"
  248. @selection-change="handleSelectionChange"
  249. >
  250. <el-table-column type="selection" width="50" align="center" />
  251. <el-table-column
  252. label="用户编号"
  253. align="center"
  254. key="userId"
  255. prop="userId"
  256. v-if="columns[0].visible"
  257. />
  258. <el-table-column
  259. label="工号"
  260. align="center"
  261. key="jobNumber"
  262. prop="jobNumber"
  263. v-if="columns[1].visible"
  264. />
  265. <el-table-column
  266. label="用户名"
  267. align="center"
  268. key="userName"
  269. prop="userName"
  270. v-if="columns[2].visible"
  271. :show-overflow-tooltip="true"
  272. />
  273. <el-table-column
  274. label="用户昵称"
  275. align="center"
  276. key="nickName"
  277. prop="nickName"
  278. v-if="columns[3].visible"
  279. :show-overflow-tooltip="true"
  280. />
  281. <el-table-column
  282. label="职位"
  283. align="center"
  284. key="roleName"
  285. prop="roleName"
  286. v-if="columns[4].visible"
  287. :show-overflow-tooltip="true"
  288. />
  289. <el-table-column
  290. label="全职/兼职"
  291. align="center"
  292. key="fullJob"
  293. prop="fullJob"
  294. v-if="columns[5].visible"
  295. width="60"
  296. >
  297. <template slot-scope="scope">
  298. <span>{{ ["兼职", "全职"][scope.row.fullJob] }}</span>
  299. </template>
  300. </el-table-column>
  301. <el-table-column
  302. label="部门"
  303. align="center"
  304. key="deptName"
  305. prop="dept.deptName"
  306. v-if="columns[6].visible"
  307. :show-overflow-tooltip="true"
  308. />
  309. <el-table-column
  310. label="参与项目数"
  311. align="center"
  312. key="projectQuantity"
  313. prop="projectQuantity"
  314. v-if="columns[7].visible"
  315. width="60"
  316. />
  317. <el-table-column
  318. label="上级负责人"
  319. align="center"
  320. key="superiorName"
  321. prop="superiorName"
  322. v-if="columns[8].visible"
  323. :show-overflow-tooltip="true"
  324. />
  325. <el-table-column
  326. label="累计工时"
  327. align="center"
  328. key="duration"
  329. prop="duration"
  330. v-if="columns[9].visible"
  331. width="50"
  332. />
  333. <el-table-column
  334. label="状态"
  335. align="center"
  336. key="status"
  337. v-if="columns[10].visible"
  338. width="50"
  339. >
  340. <template slot-scope="scope">
  341. <span>{{ ["正常", "停用", "暂停"][scope.row.status] }}</span>
  342. </template>
  343. <!-- <template slot-scope="scope">
  344. <el-switch
  345. v-model="scope.row.status"
  346. active-value="0"
  347. inactive-value="1"
  348. @change="handleStatusChange(scope.row)"
  349. ></el-switch>
  350. </template> -->
  351. </el-table-column>
  352. <el-table-column
  353. label="创建时间"
  354. align="center"
  355. prop="createTime"
  356. v-if="columns[11].visible"
  357. width="100"
  358. >
  359. <template slot-scope="scope">
  360. <span>{{ parseTime(scope.row.createTime) }}</span>
  361. </template>
  362. </el-table-column>
  363. <el-table-column
  364. label="最后登录时间"
  365. align="center"
  366. prop="loginDate"
  367. v-if="columns[12].visible"
  368. width="100"
  369. >
  370. <template slot-scope="scope">
  371. <span>{{ parseTime(scope.row.loginDate) }}</span>
  372. </template>
  373. </el-table-column>
  374. <el-table-column
  375. label="操作"
  376. align="center"
  377. width="160"
  378. class-name="small-padding fixed-width"
  379. >
  380. <template slot-scope="scope" v-if="scope.row.userId !== 1">
  381. <el-button
  382. size="mini"
  383. type="text"
  384. icon="el-icon-edit"
  385. @click="handleUpdate(scope.row)"
  386. v-hasPermi="['system:user:edit']"
  387. >修改</el-button
  388. >
  389. <el-button
  390. size="mini"
  391. type="text"
  392. icon="el-icon-delete"
  393. @click="handleDelete(scope.row)"
  394. v-hasPermi="['system:user:remove']"
  395. >删除</el-button
  396. >
  397. <el-dropdown
  398. size="mini"
  399. @command="(command) => handleCommand(command, scope.row)"
  400. v-hasPermi="['system:user:resetPwd', 'system:user:edit']"
  401. >
  402. <el-button size="mini" type="text" icon="el-icon-d-arrow-right"
  403. >更多</el-button
  404. >
  405. <el-dropdown-menu slot="dropdown">
  406. <el-dropdown-item
  407. command="handleResetPwd"
  408. icon="el-icon-key"
  409. v-hasPermi="['system:user:resetPwd']"
  410. >重置密码</el-dropdown-item
  411. >
  412. <el-dropdown-item
  413. command="handleAuthRole"
  414. icon="el-icon-circle-check"
  415. v-hasPermi="['system:user:edit']"
  416. >分配角色</el-dropdown-item
  417. >
  418. </el-dropdown-menu>
  419. </el-dropdown>
  420. </template>
  421. </el-table-column>
  422. </el-table>
  423. <pagination
  424. v-show="total > 0"
  425. :total="total"
  426. :page.sync="queryParams.pageNum"
  427. :limit.sync="queryParams.pageSize"
  428. @pagination="getList"
  429. />
  430. </el-col>
  431. </el-row>
  432. <!-- 添加或修改用户配置对话框 -->
  433. <el-dialog
  434. :title="title"
  435. :visible.sync="open"
  436. width="700px"
  437. append-to-body
  438. :close-on-click-modal="false"
  439. >
  440. <el-form ref="form" :model="form" :rules="rules" label-width="90px">
  441. <el-row>
  442. <el-col :span="12">
  443. <el-form-item label="用户名" prop="userName">
  444. <el-input
  445. v-model="form.userName"
  446. placeholder="请输入登录用户名"
  447. maxlength="30"
  448. />
  449. </el-form-item>
  450. </el-col>
  451. <el-col :span="12">
  452. <el-form-item
  453. v-if="form.userId == undefined"
  454. label="用户密码"
  455. prop="password"
  456. >
  457. <el-input
  458. v-model="form.password"
  459. placeholder="请输入用户密码"
  460. type="password"
  461. maxlength="20"
  462. show-password
  463. />
  464. </el-form-item>
  465. </el-col>
  466. </el-row>
  467. <el-row>
  468. <el-col :span="12">
  469. <el-form-item label="用户昵称" prop="nickName">
  470. <el-input
  471. v-model="form.nickName"
  472. placeholder="请输入用户昵称"
  473. maxlength="30"
  474. />
  475. </el-form-item>
  476. </el-col>
  477. <el-col :span="12">
  478. <el-form-item label="归属部门" prop="deptId">
  479. <treeselect
  480. v-model="form.deptId"
  481. :options="deptOptions"
  482. :show-count="true"
  483. placeholder="请选择归属部门"
  484. />
  485. </el-form-item>
  486. </el-col>
  487. </el-row>
  488. <el-row>
  489. <!-- <el-col :span="12">
  490. <el-form-item label="岗位" prop="postIds">
  491. <el-select
  492. v-model="form.postIds"
  493. multiple
  494. placeholder="请选择岗位"
  495. style="width: 240px"
  496. >
  497. <el-option
  498. v-for="item in postOptions"
  499. :key="item.postId"
  500. :label="item.postName"
  501. :value="item.postId"
  502. :disabled="item.status == 1"
  503. ></el-option>
  504. </el-select>
  505. </el-form-item>
  506. </el-col> -->
  507. <el-col :span="12">
  508. <el-form-item label="角色" prop="roleIds">
  509. <el-select
  510. v-model="form.roleIds"
  511. multiple
  512. placeholder="请选择角色"
  513. style="width: 240px"
  514. >
  515. <el-option
  516. v-for="item in roleOptions"
  517. :key="item.roleId"
  518. :label="item.roleName"
  519. :value="item.roleId"
  520. :disabled="item.status == 1"
  521. ></el-option>
  522. </el-select>
  523. </el-form-item>
  524. </el-col>
  525. <el-col :span="12">
  526. <el-form-item label="用户性别">
  527. <el-select v-model="form.sex" placeholder="请选择性别" style="width: 240px">
  528. <el-option
  529. v-for="dict in dict.type.sys_user_sex"
  530. :key="dict.value"
  531. :label="dict.label"
  532. :value="dict.value"
  533. ></el-option>
  534. </el-select>
  535. </el-form-item>
  536. </el-col>
  537. </el-row>
  538. <el-row>
  539. <el-col :span="12">
  540. <el-form-item label="工号" prop="jobNumber">
  541. <el-input
  542. v-model="form.jobNumber"
  543. placeholder="请填写工号"
  544. maxlength="11"
  545. />
  546. </el-form-item>
  547. </el-col>
  548. <el-col :span="12">
  549. <el-form-item label="上级" prop="superiorId">
  550. <el-autocomplete
  551. style="width: 240px"
  552. v-model="form.superiorName"
  553. value-key="nickName"
  554. :fetch-suggestions="getDatas"
  555. :filter-multiple="true"
  556. clearable
  557. placeholder="请输入姓名"
  558. @select="selectUser"
  559. />
  560. </el-form-item>
  561. </el-col>
  562. </el-row>
  563. <el-row>
  564. <el-col :span="12">
  565. <el-form-item label="手机号码" prop="phonenumber">
  566. <el-input
  567. v-model="form.phonenumber"
  568. placeholder="请输入手机号码"
  569. maxlength="11"
  570. />
  571. </el-form-item>
  572. </el-col>
  573. <el-col :span="12">
  574. <el-form-item label="邮箱" prop="email">
  575. <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
  576. </el-form-item>
  577. </el-col>
  578. </el-row>
  579. <el-row>
  580. <el-col :span="12">
  581. <el-form-item label="兼职/全职" prop="fullJob">
  582. <el-select v-model="form.fullJob" placeholder="请选择" style="width: 240px">
  583. <el-option
  584. v-for="dict in dict.type.sys_user_fulljob"
  585. :key="dict.value"
  586. :label="dict.label"
  587. :value="dict.value"
  588. ></el-option>
  589. </el-select>
  590. </el-form-item>
  591. </el-col>
  592. <el-col :span="12">
  593. <el-form-item label="状态">
  594. <el-radio-group v-model="form.status">
  595. <el-radio
  596. v-for="dict in dict.type.sys_normal_disable"
  597. :key="dict.value"
  598. :label="dict.value"
  599. >{{ dict.label }}</el-radio
  600. >
  601. </el-radio-group>
  602. </el-form-item>
  603. </el-col>
  604. </el-row>
  605. <el-row>
  606. <el-col :span="24">
  607. <el-form-item label="备注">
  608. <el-input
  609. v-model="form.remark"
  610. type="textarea"
  611. placeholder="请输入内容"
  612. ></el-input>
  613. </el-form-item>
  614. </el-col>
  615. </el-row>
  616. </el-form>
  617. <div slot="footer" class="dialog-footer">
  618. <el-button type="primary" @click="submitForm">确 定</el-button>
  619. <el-button @click="cancel">取 消</el-button>
  620. </div>
  621. </el-dialog>
  622. <!-- 用户导入对话框 -->
  623. <el-dialog
  624. :title="upload.title"
  625. :visible.sync="upload.open"
  626. width="400px"
  627. append-to-body
  628. >
  629. <el-upload
  630. ref="upload"
  631. :limit="1"
  632. accept=".xlsx, .xls"
  633. :headers="upload.headers"
  634. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  635. :disabled="upload.isUploading"
  636. :on-progress="handleFileUploadProgress"
  637. :on-success="handleFileSuccess"
  638. :auto-upload="false"
  639. drag
  640. >
  641. <i class="el-icon-upload"></i>
  642. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  643. <div class="el-upload__tip text-center" slot="tip">
  644. <div class="el-upload__tip" slot="tip">
  645. <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
  646. </div>
  647. <span>仅允许导入xls、xlsx格式文件。</span>
  648. <el-link
  649. type="primary"
  650. :underline="false"
  651. style="font-size: 12px; vertical-align: baseline"
  652. @click="importTemplate"
  653. >下载模板</el-link
  654. >
  655. </div>
  656. </el-upload>
  657. <div slot="footer" class="dialog-footer">
  658. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  659. <el-button @click="upload.open = false">取 消</el-button>
  660. </div>
  661. </el-dialog>
  662. </div>
  663. </template>
  664. <script>
  665. import {
  666. listUser,
  667. getUser,
  668. getCompany,
  669. delUser,
  670. addUser,
  671. updateUser,
  672. resetUserPwd,
  673. changeUserStatus,
  674. deptTreeSelect,
  675. selectName,
  676. } from "@/api/system/user";
  677. import { getToken } from "@/utils/auth";
  678. import Treeselect from "@riophae/vue-treeselect";
  679. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  680. export default {
  681. name: "User",
  682. dicts: ["sys_normal_disable", "sys_user_sex", "sys_user_fulljob"],
  683. components: { Treeselect },
  684. data() {
  685. return {
  686. selectedValue: "",
  687. options: [],
  688. // 遮罩层
  689. loading: true,
  690. // 选中数组
  691. ids: [],
  692. // 非单个禁用
  693. single: true,
  694. // 非多个禁用
  695. multiple: true,
  696. // 显示搜索条件
  697. showSearch: true,
  698. // 总条数
  699. total: 0,
  700. // 用户表格数据
  701. userList: null,
  702. // 弹出层标题
  703. title: "",
  704. // 部门树选项
  705. deptOptions: undefined,
  706. // 是否显示弹出层
  707. open: false,
  708. // 部门名称
  709. deptName: undefined,
  710. // 默认密码
  711. initPassword: undefined,
  712. // 日期范围
  713. dateRange: [],
  714. // 岗位选项
  715. postOptions: [],
  716. // 公司选项
  717. company: [],
  718. // 角色选项
  719. roleOptions: [],
  720. // 表单参数
  721. form: {},
  722. // 排序
  723. sortList: [
  724. { label: "低到高", value: 0 },
  725. { label: "高到低", value: 1 },
  726. ],
  727. defaultProps: {
  728. children: "children",
  729. label: "label",
  730. },
  731. // 用户导入参数
  732. upload: {
  733. // 是否显示弹出层(用户导入)
  734. open: false,
  735. // 弹出层标题(用户导入)
  736. title: "",
  737. // 是否禁用上传
  738. isUploading: false,
  739. // 是否更新已经存在的用户数据
  740. updateSupport: 0,
  741. // 设置上传的请求头部
  742. headers: { Authorization: "Bearer " + getToken() },
  743. // 上传的地址
  744. url: process.env.VUE_APP_BASE_API + "/system/user/importData",
  745. },
  746. // 查询参数
  747. queryParams: {
  748. pageNum: 1,
  749. pageSize: 10,
  750. userName: undefined,
  751. phonenumber: undefined,
  752. status: undefined,
  753. deptId: undefined,
  754. },
  755. // 列信息
  756. columns: [
  757. { key: 0, label: `用户编号`, visible: false },
  758. { key: 1, label: `工号`, visible: true },
  759. { key: 2, label: `账号`, visible: true },
  760. { key: 3, label: `用户名称`, visible: true },
  761. { key: 4, label: `职位`, visible: true },
  762. { key: 5, label: `全职/兼职`, visible: true },
  763. { key: 6, label: `部门`, visible: true },
  764. { key: 7, label: `参与项目`, visible: true },
  765. { key: 8, label: `上级负责人`, visible: true },
  766. { key: 9, label: `累计工时`, visible: true },
  767. { key: 10, label: `状态`, visible: true },
  768. { key: 11, label: `创建时间`, visible: true },
  769. { key: 12, label: `最后登录时间`, visible: true },
  770. ],
  771. // 表单校验
  772. rules: {
  773. nickName: [
  774. { required: true, message: "建议为岗位+名称的形式", trigger: "blur" },
  775. {
  776. min: 2,
  777. max: 20,
  778. message: "用户昵称长度必须介于 2 和 20 之间",
  779. trigger: "blur",
  780. },
  781. ],
  782. deptId: [{ required: true, message: "归属部门不能为空", trigger: "blur" }],
  783. jobNumber: [{ required: true, message: "工号不能为空", trigger: "blur" }],
  784. superiorId: [
  785. { required: true, message: "上级不能为空", trigger: ["blur", "change"] },
  786. ],
  787. userName: [
  788. { required: true, message: "建议以手机号为用户登录账号", trigger: "blur" },
  789. {
  790. min: 2,
  791. max: 20,
  792. message: "用户名长度必须介于 2 和 20 之间",
  793. trigger: "blur",
  794. },
  795. ],
  796. password: [
  797. { required: true, message: "初始密码为123456,请及时修改", trigger: "blur" },
  798. {
  799. min: 5,
  800. max: 20,
  801. message: "用户密码长度必须介于 5 和 20 之间",
  802. trigger: "blur",
  803. },
  804. ],
  805. roleIds: [{ required: true, message: "角色不能为空", trigger: "blur" }],
  806. fullJob: [{ required: true, message: "是否全职", trigger: "blur" }],
  807. email: [
  808. {
  809. type: "email",
  810. message: "请输入正确的邮箱地址",
  811. trigger: ["blur", "change"],
  812. },
  813. ],
  814. phonenumber: [
  815. {
  816. pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
  817. message: "请输入正确的手机号码",
  818. trigger: "blur",
  819. },
  820. ],
  821. },
  822. };
  823. },
  824. watch: {
  825. // 根据名称筛选部门树
  826. deptName(val) {
  827. this.$refs.tree.filter(val);
  828. },
  829. },
  830. created() {
  831. this.getList();
  832. this.getUser();
  833. this.getCompany();
  834. this.getDeptTree();
  835. this.getConfigKey("sys.user.initPassword").then((response) => {
  836. this.initPassword = response.msg;
  837. });
  838. },
  839. methods: {
  840. // 根据查询关键词,获取匹配的下拉列表数据
  841. getDatas(query, cb) {
  842. selectName(query, 2).then((response) => {
  843. cb(response.data);
  844. });
  845. },
  846. selectUser(item) {
  847. this.form.superiorId = item.userId;
  848. this.form.superiorName = item.nickName;
  849. },
  850. /** 查询用户列表 */
  851. getList() {
  852. this.loading = true;
  853. listUser(this.addDateRange(this.queryParams, this.dateRange)).then((response) => {
  854. this.userList = response.rows;
  855. this.total = response.total;
  856. this.loading = false;
  857. });
  858. },
  859. /** 获取公司信息 */
  860. getCompany() {
  861. getCompany().then((response) => {
  862. this.company = response.data;
  863. });
  864. },
  865. /** 获取岗位信息 */
  866. getUser() {
  867. getUser().then((response) => {
  868. this.postOptions = response.posts;
  869. this.roleOptions = response.roles;
  870. });
  871. },
  872. /** 查询部门下拉树结构 */
  873. getDeptTree() {
  874. deptTreeSelect().then((response) => {
  875. this.deptOptions = response.data;
  876. });
  877. },
  878. // 筛选节点
  879. filterNode(value, data) {
  880. if (!value) return true;
  881. return data.label.indexOf(value) !== -1;
  882. },
  883. // 节点单击事件
  884. handleNodeClick(data) {
  885. this.queryParams.deptId = data.id;
  886. this.handleQuery();
  887. },
  888. // 用户状态修改
  889. handleStatusChange(row) {
  890. let text = row.status === "0" ? "启用" : "停用";
  891. this.$modal
  892. .confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
  893. .then(function () {
  894. return changeUserStatus(row.userId, row.status);
  895. })
  896. .then(() => {
  897. this.$modal.msgSuccess(text + "成功");
  898. })
  899. .catch(function () {
  900. row.status = row.status === "0" ? "1" : "0";
  901. });
  902. },
  903. // 取消按钮
  904. cancel() {
  905. this.open = false;
  906. this.reset();
  907. },
  908. // 表单重置
  909. reset() {
  910. this.form = {
  911. superiorId: undefined,
  912. superiorName: undefined,
  913. fullJob: undefined,
  914. jobNumber: undefined,
  915. userId: undefined,
  916. deptId: undefined,
  917. userName: undefined,
  918. nickName: undefined,
  919. password: undefined,
  920. phonenumber: undefined,
  921. email: undefined,
  922. sex: undefined,
  923. status: "0",
  924. remark: undefined,
  925. // postIds: [],
  926. roleIds: [],
  927. };
  928. this.resetForm("form");
  929. },
  930. /** 搜索按钮操作 */
  931. handleQuery() {
  932. this.queryParams.pageNum = 1;
  933. this.getList();
  934. },
  935. /** 重置按钮操作 */
  936. resetQuery() {
  937. this.dateRange = [];
  938. this.resetForm("queryForm");
  939. this.queryParams.deptId = undefined;
  940. this.$refs.tree.setCurrentKey(null);
  941. this.handleQuery();
  942. },
  943. // 多选框选中数据
  944. handleSelectionChange(selection) {
  945. this.ids = selection.map((item) => item.userId);
  946. this.single = selection.length != 1;
  947. this.multiple = !selection.length;
  948. },
  949. // 更多操作触发
  950. handleCommand(command, row) {
  951. switch (command) {
  952. case "handleResetPwd":
  953. this.handleResetPwd(row);
  954. break;
  955. case "handleAuthRole":
  956. this.handleAuthRole(row);
  957. break;
  958. default:
  959. break;
  960. }
  961. },
  962. /** 新增按钮操作 */
  963. handleAdd() {
  964. this.reset();
  965. getUser().then((response) => {
  966. this.postOptions = response.posts;
  967. this.roleOptions = response.roles;
  968. this.open = true;
  969. this.title = "添加用户";
  970. this.form.password = this.initPassword;
  971. });
  972. },
  973. /** 修改按钮操作 */
  974. handleUpdate(row) {
  975. this.reset();
  976. const userId = row.userId || this.ids;
  977. getUser(userId).then((response) => {
  978. this.form = response.data;
  979. this.postOptions = response.posts;
  980. this.roleOptions = response.roles;
  981. // this.$set(this.form, "postIds", response.postIds);
  982. this.$set(this.form, "roleIds", response.roleIds);
  983. this.open = true;
  984. this.title = "修改用户";
  985. this.form.password = "";
  986. });
  987. },
  988. /** 重置密码按钮操作 */
  989. handleResetPwd(row) {
  990. this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
  991. confirmButtonText: "确定",
  992. cancelButtonText: "取消",
  993. closeOnClickModal: false,
  994. inputPattern: /^.{5,20}$/,
  995. inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
  996. })
  997. .then(({ value }) => {
  998. resetUserPwd(row.userId, value).then((response) => {
  999. this.$modal.msgSuccess("修改成功,新密码是:" + value);
  1000. });
  1001. })
  1002. .catch(() => {});
  1003. },
  1004. /** 分配角色操作 */
  1005. handleAuthRole: function (row) {
  1006. const userId = row.userId;
  1007. this.$router.push("/system/user-auth/role/" + userId);
  1008. },
  1009. /** 提交按钮 */
  1010. submitForm: function () {
  1011. this.$refs["form"].validate((valid) => {
  1012. if (valid) {
  1013. if (this.form.userId != undefined) {
  1014. updateUser(this.form).then((response) => {
  1015. this.$modal.msgSuccess("修改成功");
  1016. this.open = false;
  1017. this.getList();
  1018. });
  1019. } else {
  1020. addUser(this.form).then((response) => {
  1021. this.$modal.msgSuccess("新增成功");
  1022. this.open = false;
  1023. this.getList();
  1024. });
  1025. }
  1026. }
  1027. });
  1028. },
  1029. /** 删除按钮操作 */
  1030. handleDelete(row) {
  1031. const userIds = row.userId || this.ids;
  1032. this.$modal
  1033. .confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
  1034. .then(function () {
  1035. return delUser(userIds);
  1036. })
  1037. .then(() => {
  1038. this.getList();
  1039. this.$modal.msgSuccess("删除成功");
  1040. })
  1041. .catch(() => {});
  1042. },
  1043. /** 导出按钮操作 */
  1044. handleExport() {
  1045. this.download(
  1046. "system/user/export",
  1047. {
  1048. ...this.queryParams,
  1049. },
  1050. `user_${new Date().getTime()}.xlsx`
  1051. );
  1052. },
  1053. /** 导入按钮操作 */
  1054. handleImport() {
  1055. this.upload.title = "用户导入";
  1056. this.upload.open = true;
  1057. },
  1058. /** 下载模板操作 */
  1059. importTemplate() {
  1060. this.download(
  1061. "system/user/importTemplate",
  1062. {},
  1063. `user_template_${new Date().getTime()}.xlsx`
  1064. );
  1065. },
  1066. // 文件上传中处理
  1067. handleFileUploadProgress(event, file, fileList) {
  1068. this.upload.isUploading = true;
  1069. },
  1070. // 文件上传成功处理
  1071. handleFileSuccess(response, file, fileList) {
  1072. this.upload.open = false;
  1073. this.upload.isUploading = false;
  1074. this.$refs.upload.clearFiles();
  1075. this.$alert(
  1076. "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
  1077. response.msg +
  1078. "</div>",
  1079. "导入结果",
  1080. { dangerouslyUseHTMLString: true }
  1081. );
  1082. this.getList();
  1083. },
  1084. // 提交上传文件
  1085. submitFileForm() {
  1086. this.$refs.upload.submit();
  1087. },
  1088. },
  1089. };
  1090. </script>