index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <template>
  2. <div class="app-container">
  3. <el-row :gutter="20">
  4. <!--部门数据-->
  5. <el-col :span="4" :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="productOptions"
  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="20" :xs="24">
  32. <el-row :gutter="10" class="mb8">
  33. <el-col :span="1.5">
  34. <el-button
  35. type="primary"
  36. plain
  37. icon="el-icon-plus"
  38. size="mini"
  39. @click="handleAdd"
  40. v-hasPermi="['system:user:add']"
  41. >新增</el-button>
  42. </el-col>
  43. <el-col :span="1.5">
  44. <el-button
  45. type="success"
  46. plain
  47. icon="el-icon-edit"
  48. size="mini"
  49. :disabled="single"
  50. @click="handleUpdate"
  51. v-hasPermi="['system:user:edit']"
  52. >修改</el-button>
  53. </el-col>
  54. <el-col :span="1.5">
  55. <el-button
  56. type="danger"
  57. plain
  58. icon="el-icon-delete"
  59. size="mini"
  60. :disabled="multiple"
  61. @click="handleDelete"
  62. v-hasPermi="['system:user:remove']"
  63. >删除</el-button>
  64. </el-col>
  65. <el-col :span="1.5">
  66. <el-button
  67. type="info"
  68. plain
  69. icon="el-icon-upload2"
  70. size="mini"
  71. @click="handleImport"
  72. v-hasPermi="['system:user:import']"
  73. >导入</el-button>
  74. </el-col>
  75. <el-col :span="1.5">
  76. <el-button
  77. type="warning"
  78. plain
  79. icon="el-icon-download"
  80. size="mini"
  81. @click="handleExport"
  82. v-hasPermi="['system:user:export']"
  83. >导出</el-button>
  84. </el-col>
  85. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
  86. </el-row>
  87. <el-table v-loading="loading" :data="productList" @selection-change="handleSelectionChange">
  88. <el-table-column type="selection" width="50" align="center" />
  89. <el-table-column :label="formColumn.snsId" align="center" key="snsId" prop="snsId" v-if="columns[0].visible" />
  90. <el-table-column :label="formColumn.name" align="center" key="name" prop="name" v-if="columns[1].visible" :show-overflow-tooltip="true" />
  91. <el-table-column :label="formColumn.parentId" align="center" key="parentId" prop="parentId" v-if="columns[2].visible" :show-overflow-tooltip="true" />
  92. <el-table-column
  93. label="操作"
  94. align="center"
  95. width="160"
  96. class-name="small-padding fixed-width"
  97. >
  98. <template slot-scope="scope" v-if="scope.row.userId !== 1">
  99. <el-button
  100. size="mini"
  101. type="text"
  102. icon="el-icon-edit"
  103. @click="handleUpdate(scope.row)"
  104. v-hasPermi="['system:user:edit']"
  105. >修改</el-button>
  106. <el-button
  107. size="mini"
  108. type="text"
  109. icon="el-icon-delete"
  110. @click="handleDelete(scope.row)"
  111. v-hasPermi="['system:user:remove']"
  112. >删除</el-button>
  113. </template>
  114. </el-table-column>
  115. </el-table>
  116. <pagination
  117. v-show="total>0"
  118. :total="total"
  119. :page.sync="queryParams.pageNum"
  120. :limit.sync="queryParams.pageSize"
  121. @pagination="getList"
  122. />
  123. </el-col>
  124. </el-row>
  125. <!-- 添加或修改用户配置对话框 -->
  126. <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
  127. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  128. <el-form-item label="父ID" prop="parentId">
  129. <treeselect v-model="form.parentId" :options="productOptions" :normalizer="normalizer" placeholder="请选择父ID" />
  130. </el-form-item>
  131. <el-form-item label="产品名称" prop="name">
  132. <el-input v-model="form.name" placeholder="请输入产品名称" />
  133. </el-form-item>
  134. <el-form-item label="SNS编号" prop="snsId">
  135. <el-input v-model="form.snsId" placeholder="请输入SNS编号" />
  136. </el-form-item>
  137. </el-form>
  138. <div slot="footer" class="dialog-footer">
  139. <el-button type="primary" @click="submitForm">确 定</el-button>
  140. <el-button @click="cancel">取 消</el-button>
  141. </div>
  142. </el-dialog>
  143. <!-- 用户导入对话框 -->
  144. <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  145. <el-upload
  146. ref="upload"
  147. :limit="1"
  148. accept=".xlsx, .xls"
  149. :headers="upload.headers"
  150. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  151. :disabled="upload.isUploading"
  152. :on-progress="handleFileUploadProgress"
  153. :on-success="handleFileSuccess"
  154. :auto-upload="false"
  155. drag
  156. >
  157. <i class="el-icon-upload"></i>
  158. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  159. <div class="el-upload__tip text-center" slot="tip">
  160. <div class="el-upload__tip" slot="tip">
  161. <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
  162. </div>
  163. <span>仅允许导入xls、xlsx格式文件。</span>
  164. <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
  165. </div>
  166. </el-upload>
  167. <div slot="footer" class="dialog-footer">
  168. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  169. <el-button @click="upload.open = false">取 消</el-button>
  170. </div>
  171. </el-dialog>
  172. </div>
  173. </template>
  174. <script>
  175. import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user";
  176. import { listProduct, getProduct, delProduct, addProduct, updateProduct } from "@/api/manage/product";
  177. import { getToken } from "@/utils/auth";
  178. import Treeselect from "@riophae/vue-treeselect";
  179. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  180. const columnss = {
  181. 1: {
  182. name: '系统名称1',
  183. snsId: 'SNS编号1',
  184. parentId: '归属平台型号'
  185. },
  186. 2:{
  187. name: '分/子系统名称',
  188. snsId: 'SNS编号',
  189. parentId: '归属系统'
  190. },
  191. 3:{
  192. name: '部件名称',
  193. snsId: 'SNS编号',
  194. parentId: '归属分/子系统'
  195. },
  196. 4:{
  197. name: 'LRU名称',
  198. snsId: 'SNS编号',
  199. parentId: '归属部件'
  200. },
  201. }
  202. export default {
  203. name: "User",
  204. dicts: ['sys_normal_disable', 'sys_user_sex'],
  205. components: { Treeselect },
  206. data() {
  207. return {
  208. formColumn: {
  209. name: '系统名称',
  210. snsId: 'SNS编号',
  211. parentId: '归属平台型号'
  212. },
  213. // 遮罩层
  214. loading: true,
  215. // 选中数组
  216. ids: [],
  217. // 非单个禁用
  218. single: true,
  219. // 非多个禁用
  220. multiple: true,
  221. // 显示搜索条件
  222. showSearch: true,
  223. // 总条数
  224. total: 0,
  225. // 产品树表格数据
  226. productList: null,
  227. // 弹出层标题
  228. title: "",
  229. // 产品树选项
  230. productOptions: undefined,
  231. // 是否显示弹出层
  232. open: false,
  233. // 部门名称
  234. deptName: undefined,
  235. // 默认密码
  236. initPassword: undefined,
  237. // 日期范围
  238. dateRange: [],
  239. // 岗位选项
  240. postOptions: [],
  241. // 角色选项
  242. roleOptions: [],
  243. // 表单参数
  244. form: {},
  245. defaultProps: {
  246. children: "children",
  247. label: "name"
  248. },
  249. // 列信息
  250. columns: [
  251. { key: 0, visible: true },
  252. { key: 1, visible: true },
  253. { key: 2, visible: true },
  254. ],
  255. // 用户导入参数
  256. upload: {
  257. // 是否显示弹出层(用户导入)
  258. open: false,
  259. // 弹出层标题(用户导入)
  260. title: "",
  261. // 是否禁用上传
  262. isUploading: false,
  263. // 是否更新已经存在的用户数据
  264. updateSupport: 0,
  265. // 设置上传的请求头部
  266. headers: { Authorization: "Bearer " + getToken() },
  267. // 上传的地址
  268. url: process.env.VUE_APP_BASE_API + "/system/user/importData"
  269. },
  270. // 查询参数
  271. queryParams: {
  272. snsId:null,
  273. name: null,
  274. parentId:null
  275. },
  276. // 表单校验
  277. rules: {
  278. parentId: [
  279. { required: true, message: "父ID不能为空", trigger: "blur" }
  280. ],
  281. name: [
  282. { required: true, message: "产品名称不能为空", trigger: "blur" }
  283. ],
  284. isDelete: [
  285. { required: true, message: "数据是否删除不能为空", trigger: "blur" }
  286. ],
  287. }
  288. };
  289. },
  290. watch: {
  291. // 根据名称筛选部门树
  292. deptName(val) {
  293. this.$refs.tree.filter(val);
  294. }
  295. },
  296. created() {
  297. this.getList();
  298. this.getTreeselect();
  299. },
  300. methods: {
  301. /** 查询产品树信息列表 */
  302. getList() {
  303. this.loading = true;
  304. listProduct(this.queryParams).then(response => {
  305. this.productList=response.data
  306. this.loading = false;
  307. });
  308. },
  309. /** 查询产品树信息下拉树结构 */
  310. getTreeselect() {
  311. listProduct().then(response => {
  312. this.productOptions = [];
  313. const data = { id: 0, name: '顶级节点', children: [] };
  314. data.children = this.handleTree(response.data, "id", "parentId");
  315. this.productOptions.push(data);
  316. });
  317. },
  318. /** 转换产品树信息数据结构 */
  319. normalizer(node) {
  320. if (node.children && !node.children.length) {
  321. delete node.children;
  322. }
  323. return {
  324. id: node.id,
  325. label: node.name,
  326. children: node.children
  327. };
  328. },
  329. // 筛选节点
  330. filterNode(value, data) {
  331. if (!value) return true;
  332. return data.name.indexOf(value) !== -1;
  333. },
  334. // 节点单击事件
  335. handleNodeClick(data) {
  336. let i = 1
  337. this.formColumn = columnss[i]
  338. this.loading = false;
  339. getProduct(data.id).then(response => {
  340. this.productList=[response.data]
  341. this.loading = false;
  342. });
  343. },
  344. // 取消按钮
  345. cancel() {
  346. this.open = false;
  347. this.reset();
  348. },
  349. // 表单重置
  350. reset() {
  351. this.form = {
  352. parentId: null,
  353. name: null,
  354. snsId: null,
  355. };
  356. this.resetForm("form");
  357. },
  358. // 多选框选中数据
  359. handleSelectionChange(selection) {
  360. this.ids = selection.map(item => item.id);
  361. this.single = selection.length != 1;
  362. this.multiple = !selection.length;
  363. },
  364. // 更多操作触发
  365. handleCommand(command, row) {
  366. switch (command) {
  367. case "handleResetPwd":
  368. this.handleResetPwd(row);
  369. break;
  370. case "handleAuthRole":
  371. this.handleAuthRole(row);
  372. break;
  373. default:
  374. break;
  375. }
  376. },
  377. /** 新增按钮操作 */
  378. handleAdd() {
  379. this.reset();
  380. getUser().then(response => {
  381. this.postOptions = response.posts;
  382. this.roleOptions = response.roles;
  383. this.open = true;
  384. this.title = "添加用户";
  385. this.form.password = this.initPassword;
  386. });
  387. },
  388. /** 修改按钮操作 */
  389. handleUpdate(row) {
  390. const Id = row.id || this.ids;
  391. getProduct(Id).then(response => {
  392. this.form = response.data;
  393. this.open = true;
  394. this.title = "修改产品树信息";
  395. });
  396. },
  397. /** 提交按钮 */
  398. submitForm() {
  399. this.$refs["form"].validate(valid => {
  400. if (valid) {
  401. if (this.form.id != null) {
  402. updateProduct(this.form).then(response => {
  403. this.$modal.msgSuccess("修改成功");
  404. this.open = false;
  405. this.getList();
  406. });
  407. } else {
  408. addProduct(this.form).then(response => {
  409. this.$modal.msgSuccess("新增成功");
  410. this.open = false;
  411. this.getList();
  412. });
  413. }
  414. }
  415. });
  416. },
  417. /** 删除按钮操作 */
  418. handleDelete(row) {
  419. const productIds = row.id || this.ids;
  420. this.$modal.confirm('是否确认删除产品树信息编号为"' + productIds + '"的数据项?').then(function() {
  421. return delProduct(row.id);
  422. }).then(() => {
  423. this.getList();
  424. this.$modal.msgSuccess("删除成功");
  425. }).catch(() => {});
  426. },
  427. /** 导出按钮操作 */
  428. handleExport() {
  429. this.download('manage/product/export', {
  430. ...this.queryParams
  431. }, `user_${new Date().getTime()}.xlsx`)
  432. },
  433. /** 导入按钮操作 */
  434. handleImport() {
  435. this.upload.title = "产品树导入";
  436. this.upload.open = true;
  437. },
  438. /** 下载模板操作 */
  439. importTemplate() {
  440. this.download('system/user/importTemplate', {
  441. }, `user_template_${new Date().getTime()}.xlsx`)
  442. },
  443. // 文件上传中处理
  444. handleFileUploadProgress(event, file, fileList) {
  445. this.upload.isUploading = true;
  446. },
  447. // 文件上传成功处理
  448. handleFileSuccess(response, file, fileList) {
  449. this.upload.open = false;
  450. this.upload.isUploading = false;
  451. this.$refs.upload.clearFiles();
  452. this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
  453. this.getList();
  454. },
  455. // 提交上传文件
  456. submitFileForm() {
  457. this.$refs.upload.submit();
  458. }
  459. }
  460. };
  461. </script>