UserList.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. <template>
  2. <a-card :bordered="false">
  3. <!-- 查询区域 -->
  4. <div class="table-page-search-wrapper">
  5. <a-form layout="inline" @keyup.enter.native="searchQuery">
  6. <a-row :gutter="24">
  7. <a-col :md="6" :sm="8">
  8. <a-form-item label="真实名字">
  9. <a-input @change="clearSpace" placeholder="请输入真实名字" v-model="queryParam.realname"></a-input>
  10. </a-form-item>
  11. </a-col>
  12. <a-col :md="6" :sm="8">
  13. <a-form-item label="工号">
  14. <a-input @change="clearSpaces" placeholder="请输入工号查询" v-model="queryParam.workNo"></a-input>
  15. </a-form-item>
  16. </a-col>
  17. <a-col :md="6" :sm="8">
  18. <a-form-item label="部门名称">
  19. <a-input @click="openModal" placeholder="请点击选择部门" v-model="departNames" readOnly >
  20. <a-icon slot="prefix" type="cluster" title="部门选择控件"/>
  21. <a-icon v-if="queryParam.orgCodeTxt!=null&&queryParam.orgCodeTxt!=''" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
  22. </a-input>
  23. <!-- <j-select-depart v-model="queryParam.orgCodeTxt"/> -->
  24. <!-- <j-tree-select
  25. style="width: 200px"
  26. v-model="queryParam.orgCodeTxt"
  27. dict="sys_depart,depart_name,id"
  28. pid-field="parent_id">
  29. </j-tree-select> -->
  30. </a-form-item>
  31. </a-col>
  32. <a-col :md="6" :sm="8">
  33. <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
  34. <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
  35. <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
  36. <a @click="handleToggleSearch" style="margin-left: 8px">
  37. {{ toggleSearchStatus ? '收起' : '展开' }}
  38. <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
  39. </a>
  40. </span>
  41. </a-col>
  42. </a-row>
  43. <template v-if="toggleSearchStatus">
  44. <a-row :gutter="24">
  45. <a-col :md="6" :sm="8">
  46. <a-form-item label="性别">
  47. <a-select placeholder="请选择性别"
  48. v-model="queryParam.sex"
  49. :getPopupContainer="(target) => target.parentNode">
  50. <a-select-option :value="1">男</a-select-option>
  51. <a-select-option :value="2">女</a-select-option>
  52. </a-select>
  53. </a-form-item>
  54. </a-col>
  55. <a-col :md="6" :sm="8">
  56. <a-form-item label="入职日期">
  57. <a-range-picker
  58. style="width: 210px"
  59. format="YYYY-MM-DD"
  60. :placeholder="['开始时间', '结束时间']"
  61. @change="onDateChange"
  62. />
  63. </a-form-item>
  64. </a-col>
  65. <a-col :md="6" :sm="8">
  66. <a-form-item label="试用结束日期">
  67. <a-range-picker
  68. style="width: 210px"
  69. format="YYYY-MM-DD"
  70. :placeholder="['开始时间', '结束时间']"
  71. @change="onDateChanges"
  72. />
  73. </a-form-item>
  74. </a-col>
  75. </a-row>
  76. <a-row :gutter="24">
  77. <a-col :md="6" :sm="12" style="width: 50%;">
  78. <a-form-item label="人员类别">
  79. <j-multi-select-tag
  80. v-model="queryParam.categorys" placeholder="请选择人员类别"
  81. dictCode="category"/>
  82. </j-multi-select-tag>
  83. </a-form-item>
  84. </a-col>
  85. <a-col :md="6" :sm="12" style="width: 50%;">
  86. <a-form-item label="雇佣状态">
  87. <j-multi-select-tag
  88. v-model="queryParam.empStatus"
  89. dictCode="employmentStatus"
  90. placeholder="请选择雇佣状态">
  91. </j-multi-select-tag>
  92. </a-form-item>
  93. </a-col>
  94. </a-row>
  95. </template>
  96. </a-form>
  97. </div>
  98. <!-- 操作按钮区域 -->
  99. <div class="table-operator" style="border-top: 5px">
  100. <a-button @click="handleAdd()" type="primary" icon="plus" v-has="'user:add'" >添加员工</a-button>
  101. <a-button @click="handleExportXltx()"type="primary" icon="plus" v-has="'user:usermb'" >员工模板</a-button>
  102. <a-button @click="handleExportXls3('薪资模板')"type="primary" icon="plus" v-has="'user:changemb'" >薪资模板</a-button>
  103. <a-button type="primary" icon="download" @click="handleExportXls('用户信息')" v-has='"user:export"'>导出</a-button>
  104. <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel" v-has='"user:import"'>
  105. <a-button type="primary" icon="import">员工导入</a-button>
  106. </a-upload>
  107. <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrls" @change="handleImportExcels" >
  108. <a-button type="primary" icon="import">薪资导入</a-button>
  109. </a-upload>
  110. <a-button type="primary" icon="download" @click="handleExportXlst('员工假期')" v-has='"user:vation"'>假期导出</a-button>
  111. <a-button type="primary" icon="hdd" @click="recycleBinVisible=true" v-has='"user:recovery"'>回收站</a-button>
  112. <a-dropdown v-if="selectedRowKeys.length > 0&&selectionRows[0].employmentStatus==40">
  113. <a-menu slot="overlay" @click="handleMenuClick">
  114. <a-menu-item key="1" v-if="selectionRows[0].employmentStatus==40" v-has='"user:delete"'>
  115. <a-icon type="delete" @click="batchDel" />
  116. 删除
  117. </a-menu-item>
  118. <a-menu-item key="4" v-if="selectionRows[0].employmentStatus==40" v-has='"user:rz"'>
  119. <a-icon type="check-circle" @click="batchrz"/>
  120. 入职
  121. </a-menu-item>
  122. </a-menu>
  123. <a-button style="margin-left: 8px">
  124. 批量操作
  125. <a-icon type="down"/>
  126. </a-button>
  127. </a-dropdown>
  128. <!-- <j-super-query :fieldList="superQueryFieldList" @handleSuperQuery="handleSuperQuery" v-has='"user:query"'/> -->
  129. </div>
  130. <!-- table区域-begin -->
  131. <div>
  132. <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
  133. <i class="anticon anticon-info-circle ant-alert-icon"></i>已选择&nbsp;<a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项&nbsp;&nbsp;
  134. <a style="margin-left: 24px" @click="onClearSelected">清空</a>
  135. </div>
  136. <a-table
  137. ref="table"
  138. bordered
  139. size="middle"
  140. rowKey="id"
  141. :columns="columns"
  142. :dataSource="dataSource"
  143. :pagination="ipagination"
  144. :loading="loading"
  145. :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
  146. @change="handleTableChange" :scroll="{ y: 700,x:1100 }">
  147. <template slot="avatarslot" slot-scope="text, record, index">
  148. <div class="anty-img-wrap">
  149. <a-avatar shape="square" :src="getAvatarView(record.avatar)" icon="user"/>
  150. </div>
  151. </template>
  152. <template slot="userRealname" slot-scope="text, record, index">
  153. <div class="anty-img-wrap">
  154. <a @click="handleDetails(record)" >{{text}}</a>
  155. </div>
  156. </template>
  157. <span slot="categorys" slot-scope="text, record, index">
  158. <a-tag color="#87d068">{{text}}</a-tag>
  159. </span>
  160. <span slot="employmentStatuss" slot-scope="text, record, index">
  161. <a-tag color="#87d068" v-if="record.employmentStatus=='10'||record.employmentStatus==10 ">在职</a-tag>
  162. <a-tag color="#cd201f" v-else-if="record.employmentStatus=='20'||record.employmentStatus==20 ">离退</a-tag>
  163. <a-tag color="#cd201f" v-else-if="record.employmentStatus=='30'||record.employmentStatus==30 ">离职</a-tag>
  164. <a-tag color="blue" v-else-if="record.employmentStatus=='40'||record.employmentStatus==40 ">待入职</a-tag>
  165. </span>
  166. <span slot="action" slot-scope="text, record">
  167. <a @click="handleEdit(record)" v-has='"user:edit"'>编辑</a>
  168. <a-divider type="vertical"/>
  169. <a @click="handleChangePassword(record.username)" v-has='"user:editpwd"'>修改密码</a>
  170. <!-- <a-dropdown v-has='"user:more"'>
  171. <a class="ant-dropdown-link">
  172. 更多 <a-icon type="down"/>
  173. </a>
  174. <a-menu slot="overlay">
  175. <a-menu-item v-has="'user:details'" v-if="record.employmentStatus==40||record.employmentStatus=='40'">
  176. <a href="javascript:;" @click="handleDetails(record)">入职</a>
  177. </a-menu-item>
  178. <a-menu-item v-has='"user:delete"'>
  179. <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
  180. <a>删除</a>
  181. </a-popconfirm>
  182. </a-menu-item>
  183. </a-menu>
  184. </a-dropdown> -->
  185. </span>
  186. </a-table>
  187. </div>
  188. <!-- table区域-end -->
  189. <user-modal ref="modalForm" @ok="modalFormOk"></user-modal>
  190. <user-detail-modal ref="userdetailmodal"></user-detail-modal>
  191. <password-modal ref="passwordmodal" @ok="passwordModalOk"></password-modal>
  192. <depart-window ref="departWindow" @ok="modalFormOks"></depart-window>
  193. <!-- 用户回收站 -->
  194. <user-recycle-bin-modal :visible.sync="recycleBinVisible" @ok="modalFormOk"/>
  195. </a-card>
  196. </template>
  197. <script>
  198. import UserModal from './modules/UserModal'
  199. import departWindow from './modules/DepartWindow'
  200. import UserDetailModal from './modules/UserDetailModal'
  201. import PasswordModal from './modules/PasswordModal'
  202. import {putAction,getFileAccessHttpUrl,getAction,downFile} from '@/api/manage';
  203. import {frozenBatch} from '@/api/api'
  204. import {JeecgListMixin} from '@/mixins/JeecgListMixin'
  205. import JInput from '@/components/jeecg/JInput'
  206. import UserRecycleBinModal from './modules/UserRecycleBinModal'
  207. import JSuperQuery from '@/components/jeecg/JSuperQuery'
  208. import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
  209. import JTreeSelect from '@/components/jeecg/JTreeSelect'
  210. import JDictSelectTag from '@/components/dict/JDictSelectTag'
  211. import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
  212. import store from '@/store'
  213. import { filterObj } from '@/utils/util';
  214. import {Modal} from 'ant-design-vue'
  215. import Vue from 'vue'
  216. export default {
  217. name: "UserList",
  218. mixins: [JeecgListMixin],
  219. components: {
  220. UserModal,
  221. PasswordModal,
  222. JInput,
  223. UserRecycleBinModal,
  224. departWindow,
  225. UserDetailModal,
  226. JSuperQuery,
  227. JSelectDepart,
  228. JTreeSelect,
  229. JDictSelectTag
  230. },
  231. data() {
  232. return {
  233. description: '这是用户管理页面',
  234. queryParam: {
  235. empStatus:"10",
  236. categorys:null,
  237. orgCodeTxt:null,
  238. rzDate:null,
  239. syDate:null,
  240. sex:null
  241. },
  242. departNames:null,
  243. recycleBinVisible: false,
  244. selectedRowKeys:[],
  245. selectionRows:[],
  246. columns: [
  247. /*{
  248. title: '#',
  249. dataIndex: '',
  250. key:'rowIndex',
  251. width:60,
  252. align:"center",
  253. customRender:function (t,r,index) {
  254. return parseInt(index)+1;
  255. }
  256. },*/
  257. {
  258. title: '工号',
  259. align: "center",
  260. dataIndex: 'workNo',
  261. width: 100,
  262. sorter: true
  263. },
  264. {
  265. title: '员工姓名',
  266. align: "center",
  267. width: 100,
  268. dataIndex: 'realname',
  269. scopedSlots: {customRender: "userRealname"},
  270. sorter: true
  271. },
  272. // {
  273. // title: '头像',
  274. // align: "center",
  275. // width: 100,
  276. // dataIndex: 'avatar',
  277. // scopedSlots: {customRender: "avatarslot"}
  278. // },
  279. {
  280. title: '性别',
  281. align: "center",
  282. width: 80,
  283. dataIndex: 'sex_dictText',
  284. sorter: true
  285. },
  286. // {
  287. // title: '生日',
  288. // align: "center",
  289. // width: 100,
  290. // dataIndex: 'birthday'
  291. // },
  292. // {
  293. // title: '手机号码',
  294. // align: "center",
  295. // width: 120,
  296. // dataIndex: 'phone',
  297. // customRender:function (t,r,index) {
  298. // if(t!=null&&t!=""){
  299. // var a=t.slice(0,3);
  300. // var b=t.slice(8,11);
  301. // return a+"****"+b;
  302. // }else{
  303. // return"";
  304. // }
  305. // }
  306. // },
  307. {
  308. title: '邮箱',
  309. align: "center",
  310. width: 120,
  311. dataIndex: 'email',
  312. sorter: true
  313. },
  314. {
  315. title: '一级部门',
  316. align: "center",
  317. width: 120,
  318. dataIndex: 'del2',
  319. },
  320. {
  321. title: '末级部门',
  322. align: "center",
  323. width: 120,
  324. dataIndex: 'del3'
  325. },
  326. // {
  327. // title: '三级部门',
  328. // align: "center",
  329. // width: 120,
  330. // dataIndex: 'del4'
  331. // },
  332. {
  333. title: '职位',
  334. align: "center",
  335. width: 120,
  336. dataIndex: 'post_dictText',
  337. sorter: true
  338. },
  339. {
  340. title: '入职时间',
  341. align: "center",
  342. width: 120,
  343. dataIndex: 'entryDate',
  344. sorter: true
  345. },
  346. {
  347. title: '试用期结束时间',
  348. align: "center",
  349. width: 120,
  350. dataIndex: 'trialEndDate',
  351. sorter: true
  352. },
  353. {
  354. title: '合同到期时间',
  355. align: "center",
  356. width: 120,
  357. dataIndex: 'cEndDate',
  358. },
  359. {
  360. title: '人员类别',
  361. align: "center",
  362. width: 100,
  363. dataIndex: 'category_dictText',
  364. scopedSlots: {customRender: "categorys"},
  365. sorter: true
  366. },
  367. {
  368. title: '雇佣状态',
  369. align: "center",
  370. width: 100,
  371. dataIndex: 'employmentStatus',
  372. scopedSlots: {customRender: "employmentStatuss"},
  373. sorter: true
  374. },
  375. // {
  376. // title: '状态',
  377. // align: "center",
  378. // width: 80,
  379. // dataIndex: 'status_dictText'
  380. // },
  381. {
  382. title: '操作',
  383. dataIndex: 'action',
  384. scopedSlots: {customRender: 'action'},
  385. align: "center",
  386. fixed: 'right',
  387. width: 170
  388. }
  389. ],
  390. superQueryFieldList: [
  391. { type: 'input', value: 'username', text: '用户账号', },
  392. { type: 'input', value: 'realname', text: '用户姓名', },
  393. { type: 'select', value: 'sex', text: '性别', dictCode: 'sex' },
  394. ],
  395. url: {
  396. syncUser: "/act/process/extActProcess/doSyncUser",
  397. list: "/sys/user/list",
  398. delete: "/sys/user/delete",
  399. deleteBatch: "/sys/user/deleteBatch",
  400. exportXlsUrl: "/sys/user/exportXls",
  401. exportXlsUrls: "/sys/user/exportXlsts",
  402. importExcelUrl: "sys/user/importExcel",
  403. importExcelUrls:'sys/user/importExcels',
  404. pulldata:"/sys/weixin/pullData",
  405. editstate:"/sys/user/editState",
  406. userChangemb:'/userchange/userChage/exportXls'
  407. },
  408. }
  409. },
  410. computed: {
  411. importExcelUrl: function(){
  412. return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
  413. },
  414. importExcelUrls(){
  415. return `${window._CONFIG['domianURL']}/${this.url.importExcelUrls}`;
  416. }
  417. },
  418. methods: {
  419. // onSelectChanges(selectedRowKeys, selectionRows) {
  420. // this.selectedRowKeys = selectedRowKeys;
  421. // this.selectionRows = selectionRows;
  422. // },
  423. onDateChange: function (value, dateString) {
  424. this.queryParam.rzDate=dateString[0]+","+dateString[1];
  425. },
  426. onDateChanges: function (value, dateString) {
  427. this.queryParam.syDate=dateString[0]+","+dateString[1];
  428. },
  429. handleExportXltx(){
  430. this.queryParam.orgCodeTxt="空白模板";
  431. this.$options.methods.handleExportXls.call(this)
  432. this.queryParam.orgCodeTxt="";
  433. },
  434. getAvatarView: function (avatar) {
  435. return getFileAccessHttpUrl(avatar)
  436. },
  437. clearSpace(e) {
  438. this.queryParam.realname = e.target.value.replace(/\s+/g, '')
  439. },
  440. clearSpaces(e) {
  441. this.queryParam.workNo = e.target.value.replace(/\s+/g, '')
  442. },
  443. modalFormOks(formData) {
  444. if (formData.departIdList != null && formData.departIdList.length > 0) {
  445. for (let i = 0; i < formData.departIdList.length; i++) {
  446. this.queryParam.orgCodeTxt=formData.departIdList[i].key;
  447. this.departNames =formData.departIdList[i].title;
  448. }
  449. }
  450. },
  451. batchrz(){
  452. if (this.selectedRowKeys.length<=0) {
  453. this.$message.warning('请选择一条记录!');
  454. return false;
  455. } else {
  456. var userids=this.selectedRowKeys.join(",");
  457. getAction(this.url.editstate, {
  458. userids:userids
  459. }).then(res => {
  460. if (res.success) {
  461. this.$message.success(res.message);
  462. this.loadData();
  463. }else{
  464. this.$message.warning(res.message);
  465. }
  466. })
  467. this.selectedRowKeys=[];
  468. this.selectionRows=[];
  469. }
  470. },
  471. handleEmpty(){
  472. this.queryParam.orgCodeTxt=null;
  473. this.departNames=null;
  474. },
  475. batchFrozen: function (status) {
  476. if (this.selectedRowKeys.length <= 0) {
  477. this.$message.warning('请选择一条记录!');
  478. return false;
  479. } else {
  480. let ids = "";
  481. let that = this;
  482. let isAdmin = false;
  483. that.selectionRows.forEach(function (row) {
  484. if (row.username == 'admin') {
  485. isAdmin = true;
  486. }
  487. });
  488. if (isAdmin) {
  489. that.$message.warning('管理员账号不允许此操作,请重新选择!');
  490. return;
  491. }
  492. that.selectedRowKeys.forEach(function (val) {
  493. ids += val + ",";
  494. });
  495. that.$confirm({
  496. title: "确认操作",
  497. content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
  498. onOk: function () {
  499. frozenBatch({ids: ids, status: status}).then((res) => {
  500. if (res.success) {
  501. that.$message.success(res.message);
  502. that.loadData();
  503. that.onClearSelected();
  504. } else {
  505. that.$message.warning(res.message);
  506. }
  507. });
  508. }
  509. });
  510. }
  511. },
  512. openModal(){
  513. var ls=[];
  514. ls.push(this.queryParam.orgCodeTxt);
  515. this.$refs.departWindow.add(ls, {});
  516. },
  517. handleMenuClick(e) {
  518. var data=this.selectionRows;
  519. var f=false;
  520. for(var i=0;i<data.length;i++){
  521. if(data[i].employmentStatus!=40){
  522. f=true;
  523. }
  524. }
  525. if(f){
  526. this.$message.warning('请勾选待入职数据');
  527. return;
  528. }
  529. if (e.key == 1) {
  530. this.batchDel();
  531. } else if (e.key == 2) {
  532. this.batchFrozen(2);
  533. } else if (e.key == 3) {
  534. this.batchFrozen(1);
  535. }else if(e.key==4){
  536. this.batchrz();
  537. }
  538. },
  539. handleDetails(e){
  540. console.log(this.$refs)
  541. this.$refs.userdetailmodal.edit(e);
  542. },
  543. handleFrozen: function (id, status, username) {
  544. let that = this;
  545. //TODO 后台校验管理员角色
  546. if ('admin' == username) {
  547. that.$message.warning('管理员账号不允许此操作!');
  548. return;
  549. }
  550. frozenBatch({ids: id, status: status}).then((res) => {
  551. if (res.success) {
  552. that.$message.success(res.message);
  553. that.loadData();
  554. } else {
  555. that.$message.warning(res.message);
  556. }
  557. });
  558. },
  559. handleExportXls3(fileName){
  560. if(!fileName || typeof fileName != "string"){
  561. fileName = "导出文件"
  562. }
  563. downFile(this.url.userChangemb,{}).then((data)=>{
  564. if (!data) {
  565. this.$message.warning("文件下载失败")
  566. return
  567. }
  568. if (typeof window.navigator.msSaveBlob !== 'undefined') {
  569. window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
  570. }else{
  571. let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
  572. let link = document.createElement('a')
  573. link.style.display = 'none'
  574. link.href = url
  575. link.setAttribute('download', fileName+'.xls')
  576. document.body.appendChild(link)
  577. link.click()
  578. document.body.removeChild(link); //下载完成移除元素
  579. window.URL.revokeObjectURL(url); //释放掉blob对象
  580. }
  581. })
  582. },
  583. handleExportXlst(fileName){
  584. if(!fileName || typeof fileName != "string"){
  585. fileName = "导出文件"
  586. }
  587. downFile(this.url.exportXlsUrls,this.queryParam).then((data)=>{
  588. if (!data) {
  589. this.$message.warning("文件下载失败")
  590. return
  591. }
  592. if (typeof window.navigator.msSaveBlob !== 'undefined') {
  593. window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
  594. }else{
  595. let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
  596. let link = document.createElement('a')
  597. link.style.display = 'none'
  598. link.href = url
  599. link.setAttribute('download', fileName+'.xls')
  600. document.body.appendChild(link)
  601. link.click()
  602. document.body.removeChild(link); //下载完成移除元素
  603. window.URL.revokeObjectURL(url); //释放掉blob对象
  604. }
  605. })
  606. },
  607. /* 导入 */
  608. handleImportExcels(info){
  609. if (info.file.status !== 'uploading') {
  610. console.log(info.file, info.fileList);
  611. }
  612. if (info.file.status === 'done') {
  613. if (info.file.response.success) {
  614. // this.$message.success(`${info.file.name} 文件上传成功`);
  615. if (info.file.response.code === 201) {
  616. let { message, result: { msg, fileUrl, fileName } } = info.file.response
  617. let href = window._CONFIG['domianURL'] + fileUrl
  618. this.$warning({
  619. title: message,
  620. content: (<div>
  621. <span>{msg}</span><br/>
  622. <span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
  623. </div>
  624. )
  625. })
  626. } else {
  627. this.$message.success(info.file.response.message || `${info.file.name} 文件上传成功`)
  628. }
  629. this.loadData()
  630. } else {
  631. this.$message.error(`${info.file.name} ${info.file.response.message}.`);
  632. }
  633. } else if (info.file.status === 'error') {
  634. if (info.file.response.status === 500) {
  635. let data = info.file.response
  636. const token = Vue.ls.get(ACCESS_TOKEN)
  637. if (token && data.message.includes("Token失效")) {
  638. Modal.error({
  639. title: '登录已过期',
  640. content: '很抱歉,登录已过期,请重新登录',
  641. okText: '重新登录',
  642. mask: false,
  643. onOk: () => {
  644. store.dispatch('Logout').then(() => {
  645. Vue.ls.remove(ACCESS_TOKEN)
  646. window.location.reload();
  647. })
  648. }
  649. })
  650. }
  651. } else {
  652. this.$message.error(`文件上传失败: ${info.file.msg} `);
  653. }
  654. }
  655. },
  656. handleChangePassword(username) {
  657. this.$refs.passwordmodal.show(username);
  658. },
  659. passwordModalOk() {
  660. //TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
  661. }
  662. }
  663. }
  664. </script>
  665. <style scoped>
  666. @import '~@assets/less/common.less';
  667. </style>