account.vue 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
  1. <template>
  2. <div class="app-container">
  3. <div class="tree-container">
  4. <div style="padding: 10px; display: flex">
  5. <el-button
  6. icon="el-icon-refresh-right"
  7. size="small"
  8. style="padding: 9px 10px; margin-right: 6px"
  9. @click="refreshDepartment()"
  10. />
  11. <el-input v-model="filterText" placeholder="输入关键字进行过滤" size="small" clearable />
  12. </div>
  13. <el-tree
  14. ref="listTree"
  15. :data="departmentList"
  16. :props="defaultProps"
  17. default-expand-all
  18. highlight-current
  19. :expand-on-click-node="false"
  20. :filter-node-method="filterNode"
  21. node-key="id"
  22. @node-click="handleNodeClick"
  23. >
  24. <div slot-scope="{ node, data }" class="custom-tree-node">
  25. <i
  26. :class="data.children && data.children.length > 0 ? 'el-icon-folder-opened' : 'el-icon-document-remove'"
  27. /><span>{{ node.label }}</span>
  28. </div>
  29. </el-tree>
  30. </div>
  31. <div class="mymain-container">
  32. <div class="screen-container">
  33. <!-- <div class="top clearfix">
  34. <div class="title fl">条件筛选</div>
  35. </div> -->
  36. <Collapse :screen-form="screenForm">
  37. <template #right_btn>
  38. <el-button size="mini" @click="resetScreenForm">清空</el-button>
  39. <el-button size="mini" type="primary" @click="submitScreenForm">搜索</el-button>
  40. </template>
  41. <template #search>
  42. <el-form ref="screenForm" :model="screenForm" label-width="150px" size="mini" label-position="left">
  43. <el-row :gutter="20">
  44. <el-col :xs="24" :sm="12" :lg="8">
  45. <el-form-item label="账号/用户名名称:" prop="name">
  46. <el-input v-model="screenForm.name" placeholder="请输入账号/用户名名称" />
  47. </el-form-item>
  48. </el-col>
  49. <el-col :xs="24" :sm="12" :lg="8">
  50. <el-form-item label="角色:" prop="roleId">
  51. <el-select v-model="screenForm.roleId" class="selectStyle" placeholder="请选择" filterable>
  52. <el-option v-for="(v, i) in roleList" :key="i" :label="v.name" :value="v.adminRoleId" />
  53. </el-select>
  54. </el-form-item>
  55. </el-col>
  56. </el-row>
  57. </el-form>
  58. </template>
  59. </Collapse>
  60. </div>
  61. <div class="btn-group clearfix" style="margin-top: 20px">
  62. <div class="fl">
  63. <el-button size="mini" type="primary" @click="openAccountForm('add')">添加账号</el-button>
  64. </div>
  65. <div class="fr">
  66. <el-button v-if="checkBtnRole('download')" size="mini" @click="handleDownload">下载导入模板</el-button>
  67. <ExportButton class="import-btn" :ex-url="'admin/user/user/listExport'" :ex-params="exParams" />
  68. <ImportButton
  69. class="import-btn"
  70. im-text="批量变更仓库和产品分类"
  71. :im-url="'admin/user/batch/update'"
  72. @importSuccess="getList"
  73. />
  74. <el-upload
  75. v-if="checkBtnRole('import')"
  76. class="import-btn"
  77. action=""
  78. :http-request="handleImport"
  79. :file-list="importFileList"
  80. :show-file-list="false"
  81. >
  82. <!-- v-if="checkBtnRole('import')" -->
  83. <el-button size="mini" type="primary" :loading="importLoading">{{
  84. importLoading ? '导入中...' : '导入'
  85. }}</el-button>
  86. </el-upload>
  87. <!--/admin/user/batch/update
  88. <el-button size="small" type="primary" @click="handleExport">导出</el-button>
  89. <el-button size="small" type="primary" :loading="importLoading" @click="clickImport">{{ importLoading ? '导入中...' : '导入' }}</el-button>
  90. -->
  91. </div>
  92. </div>
  93. <div class="table">
  94. <el-table
  95. v-loading="listLoading"
  96. :data="dataList"
  97. element-loading-text="Loading"
  98. border
  99. fit
  100. highlight-current-row
  101. stripe
  102. >
  103. <!-- <el-table-column align="center" type="selection" width="55" fixed></el-table-column> -->
  104. <el-table-column
  105. show-overflow-tooltip
  106. align="center"
  107. label="账号"
  108. prop="userName"
  109. min-width="120"
  110. />
  111. <el-table-column
  112. show-overflow-tooltip
  113. align="center"
  114. label="用户名"
  115. prop="nickName"
  116. min-width="160"
  117. />
  118. <el-table-column
  119. show-overflow-tooltip
  120. align="center"
  121. label="角色"
  122. prop="roleName"
  123. min-width="100"
  124. />
  125. <el-table-column
  126. show-overflow-tooltip
  127. align="center"
  128. label="修改人"
  129. prop="updateBy"
  130. min-width="160"
  131. />
  132. <el-table-column
  133. show-overflow-tooltip
  134. align="center"
  135. label="修改时间"
  136. prop="updateTime"
  137. min-width="160"
  138. />
  139. <el-table-column
  140. show-overflow-tooltip
  141. align="center"
  142. label="创建时间"
  143. prop="createTime"
  144. min-width="160"
  145. />
  146. <el-table-column
  147. show-overflow-tooltip
  148. align="center"
  149. label="最后登录时间"
  150. prop="lastLoginTime"
  151. min-width="160"
  152. />
  153. <el-table-column show-overflow-tooltip align="center" label="状态" class-name="status-col">
  154. <template slot-scope="scope">
  155. <el-tag size="mini" :type="scope.row.status ? 'success' : 'danger'">{{
  156. scope.row.status ? '正常' : '冻结'
  157. }}</el-tag>
  158. </template>
  159. </el-table-column>
  160. <el-table-column align="center" label="操作" min-width="160">
  161. <template slot-scope="scope">
  162. <template v-if="checkBtnRole('status')">
  163. <el-popconfirm
  164. v-if="scope.row.status"
  165. style="margin-right: 10px"
  166. title="确定冻结吗?"
  167. @onConfirm="changeStatus(scope.row.adminUserId, 0)"
  168. >
  169. <el-button slot="reference" type="text">冻结</el-button>
  170. </el-popconfirm>
  171. <el-popconfirm
  172. v-else
  173. style="margin-right: 10px"
  174. title="确定恢复吗?"
  175. @onConfirm="changeStatus(scope.row.adminUserId, 1)"
  176. >
  177. <el-button slot="reference" type="text">恢复</el-button>
  178. </el-popconfirm>
  179. </template>
  180. <el-button
  181. v-if="checkBtnRole('edit')"
  182. type="text"
  183. @click="openAccountForm('edit', scope.row.adminUserId)"
  184. >编辑</el-button>
  185. <el-button
  186. v-if="checkBtnRole('reset')"
  187. type="text"
  188. @click="handleReset(scope.row.adminUserId)"
  189. >重置密码</el-button>
  190. <!-- <el-popconfirm style="margin-left: 10px;" title="确定删除吗?" @onConfirm="deleteAccount(scope.row.id)" v-if="checkBtnRole('del')">
  191. <el-button slot="reference" type="text">删除</el-button>
  192. </el-popconfirm> -->
  193. </template>
  194. </el-table-column>
  195. </el-table>
  196. </div>
  197. <div class="pagination clearfix">
  198. <div class="fr">
  199. <el-pagination
  200. :current-page="currentPage"
  201. :page-sizes="[10, 20, 30, 50]"
  202. :page-size="10"
  203. layout="total, sizes, prev, pager, next, jumper"
  204. :total="listTotal"
  205. @size-change="handleSizeChange"
  206. @current-change="handleCurrentChange"
  207. />
  208. </div>
  209. </div>
  210. </div>
  211. <!-- 添加编辑账号 -->
  212. <el-dialog
  213. :title="AccountFormType == 'add' ? '添加账号' : '编辑账号'"
  214. :visible.sync="AccountFormVisible"
  215. :show-close="false"
  216. width="40%"
  217. :close-on-click-modal="false"
  218. >
  219. <el-form
  220. ref="AccountForm"
  221. :model="AccountForm"
  222. :rules="AccountFormRules"
  223. label-position="left"
  224. label-width="100px"
  225. >
  226. <el-form-item label="账号" prop="account">
  227. <el-input v-model="AccountForm.account" autocomplete="off" placeholder="请输入账号" />
  228. </el-form-item>
  229. <el-form-item label="用户名" prop="nickName">
  230. <el-input v-model="AccountForm.nickName" autocomplete="off" placeholder="请输入用户名" />
  231. </el-form-item>
  232. <el-form-item label="角色组" prop="role">
  233. <el-select v-model="AccountForm.role" placeholder="请选择角色组" style="width: 100%" filterable>
  234. <el-option
  235. v-for="(item, index) in roleList"
  236. :key="index"
  237. :label="item.name"
  238. :value="item.adminRoleId"
  239. />
  240. </el-select>
  241. </el-form-item>
  242. <el-form-item v-show="roleObj.type === 0" label="部门" prop="department">
  243. <el-tree
  244. ref="tree"
  245. :data="departmentList"
  246. show-checkbox
  247. :check-strictly="true"
  248. node-key="adminWebsitId"
  249. highlight-current
  250. :props="props"
  251. />
  252. </el-form-item>
  253. <el-form-item v-show="roleObj.type === 0 && roleObj.name === '经销商'" label="经销商" prop="dealer">
  254. <el-select v-model="AccountForm.dealer" placeholder="请选择经销商" style="width: 100%" filterable>
  255. <el-option v-for="(item, index) in dealerList" :key="index" :label="item.name" :value="item.id" />
  256. </el-select>
  257. </el-form-item>
  258. <el-form-item v-show="roleObj.type === 1 || roleObj.type === 2" label="商户" prop="merchant">
  259. <el-select v-model="AccountForm.merchant" placeholder="请选择商户" style="width: 100%" filterable>
  260. <el-option
  261. v-for="(item, index) in merchantList"
  262. :key="index"
  263. :label="item.adminCompanyName"
  264. :value="item.adminCompanyId"
  265. />
  266. </el-select>
  267. </el-form-item>
  268. <el-form-item v-show="roleObj.type === 0 && roleObj.name === '经销商'" label="集团公司" prop="isGroup">
  269. <el-radio-group v-model="AccountForm.isGroup">
  270. <el-radio :label="true">是</el-radio>
  271. <el-radio :label="false">否</el-radio>
  272. </el-radio-group>
  273. </el-form-item>
  274. <el-form-item
  275. v-show="roleObj.type === 0 && roleObj.name === '经销商' && !AccountForm.isGroup"
  276. label="所属集团"
  277. prop="company"
  278. >
  279. <el-select v-model="AccountForm.company" placeholder="请选择所属集团" style="width: 100%" filterable>
  280. <el-option v-for="(item, index) in groupList" :key="index" :label="item.name" :value="item.id" />
  281. </el-select>
  282. </el-form-item>
  283. <el-form-item v-show="roleObj.type === 0 && roleObj.name === '经销商'" label="是否折让" prop="isDiscount">
  284. <el-radio-group v-model="AccountForm.isDiscount">
  285. <el-radio :label="true">是</el-radio>
  286. <el-radio :label="false">否</el-radio>
  287. </el-radio-group>
  288. </el-form-item>
  289. <el-form-item v-if="AccountFormType == 'add'" label="密码" prop="newPassword">
  290. <el-input
  291. ref="password1"
  292. v-model="AccountForm.newPassword"
  293. autocomplete="off"
  294. placeholder="请输入密码"
  295. :type="passwordType1"
  296. />
  297. <span class="show-pwd" @click="showPwd(1)">
  298. <svg-icon :icon-class="passwordType1 === 'password' ? 'eye' : 'eye-open'" />
  299. </span>
  300. </el-form-item>
  301. <el-form-item v-if="AccountFormType == 'add'" label="确认密码" prop="confirmPassword">
  302. <el-input
  303. ref="password2"
  304. v-model="AccountForm.confirmPassword"
  305. autocomplete="off"
  306. placeholder="请再次输入密码"
  307. :type="passwordType2"
  308. />
  309. <span class="show-pwd" @click="showPwd(2)">
  310. <svg-icon :icon-class="passwordType2 === 'password' ? 'eye' : 'eye-open'" />
  311. </span>
  312. </el-form-item>
  313. <el-form-item label="可用仓库" prop="correspondIds">
  314. <el-select
  315. v-model="AccountForm.correspondIds"
  316. multiple
  317. placeholder="请选择可用仓库"
  318. style="width: 100%"
  319. filterable
  320. >
  321. <el-option v-for="(item, index) in stockList" :key="index" :label="item.name" :value="item.id" />
  322. </el-select>
  323. </el-form-item>
  324. <el-form-item label="物料分类" prop="k3CategoryIds">
  325. <el-select
  326. v-model="AccountForm.k3CategoryIds"
  327. multiple
  328. placeholder="请选择物料分类"
  329. style="width: 100%"
  330. filterable
  331. >
  332. <el-option
  333. v-for="(item, index) in categoryList"
  334. :key="index"
  335. :label="item.name"
  336. :value="item.id"
  337. />
  338. </el-select>
  339. </el-form-item>
  340. <el-form-item v-if="roleObj.name === '经销商'" label="商用经销商" prop="isShangyong">
  341. <el-radio-group v-model="AccountForm.isShangyong" size="mini">
  342. <el-radio v-for="item in [{label:'是',value:true},{label:'否', value:false}]" :key="item.value" :label="item.value">
  343. {{item.label}}
  344. </el-radio>
  345. </el-radio-group>
  346. </el-form-item>
  347. </el-form>
  348. <div slot="footer" class="dialog-footer">
  349. <el-button @click="cancelAccountForm">取 消</el-button>
  350. <el-button type="primary" @click="submitAccountForm">确 定</el-button>
  351. </div>
  352. </el-dialog>
  353. <!-- 重置密码 -->
  354. <el-dialog
  355. title="重置密码"
  356. :visible.sync="resetFormVisible"
  357. :show-close="false"
  358. width="40%"
  359. :close-on-click-modal="false"
  360. >
  361. <el-form ref="resetForm" :model="resetForm" :rules="resetFormRules" label-position="left" label-width="100px">
  362. <el-form-item label="输入新密码" prop="newPassword">
  363. <el-input
  364. ref="password1"
  365. v-model="resetForm.newPassword"
  366. autocomplete="off"
  367. placeholder="请输入新密码"
  368. :type="passwordType1"
  369. />
  370. <span class="show-pwd" @click="showPwd(1)">
  371. <svg-icon :icon-class="passwordType1 === 'password' ? 'eye' : 'eye-open'" />
  372. </span>
  373. </el-form-item>
  374. <el-form-item label="确认密码" prop="confirmPassword">
  375. <el-input
  376. ref="password2"
  377. v-model="resetForm.confirmPassword"
  378. autocomplete="off"
  379. placeholder="请再次输入新密码"
  380. :type="passwordType2"
  381. />
  382. <span class="show-pwd" @click="showPwd(2)">
  383. <svg-icon :icon-class="passwordType2 === 'password' ? 'eye' : 'eye-open'" />
  384. </span>
  385. </el-form-item>
  386. </el-form>
  387. <div slot="footer" class="dialog-footer">
  388. <el-button @click="cancelResetForm">取 消</el-button>
  389. <el-button type="primary" @click="submitResetForm">确 定</el-button>
  390. </div>
  391. </el-dialog>
  392. </div>
  393. </template>
  394. <script>
  395. import {
  396. getStockListStock,
  397. getDepartmentList,
  398. getAccountList,
  399. addAccount,
  400. editAccount,
  401. deleteAccount,
  402. getAccountDetail,
  403. getRoleList,
  404. getMerchantList,
  405. changeAccountStatus,
  406. resetPassword
  407. } from '@/api/setting'
  408. import { getDealerList, getCategoryList } from '@/api/common'
  409. import { findElem, downloadFiles, handleImportTwo } from '@/utils/util'
  410. export default {
  411. data() {
  412. var validatePass = (rule, value, callback) => {
  413. if (value === '') {
  414. callback(new Error('请输入新密码'))
  415. } else if (value && value.length < 6) {
  416. callback(new Error('密码长度至少6位'))
  417. } else {
  418. if (this.resetForm.confirmPassword !== '') {
  419. this.$refs.resetForm.validateField('confirmPassword')
  420. }
  421. callback()
  422. }
  423. }
  424. var validatePass2 = (rule, value, callback) => {
  425. if (value === '') {
  426. callback(new Error('请再次输入密码'))
  427. } else if (value !== this.resetForm.newPassword) {
  428. callback(new Error('两次输入密码不一致'))
  429. } else {
  430. callback()
  431. }
  432. }
  433. var validatePass3 = (rule, value, callback) => {
  434. if (value === '') {
  435. callback(new Error('请输入新密码'))
  436. } else if (value && value.length < 6) {
  437. callback(new Error('密码长度至少6位'))
  438. } else {
  439. if (this.AccountForm.confirmPassword !== '') {
  440. this.$refs.AccountForm.validateField('confirmPassword')
  441. }
  442. callback()
  443. }
  444. }
  445. var validatePass4 = (rule, value, callback) => {
  446. if (value === '') {
  447. callback(new Error('请再次输入密码'))
  448. } else if (value !== this.AccountForm.newPassword) {
  449. callback(new Error('两次输入密码不一致'))
  450. } else {
  451. callback()
  452. }
  453. }
  454. var validateName = (rule, value, callback) => {
  455. if (!/^[A-Za-z0-9]+$/.test(value)) {
  456. callback(new Error('帐号只能用英文字母和数字组成'))
  457. } else {
  458. callback()
  459. }
  460. }
  461. return {
  462. stockList: [], // 仓库列表
  463. baseURL: process.env.VUE_APP_BASE_API,
  464. dataList: null, // 列表数据
  465. moduleList: null, // 模块列表
  466. listLoading: true, // 列表加载loading
  467. screenForm: {
  468. // 筛选表单数据
  469. name: '', // 名称
  470. roleId: ''
  471. },
  472. currentPage: 1, // 当前页码
  473. pageSize: 10, // 每页数量
  474. listTotal: 0, // 列表总数
  475. selectDepartment: null, // 选中的部门
  476. isCollapse: true,
  477. AccountFormType: 'add',
  478. AccountFormVisible: false,
  479. AccountForm: {
  480. account: '', // 账号
  481. nickName: '', // 用户名
  482. merchant: '', // 商户
  483. dealer: '', // 经销商
  484. role: '', // 角色组
  485. correspondIds: [], // 仓库
  486. isGroup: false,
  487. company: '',
  488. isDiscount: true,
  489. newPassword: '', // 新密码
  490. confirmPassword: '', // 确认密码
  491. k3CategoryIds: [],
  492. isShangyong: false, // 是否商用经销商
  493. },
  494. AccountFormRules: {
  495. account: [{ required: true, validator: validateName, trigger: 'blur' }],
  496. nickName: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  497. role: [{ required: true, message: '请选择角色组', trigger: 'change' }],
  498. correspondIds: [{ required: true, message: '请选择可用仓库', trigger: 'change' }],
  499. isShangyong: [{ required: true, message: '请选择商用经销商', trigger: 'change' }],
  500. newPassword: [{ required: true, validator: validatePass3, trigger: 'blur' }],
  501. confirmPassword: [{ required: true, validator: validatePass4, trigger: 'blur' }]
  502. },
  503. editAccountId: null,
  504. categoryList: [],
  505. filterText: '',
  506. departmentList: [],
  507. defaultProps: {
  508. children: 'children',
  509. label: 'name'
  510. },
  511. props: {
  512. multiple: true,
  513. value: 'adminWebsitId',
  514. label: 'name',
  515. children: 'children'
  516. },
  517. tableSelection: [],
  518. importLoading: false, // 导入加载loading
  519. importFileList: [], // 导入列表
  520. resetId: null,
  521. resetFormVisible: false,
  522. resetForm: {
  523. newPassword: '', // 新密码
  524. confirmPassword: '' // 确认密码
  525. },
  526. resetFormRules: {
  527. newPassword: [{ required: true, validator: validatePass, trigger: 'blur' }],
  528. confirmPassword: [{ required: true, validator: validatePass2, trigger: 'blur' }]
  529. },
  530. roleList: [], // 角色列表
  531. roleObj: {}, // 选中的角色
  532. merchantList: [],
  533. dealerList: [],
  534. groupList: [],
  535. passwordType1: 'password',
  536. passwordType2: 'password'
  537. }
  538. },
  539. computed: {
  540. exParams() {
  541. return {
  542. userName: this.screenForm.name,
  543. roleId: this.screenForm.roleId,
  544. isMaster: true
  545. }
  546. }
  547. },
  548. watch: {
  549. filterText(val) {
  550. this.$refs.listTree.filter(val)
  551. },
  552. 'AccountForm.role'() {
  553. if (this.AccountForm.role) {
  554. const index = findElem(this.roleList, 'adminRoleId', this.AccountForm.role)
  555. this.roleObj = this.roleList[index]
  556. }
  557. }
  558. },
  559. async created() {
  560. this.getTree()
  561. this.getList()
  562. this.getStockList()
  563. await this.getRoleList()
  564. },
  565. methods: {
  566. // 获取仓库仓位对应关系列表
  567. async getStockList() {
  568. const res = await getStockListStock({ pageSize: -1, pageNum: 1 })
  569. this.stockList = res.data.records
  570. },
  571. // 查询按钮权限
  572. checkBtnRole(value) {
  573. // let btnRole = this.$route.meta.roles;
  574. // if(!btnRole) {return true}
  575. // let index = btnRole.indexOf(value);
  576. // return index >= 0 ? true : false;
  577. return true
  578. },
  579. // 获取角色列表
  580. async getRoleList() {
  581. const result = await new Promise((resolve, reject) => {
  582. getRoleList({ pageNum: 1, pageSize: -1 })
  583. .then(res => {
  584. this.roleList = res.data.records
  585. resolve(res.data)
  586. })
  587. .catch(res => {
  588. resolve([])
  589. })
  590. })
  591. return result
  592. },
  593. // 获取金蝶品类
  594. async getCategoryList() {
  595. const result = await new Promise((resolve, reject) => {
  596. getCategoryList({ pageNum: 1, pageSize: -1 })
  597. .then(res => {
  598. this.categoryList = res.data.records
  599. resolve(res.data)
  600. })
  601. .catch(res => {
  602. resolve([])
  603. })
  604. })
  605. return result
  606. },
  607. // 获取商户列表
  608. async getMerchantList() {
  609. const result = await new Promise((resolve, reject) => {
  610. getMerchantList({
  611. pageNum: 1,
  612. pageSize: -1
  613. })
  614. .then(res => {
  615. this.merchantList = res.data.records
  616. resolve(res.data.records)
  617. })
  618. .catch(res => {
  619. resolve([])
  620. })
  621. })
  622. return result
  623. },
  624. // 获取经销商列表
  625. async getDealerList(id) {
  626. const result = await new Promise((resolve, reject) => {
  627. getDealerList({
  628. pageNum: 1,
  629. pageSize: -1,
  630. bindUser: false,
  631. adminUserId: id || ''
  632. })
  633. .then(res => {
  634. this.dealerList = res.data.records
  635. resolve(res.data.records)
  636. })
  637. .catch(res => {
  638. resolve([])
  639. })
  640. })
  641. return result
  642. },
  643. // 获取集团列表
  644. async getGroupList(id) {
  645. const result = await new Promise((resolve, reject) => {
  646. getDealerList({
  647. pageNum: 1,
  648. pageSize: -1
  649. })
  650. .then(res => {
  651. this.groupList = res.data.records
  652. resolve(res.data.records)
  653. })
  654. .catch(res => {
  655. resolve([])
  656. })
  657. })
  658. return result
  659. },
  660. // 获取部门列表
  661. getTree() {
  662. getDepartmentList().then(res => {
  663. this.departmentList = res.data
  664. })
  665. },
  666. // 获取账号列表
  667. getList() {
  668. this.listLoading = true
  669. const params = {
  670. pageNum: this.currentPage,
  671. pageSize: this.pageSize,
  672. adminWebsitId: this.selectDepartment ? this.selectDepartment.adminWebsitId : '',
  673. userName: this.screenForm.name,
  674. roleId: this.screenForm.roleId,
  675. isMaster: true
  676. }
  677. getAccountList(params).then(res => {
  678. this.dataList = res.data.records
  679. this.listTotal = res.data.total
  680. this.listLoading = false
  681. })
  682. },
  683. // 更改每页数量
  684. handleSizeChange(val) {
  685. this.pageSize = val
  686. this.currentPage = 1
  687. this.getList()
  688. },
  689. // 更改当前页
  690. handleCurrentChange(val) {
  691. this.currentPage = val
  692. this.getList()
  693. },
  694. // 提交筛选表单
  695. submitScreenForm() {
  696. this.currentPage = 1
  697. this.getList()
  698. },
  699. // 重置筛选表单
  700. resetScreenForm() {
  701. this.$refs.screenForm.resetFields()
  702. this.currentPage = 1
  703. this.getList()
  704. },
  705. // 筛选部门
  706. filterNode(value, data) {
  707. if (!value) return true
  708. return data.name.indexOf(value) !== -1
  709. },
  710. // 选择部门
  711. handleNodeClick(data) {
  712. console.log(data)
  713. if (this.selectDepartment && data.adminWebsitId === this.selectDepartment.adminWebsitId) {
  714. this.$refs.listTree.setCurrentKey(null)
  715. this.selectDepartment = null
  716. } else {
  717. this.selectDepartment = data
  718. }
  719. this.getList()
  720. },
  721. // 刷新部门
  722. refreshDepartment() {
  723. this.$refs.listTree.setCurrentKey(null)
  724. this.selectDepartment = null
  725. this.getTree()
  726. this.getList()
  727. },
  728. // 打开 新增编辑 账号表单
  729. async openAccountForm(type, id) {
  730. this.AccountFormType = type
  731. this.AccountFormVisible = true
  732. await this.getMerchantList()
  733. await this.getDealerList(id)
  734. await this.getGroupList(id)
  735. await this.getRoleList()
  736. await this.getCategoryList()
  737. if (type == 'add') {
  738. if (this.selectDepartment) {
  739. this.$refs.tree.setCheckedKeys([this.selectDepartment.adminWebsitId])
  740. }
  741. }
  742. if (type == 'edit') {
  743. this.editAccountId = id
  744. getAccountDetail({ adminUserId: id }).then(res => {
  745. console.log(res, 78787)
  746. this.AccountForm.account = res.data.userName
  747. this.AccountForm.role = res.data.roleId
  748. this.AccountForm.nickName = res.data.nickName
  749. this.AccountForm.merchant = res.data.companyWechatId
  750. this.AccountForm.dealer = res.data.customerId
  751. this.AccountForm.isGroup = res.data.isGroupCompany
  752. this.AccountForm.company = res.data.groupCompanyId
  753. this.AccountForm.isDiscount = res.data.isZr
  754. this.AccountForm.correspondIds = res.data.stockCorrespondList
  755. this.AccountForm.k3CategoryIds = res.data.k3CategoryList
  756. this.AccountForm.isShangyong = res.data.isShangyong
  757. this.$refs.tree.setCheckedKeys(res.data.adminWebsitIds || [])
  758. })
  759. }
  760. },
  761. // 取消 新增编辑 账号表单
  762. cancelAccountForm() {
  763. this.AccountFormVisible = false
  764. this.$refs.AccountForm.resetFields()
  765. this.passwordType1 = 'password'
  766. this.passwordType2 = 'password'
  767. },
  768. // 提交 账号表单
  769. submitAccountForm() {
  770. console.log(this.AccountForm.correspondIds)
  771. this.$refs.AccountForm.validate(valid => {
  772. if (valid) {
  773. const categoryIds = []
  774. this.categoryList.map(k => {
  775. this.AccountForm.k3CategoryIds.map(i => {
  776. if (i == k.id) {
  777. categoryIds.push({
  778. k3CategoryId: k.id,
  779. k3CategoryName: k.name,
  780. k3CategoryNumber: k.number
  781. })
  782. }
  783. })
  784. })
  785. const params = {
  786. userName: this.AccountForm.account,
  787. nickName: this.AccountForm.nickName,
  788. roleId: this.AccountForm.role,
  789. password: this.AccountForm.newPassword,
  790. correspondIds: this.AccountForm.correspondIds,
  791. isShangyong: this.AccountForm.isShangyong,
  792. categoryIds
  793. }
  794. if (this.roleObj.type === 0) {
  795. params.adminWebsitIds = this.$refs.tree.getCheckedKeys()
  796. params.roleName = this.roleObj.name
  797. if (this.roleObj.name === '经销商') {
  798. params.customerId = this.AccountForm.dealer
  799. params.isGroupCompany = this.AccountForm.isGroup
  800. params.parentCustomerId = this.AccountForm.company
  801. params.isZr = this.AccountForm.isDiscount
  802. }
  803. } else {
  804. params.adminCompanyId = this.AccountForm.merchant
  805. }
  806. if (this.AccountFormType == 'edit') {
  807. params.adminUserId = this.editAccountId
  808. editAccount(params).then(res => {
  809. this.cancelAccountForm()
  810. this.getList()
  811. this.$successMsg('编辑成功')
  812. })
  813. } else {
  814. addAccount(params).then(res => {
  815. this.cancelAccountForm()
  816. this.getList()
  817. this.$successMsg('添加成功')
  818. })
  819. }
  820. }
  821. })
  822. },
  823. // 表格选择列
  824. handleTableSelection(val) {
  825. this.tableSelection = val
  826. },
  827. // 批量删除账号
  828. batchDeleteAccount() {
  829. if (this.tableSelection.length < 1) {
  830. return this.$errorMsg('至少选择一名账号')
  831. }
  832. this.$confirm(`确定删除选中的账号吗?`, '提示', {
  833. confirmButtonText: '确定',
  834. cancelButtonText: '取消',
  835. type: 'warning'
  836. })
  837. .then(() => {
  838. const AccountIds = []
  839. this.tableSelection.forEach(item => {
  840. AccountIds.push(item.id)
  841. })
  842. deleteAccount({ id: AccountIds.join(',') }).then(res => {
  843. this.$successMsg()
  844. this.getTree()
  845. this.getList()
  846. })
  847. })
  848. .catch(() => {})
  849. },
  850. // 删除账号
  851. deleteAccount(id) {
  852. deleteAccount({ id: id }).then(res => {
  853. this.$successMsg()
  854. this.getTree()
  855. this.getList()
  856. })
  857. },
  858. // 操作 - 更改状态(type: 禁用0,启用1)
  859. changeStatus(id, type) {
  860. type = !!type
  861. changeAccountStatus({ adminUserId: id, status: type }).then(res => {
  862. this.getList()
  863. this.$successMsg()
  864. })
  865. },
  866. // 显示隐藏密码
  867. showPwd(num) {
  868. if (num == 1) {
  869. if (this.passwordType1 === 'password') {
  870. this.passwordType1 = ''
  871. } else {
  872. this.passwordType1 = 'password'
  873. }
  874. this.$nextTick(() => {
  875. this.$refs.password1.focus()
  876. })
  877. }
  878. if (num == 2) {
  879. if (this.passwordType2 === 'password') {
  880. this.passwordType2 = ''
  881. } else {
  882. this.passwordType2 = 'password'
  883. }
  884. this.$nextTick(() => {
  885. this.$refs.password2.focus()
  886. })
  887. }
  888. },
  889. // 重置密码
  890. handleReset(id) {
  891. this.resetId = id
  892. this.resetFormVisible = true
  893. },
  894. // 取消重置密码
  895. cancelResetForm() {
  896. this.resetFormVisible = false
  897. this.passwordType1 = 'password'
  898. this.passwordType2 = 'password'
  899. this.$refs.resetForm.resetFields()
  900. },
  901. // 提交重置密码
  902. submitResetForm() {
  903. this.$refs.resetForm.validate(valid => {
  904. if (valid) {
  905. const params = {
  906. password: this.resetForm.newPassword,
  907. adminUserId: this.resetId
  908. }
  909. resetPassword(params).then(res => {
  910. this.cancelResetForm()
  911. this.getList()
  912. this.$successMsg()
  913. })
  914. }
  915. })
  916. },
  917. // 导出
  918. handleExport() {
  919. const screenData = {
  920. adminWebsitId: this.selectDepartment ? this.selectDepartment.websitId : '',
  921. keyword: this.screenForm.name
  922. }
  923. downloadFiles('wechat/enterprise/export', screenData)
  924. },
  925. // 下载导入模版
  926. handleDownload() {
  927. downloadFiles('admin/user/download')
  928. },
  929. clickImport() {
  930. if (!this.selectDepartment) {
  931. return this.$errorMsg('请选择部门')
  932. } else {
  933. document.querySelector('.import-btn input').click()
  934. }
  935. },
  936. // 导入
  937. async handleImport(param) {
  938. console.log(param)
  939. this.importLoading = true
  940. const file = param.file
  941. const formData = new FormData()
  942. formData.append('file', file)
  943. const result = await handleImportTwo('/admin/user/importUser', formData)
  944. this.importLoading = false
  945. this.importFileList = []
  946. // console.log(result,999);
  947. if (result) {
  948. this.$alert(result.message, '导入成功', {
  949. confirmButtonText: '确定'
  950. })
  951. const blob = new Blob([result], {
  952. type: 'application/vnd.ms-excel,charset=utf-8'
  953. })
  954. const urll = window.URL.createObjectURL(blob)
  955. const link = document.createElement('a')
  956. link.download = '导入失败数据.xlsx'
  957. link.href = urll
  958. link.click()
  959. this.getList()
  960. } else {
  961. this.$alert(result.message, '导入失败', {
  962. confirmButtonText: '确定'
  963. })
  964. }
  965. }
  966. }
  967. }
  968. </script>
  969. <style scoped lang="scss">
  970. .import-btn {
  971. display: inline-block;
  972. margin-left: 10px;
  973. }
  974. .app-container {
  975. display: flex;
  976. .tree-container {
  977. width: 18%;
  978. height: calc(100vh - 110px);
  979. flex-shrink: 0;
  980. background: #f5f5f5;
  981. margin-right: 2%;
  982. display: flex;
  983. flex-direction: column;
  984. overflow-y: hidden;
  985. .el-tree {
  986. height: 100%;
  987. background: none;
  988. width: 100%;
  989. overflow: scroll;
  990. // ::v-deep .el-tree-node:focus > .el-tree-node__content {
  991. // color: #ffffff;
  992. // background-color: #409EFF;
  993. // }
  994. ::v-deep > .el-tree-node {
  995. display: inline-block;
  996. min-width: 100%;
  997. }
  998. ::v-deep .el-tree-node > .el-tree-node__content {
  999. padding-right: 10px;
  1000. align-self: baseline;
  1001. }
  1002. ::v-deep .el-tree-node.is-current > .el-tree-node__content {
  1003. background-color: #409eff;
  1004. .custom-tree-node {
  1005. i {
  1006. color: #fff;
  1007. }
  1008. span {
  1009. color: #fff;
  1010. }
  1011. }
  1012. }
  1013. ::v-deep .el-tree-node > .el-tree-node__children {
  1014. overflow: unset;
  1015. }
  1016. .custom-tree-node {
  1017. i {
  1018. font-size: 14px;
  1019. color: #999;
  1020. }
  1021. span {
  1022. font-size: 14px;
  1023. margin-left: 6px;
  1024. color: #666;
  1025. }
  1026. }
  1027. }
  1028. }
  1029. .mymain-container {
  1030. width: 80%;
  1031. margin-top: 0;
  1032. }
  1033. }
  1034. ::v-deep .el-divider--vertical {
  1035. margin: 0 15px;
  1036. }
  1037. .show-pwd {
  1038. position: absolute;
  1039. right: 15px;
  1040. top: 0;
  1041. font-size: 16px;
  1042. cursor: pointer;
  1043. user-select: none;
  1044. }
  1045. </style>