index.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. <style>
  2. .table-body {
  3. padding: 20px 20px;
  4. background-color: #fff;
  5. }
  6. .table-body .top-input{
  7. margin-top: 34px;
  8. }
  9. .input-item {
  10. width: 200px;
  11. margin-right: 20px;
  12. }
  13. .input-item .el-input__inner {
  14. border-right: 0;
  15. }
  16. .input-item .el-input__inner:hover {
  17. border: 1px solid #dcdfe6;
  18. border-right: 0;
  19. outline: 0;
  20. }
  21. .input-item .el-input__inner:focus {
  22. border: 1px solid #dcdfe6;
  23. border-right: 0;
  24. outline: 0;
  25. }
  26. .input-item .el-input-group__append {
  27. background-color: #fff;
  28. border-left: 0;
  29. width: 10%;
  30. padding: 0;
  31. }
  32. .input-item .el-input-group__append .el-button {
  33. padding: 0;
  34. }
  35. .input-item .el-input-group__append .el-button {
  36. margin: 0;
  37. }
  38. /* #app .table-body .el-table .el-button {
  39. border-radius: 16px;
  40. } */
  41. .create {
  42. height: 36px;
  43. line-height: 36px;
  44. float: right;
  45. color: #BCBCBC;
  46. margin-left: 20px;
  47. }
  48. .name {
  49. cursor: pointer;
  50. color: #49A9FF;
  51. }
  52. .el-input-group__append {
  53. /* background-color: #fff; */
  54. }
  55. /* 卡片 */
  56. .plugin-list {
  57. margin: 0 0 0 -20px;
  58. /* padding-right: 100px; */
  59. display: flex;
  60. flex-wrap:wrap;
  61. }
  62. .plugin-list .plugin-item{
  63. width: 20%;
  64. min-width: 400px;
  65. }
  66. .plugin-item {
  67. border: 1px solid #ebebeb;
  68. background: #FFFFFF;
  69. box-shadow: 3px 5px 15px rgba(80, 80, 80, 0.16);
  70. opacity: 1;
  71. border-radius: 5px;
  72. padding: 20px;
  73. margin: 0 0 20px 20px;
  74. transition: 250ms;
  75. position: relative;
  76. /* min-width: 300px; */
  77. }
  78. .plugin-item .item-status{
  79. position: absolute;
  80. top: 0;
  81. right: 0;
  82. width: 94px;
  83. height: 30px;
  84. background: #E8EAEC;
  85. opacity: 1;
  86. border-radius: 0px 5px 0px 5px;
  87. font-size: 14px;
  88. font-family: Microsoft YaHei;
  89. font-weight: 400;
  90. line-height: 30px;
  91. color: #9398A4;
  92. text-align: center;
  93. }
  94. .item-status-permanent{
  95. width: 94px;
  96. }
  97. .item-status-effective{
  98. width: 164px;
  99. }
  100. .plugin-item .item-info{
  101. display: flex;
  102. align-items: center;
  103. }
  104. /* .plugin-item .item-info .item-right{
  105. min-width: 500px;
  106. } */
  107. .plugin-item .item-btns{
  108. display: flex;
  109. align-items: center;
  110. justify-content:flex-end;
  111. margin-top: 12px;
  112. }
  113. .plugin-item .mall-logo{
  114. width: 70px;
  115. height: 70px;
  116. margin-right: 12px;
  117. }
  118. .plugin-item .mall-logo img{
  119. width: 100%;
  120. height: 100%;
  121. display: block;
  122. border-radius: 50%;
  123. }
  124. .plugin-item .display-name {
  125. font-size: 18pt;
  126. margin-top: 10px;
  127. margin-bottom: 4px;
  128. font-family: Microsoft YaHei;
  129. font-weight: bold;
  130. line-height: 30px;
  131. color: #3F495D;
  132. opacity: 1;
  133. width: 200px;
  134. white-space:nowrap;
  135. overflow:hidden;
  136. text-overflow:ellipsis;
  137. }
  138. .plugin-item .name {
  139. color: #909399;
  140. }
  141. .plugin-item:hover {
  142. cursor: pointer;
  143. border-color: #bfddff;
  144. }
  145. /* .plugin-item:hover .display-name {
  146. color: #409EFF;
  147. } */
  148. .plugin-item .plugin-option-btn {
  149. height: 25px;
  150. width: 25px;
  151. font-size: 12px;
  152. padding: 0;
  153. }
  154. .plugin-item .detail-option.detail-option {
  155. color: #909399;
  156. background: #F2F6FC;
  157. }
  158. .plugin-item .detail-option:hover {
  159. color: #fff;
  160. background: #909399;
  161. }
  162. </style>
  163. <div id="app" v-cloak>
  164. <el-card shadow="never" style="border:0;min-width: 1200px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  165. <div slot="header">
  166. <div>
  167. <span>角色管理</span>
  168. <div style="float: right; margin: -5px 0">
  169. <el-button type="primary" size="small" @click="handleAdd">新增</el-button>
  170. </div>
  171. </div>
  172. </div>
  173. <div class="table-body">
  174. <template>
  175. <div>
  176. <el-table
  177. :data="tableData"
  178. style="width: 100%;margin-bottom: 20px;"
  179. row-key="id"
  180. stripe
  181. lazy
  182. :load="loadData"
  183. :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
  184. <el-table-column
  185. prop="title"
  186. label="名称"
  187. sortable
  188. width="180">
  189. <template slot-scope="scope">
  190. <span style="margin-left: 10px" >{{ scope.row.title }}</span>
  191. <!-- <i class="el-icon-circle-plus" @click="handleAdds(scope.$index, scope.row)"></i>-->
  192. </template>
  193. </el-table-column>
  194. <el-table-column
  195. prop="sort"
  196. label="排序">
  197. <template slot-scope="scope">
  198. <span style="margin-left: 10px">{{ scope.row.sort }}</span>
  199. </template>
  200. </el-table-column>
  201. <el-table-column label="操作">
  202. <template slot-scope="scope">
  203. <el-button type="text" size="mini" circle style="margin-left: 10px;margin-top: 10px"
  204. @click="handleEdit(scope.$index, scope.row)">
  205. <el-tooltip class="item" effect="dark" content="编辑" placement="top">
  206. <img src="resources/img/mall/edit.png" alt="">
  207. </el-tooltip>
  208. </el-button>
  209. <el-button style="margin-left: 10px;margin-top: 10px" type="text"
  210. class="set-el-button"
  211. size="mini" circle @click="handleDelete(scope.$index, scope.row)">
  212. <el-tooltip class="item" effect="dark" content="删除" placement="top">
  213. <img src="resources/img/mall/del.png" alt="">
  214. </el-tooltip>
  215. </el-button>
  216. </template>
  217. </el-table-column>
  218. </el-table>
  219. </div>
  220. </template>
  221. </div>
  222. <el-dialog :title="title" :visible.sync="dialogFormVisible_add" >
  223. <el-form :model="form" :rules="rules" ref="form" @close="handleClose('form')">
  224. <el-form-item label="上级角色" :label-width="formLabelWidth">
  225. <el-select v-model="parent_title" placeholder="请选择" @change="handleChange">
  226. <el-option
  227. v-for="item,k in parent_list"
  228. :key="k"
  229. :label="item"
  230. :value="k">
  231. </el-option>
  232. </el-select>
  233. </el-form-item>
  234. <el-form-item label="名称" :label-width="formLabelWidth" prop="title">
  235. <el-input v-model="form.title" autocomplete="off"></el-input>
  236. </el-form-item>
  237. <el-form-item label="状态" :label-width="formLabelWidth">
  238. <el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
  239. </el-form-item>
  240. <el-form-item label="排序" :label-width="formLabelWidth">
  241. <el-input v-model="form.sort" autocomplete="off"></el-input>
  242. </el-form-item>
  243. <el-form-item label="权限" :label-width="formLabelWidth">
  244. <el-tree
  245. :data="tree_data"
  246. show-checkbox
  247. node-key="id"
  248. ref="tree"
  249. :default-checked-keys="checkedKey"
  250. :props="defaultProps">
  251. </el-tree>
  252. </el-form-item>
  253. </el-form>
  254. <div slot="footer" class="dialog-footer">
  255. <el-button @click="dialogFormVisible_edit = false">取 消</el-button>
  256. <el-button type="primary" @click="postAdd('form')">确 定</el-button>
  257. </div>
  258. </el-dialog>
  259. <el-dialog :title="title" :visible.sync="dialogFormVisible_edit">
  260. <el-form :model="form" :rules="rules" ref="form" @close="handleClose('form')">
  261. <el-form-item label="上级角色" :label-width="formLabelWidth">
  262. <el-select v-model="parent_title" placeholder="请选择" @change="handleChange">
  263. <el-option
  264. v-for="item,k in parent_list"
  265. :key="k"
  266. :label="item"
  267. :value="k">
  268. </el-option>
  269. </el-select>
  270. </el-form-item>
  271. <el-form-item label="名称" :label-width="formLabelWidth" prop="title">
  272. <el-input v-model="form.title" autocomplete="off"></el-input>
  273. </el-form-item>
  274. <el-form-item label="状态" :label-width="formLabelWidth">
  275. <el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
  276. </el-form-item>
  277. <el-form-item label="排序" :label-width="formLabelWidth">
  278. <el-input v-model="form.sort" autocomplete="off"></el-input>
  279. </el-form-item>
  280. <el-form-item label="权限" :label-width="formLabelWidth">
  281. <el-tabs v-model="activeName" @tab-click="handleClick">
  282. <el-tab-pane label="平台" name="1">
  283. <el-tree
  284. :data="tree_data1"
  285. show-checkbox
  286. node-key="id"
  287. ref="tree1"
  288. @check-change="checkchange1"
  289. :check-strictly="true"
  290. :default-checked-keys="checkedKey"
  291. :props="defaultProps">
  292. </el-tree>
  293. </el-tab-pane>
  294. <el-tab-pane label="商城" name="2">
  295. <el-tree
  296. :data="tree_data2"
  297. show-checkbox
  298. node-key="id"
  299. ref="tree2"
  300. @check-change="checkchange2"
  301. :check-strictly="true"
  302. :default-checked-keys="checkedKey"
  303. :props="defaultProps">
  304. </el-tree>
  305. </el-tab-pane>
  306. <el-tab-pane label="应用" name="3">
  307. <el-tree
  308. :data="tree_data3"
  309. show-checkbox
  310. node-key="id"
  311. ref="tree3"
  312. @check-change="checkchange3"
  313. :check-strictly="true"
  314. :default-checked-keys="checkedKey"
  315. :props="defaultProps">
  316. </el-tree>
  317. </el-tab-pane>
  318. </el-tabs>
  319. </el-form-item>
  320. </el-form>
  321. <div slot="footer" class="dialog-footer">
  322. <el-button @click="dialogFormVisible_edit = false">取 消</el-button>
  323. <el-button type="primary" @click="postAdd('form')">确 定</el-button>
  324. </div>
  325. </el-dialog>
  326. </el-card>
  327. </div>
  328. <script>
  329. new Vue({
  330. el: '#app',
  331. data() {
  332. return {
  333. activeName:"1",
  334. tree_data1:[],
  335. tree_data2:[],
  336. tree_data3:[],
  337. tableData: [],
  338. dialogFormVisible_edit:false,
  339. dialogFormVisible_add:false,
  340. parent_list: [],
  341. items: [],
  342. parent_title:'',
  343. form: {
  344. id:'',
  345. title:'',
  346. pid:0,
  347. sort:999,
  348. status:1,
  349. },
  350. rules:{
  351. title: [
  352. { required: true, message: '请输入名称', trigger: 'blur' },
  353. { min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' }
  354. ],
  355. },
  356. formLabelWidth: '120px',
  357. defaultProps: {
  358. children: 'children',
  359. label: 'label'
  360. },
  361. tree_data:[],
  362. checkedKey:[],
  363. title:'新增'
  364. }
  365. },
  366. created() {
  367. this.loadList({});
  368. },
  369. methods: {
  370. checkchange1(data, checked, indeterminate){
  371. this.checkchange(data,checked,indeterminate,'tree1')
  372. },
  373. checkchange2(data, checked, indeterminate){
  374. this.checkchange(data,checked,indeterminate,'tree2')
  375. },
  376. checkchange3(data, checked, indeterminate){
  377. this.checkchange(data,checked,indeterminate,'tree3')
  378. },
  379. checkchange(data, checked, indeterminate,type){
  380. console.log(type)
  381. let checkid = []
  382. console.log(data,'data555555555')
  383. if(checked == true){
  384. checkid.push(data.id)
  385. if(data.children && data.children.length > 0){
  386. data.children.forEach((it,i)=>{
  387. checkid.push(it.id)
  388. if(it.children && it.children.length > 0){
  389. it.children.forEach((item,index)=>{
  390. checkid.push(item.id)
  391. if(item.children && item.children.length > 0){
  392. item.children.forEach((item1,index1)=>{
  393. checkid.push(item1.id)
  394. })
  395. }
  396. })
  397. }
  398. })
  399. }
  400. this.checkedKey = checkid
  401. }else{
  402. let treenodes=[]
  403. if(type == 'tree2'){
  404. treenodes=this.$refs.tree2.getCheckedKeys()
  405. }else if(type == 'tree3'){
  406. treenodes=this.$refs.tree3.getCheckedKeys()
  407. }else{
  408. treenodes=this.$refs.tree1.getCheckedKeys()
  409. }
  410. treenodes.forEach((v,i)=>{
  411. if(data.children && data.children.length >0){
  412. data.children.forEach((v1,i1)=>{
  413. if(v== v1.id){
  414. if(type == 'tree2'){
  415. this.$refs.tree2.setChecked(v,false);
  416. }else if(type == 'tree3'){
  417. this.$refs.tree3.setChecked(v,false);
  418. }else{
  419. this.$refs.tree1.setChecked(v,false);
  420. }
  421. }
  422. })
  423. if(data.children.children && data.children.children.length >0){
  424. data.children.children.forEach((v2,i2)=>{
  425. if(v== v2.id){
  426. if(type == 'tree2'){
  427. this.$refs.tree2.setChecked(v,false);
  428. }else if(type == 'tree3'){
  429. this.$refs.tree3.setChecked(v,false);
  430. }else{
  431. this.$refs.tree1.setChecked(v,false);
  432. }
  433. }
  434. })
  435. if(data.children.children.children && data.children.children.children.length >0){
  436. data.children.children.children.forEach((v3,i3)=>{
  437. if(v== v3.id){
  438. if(type == 'tree2'){
  439. this.$refs.tree2.setChecked(v,false);
  440. }else if(type == 'tree3'){
  441. this.$refs.tree3.setChecked(v,false);
  442. }else{
  443. this.$refs.tree1.setChecked(v,false);
  444. }
  445. }
  446. })
  447. }
  448. }
  449. }
  450. })
  451. }
  452. },
  453. loadList(params) {
  454. params['r'] = 'admin/role/index';
  455. this.$request({
  456. params: params,
  457. }).then(e => {
  458. if(e.data.code==0){
  459. if(e.data.data.list){
  460. let list = e.data.data.list;
  461. for(var i in list) {
  462. if(list[i]['child'].length!=0){
  463. list[i].hasChildren = true;
  464. }
  465. }
  466. this.tableData = list;
  467. }
  468. }
  469. }).catch(e => {
  470. });
  471. },
  472. handleChange(value){
  473. this.form.pid = value;
  474. },
  475. handleAdd()
  476. {
  477. this.title='新增';
  478. this.dialogFormVisible_edit = true;
  479. this.$request({
  480. params: {
  481. r:'admin/role/edit',
  482. id:''
  483. },
  484. }).then(e => {
  485. if(e.data.code==0){
  486. this.parent_title = e.data.data.parent_title;
  487. this.parent_list = e.data.data.list;
  488. this.tree_data1 = e.data.data.item_list1;
  489. this.tree_data2 = e.data.data.item_list2;
  490. this.tree_data3 = e.data.data.item_list3;
  491. this.checkedKey = e.data.data.checked_key;
  492. }
  493. }).catch(e => {
  494. });
  495. },
  496. handleAdds(index, row)
  497. {
  498. this.title='新增';
  499. this.dialogFormVisible_edit = true;
  500. this.$request({
  501. params: {
  502. r:'admin/role/edit',
  503. id:row.id
  504. },
  505. }).then(e => {
  506. if(e.data.code==0){
  507. this.form.pid = row.id;
  508. this.parent_list = e.data.data.list;
  509. this.tree_data = e.data.data.item_list;
  510. this.parent_title =e.data.data.role.title;
  511. }
  512. }).catch(e => {
  513. });
  514. },
  515. handleEdit(index, row)
  516. {
  517. this.title='编辑';
  518. this.form.id = row.id
  519. this.dialogFormVisible_edit = true;
  520. this.$request({
  521. params: {
  522. r:'admin/role/edit',
  523. id:row.id
  524. },
  525. }).then(e => {
  526. if(e.data.code==0){
  527. this.form.title = e.data.data.role.title;
  528. this.form.sort = e.data.data.role.sort;
  529. this.form.status = e.data.data.role.status;
  530. this.form.pid = e.data.data.role.pid;
  531. this.parent_title = e.data.data.parent_title;
  532. this.parent_list = e.data.data.list;
  533. this.tree_data1 = e.data.data.item_list1;
  534. this.tree_data2 = e.data.data.item_list2;
  535. this.tree_data3 = e.data.data.item_list3;
  536. this.checkedKey = e.data.data.checked_key;
  537. }
  538. }).catch(e => {
  539. });
  540. },
  541. postEdit(formName){
  542. this.$refs[formName].validate((valid) => {
  543. if(valid){
  544. let item_ids = this.$refs.tree.getCheckedKeys();
  545. let parent_item_ids = this.$refs.tree.getHalfCheckedKeys();
  546. if(parent_item_ids.length!=0){
  547. parent_item_ids.forEach(function (item) {
  548. item_ids.push(item);
  549. });
  550. }
  551. this.form.item_ids = item_ids;
  552. this.$request({
  553. method:"post",
  554. params: {
  555. r:'admin/role/edit',
  556. },
  557. data:this.form
  558. }).then(e => {
  559. if(e.data.code==0){
  560. if(this.form.id){
  561. this.dialogFormVisible_edit = false;
  562. }else{
  563. this.dialogFormVisible_add = false;
  564. }
  565. this.$message({
  566. message: e.data.msg,
  567. type: 'success'
  568. });
  569. this.dialogFormVisible_edit = false;
  570. location.reload();
  571. }else{
  572. this.$message.error(e.data.msg);
  573. }
  574. }).catch(e => {
  575. });
  576. }
  577. });
  578. },
  579. postAdd(formName){
  580. this.$refs[formName].validate((valid) => {
  581. if(valid){
  582. let item_ids1 = this.$refs.tree1.getCheckedKeys();
  583. let item_ids2 = this.$refs.tree2.getCheckedKeys();
  584. let item_ids3 = this.$refs.tree3.getCheckedKeys();
  585. // let parent_item_ids = this.$refs.tree.getHalfCheckedKeys();
  586. // if(parent_item_ids.length!=0){
  587. // parent_item_ids.forEach(function (item) {
  588. // item_ids.push(item);
  589. // });
  590. // }
  591. let item_ids = [];
  592. item_ids1.forEach(function (item_id){
  593. item_ids.push(item_id);
  594. });
  595. item_ids2.forEach(function (item_id){
  596. item_ids.push(item_id);
  597. });
  598. item_ids3.forEach(function (item_id){
  599. item_ids.push(item_id);
  600. });
  601. this.form.item_ids = item_ids;
  602. this.$request({
  603. method:"post",
  604. params: {
  605. r:'admin/role/edit',
  606. },
  607. data:this.form
  608. }).then(e => {
  609. if(e.data.code==0){
  610. this.dialogFormVisible_add = false;
  611. this.$message({
  612. message: e.data.msg,
  613. type: 'success'
  614. });
  615. this.dialogFormVisible_edit = false;
  616. location.reload();
  617. }else{
  618. this.$message.error(e.data.msg);
  619. }
  620. }).catch(e => {
  621. });
  622. }
  623. });
  624. },
  625. handleDelete(index, row) {
  626. this.$confirm('删除该条数据后不可以恢复, 是否继续?', '警告', {type: 'warning'}).then(() => {
  627. this.form.id = row.id
  628. this.$request({
  629. params: {
  630. r: 'admin/role/del',
  631. id: row.id,
  632. },
  633. }).then(e => {
  634. if (e.data.code == 0) {
  635. this.$message({
  636. message: e.data.msg,
  637. type: 'success'
  638. });
  639. location.reload();
  640. }else{
  641. this.$message({
  642. message: e.data.msg,
  643. type: 'error'
  644. });
  645. }
  646. }).catch(e => {
  647. });
  648. });
  649. },
  650. loadData(tree, treeNode, resolve){
  651. this.$request({
  652. params: {
  653. r:'admin/role/index',
  654. pid:tree.id,
  655. },
  656. }).then(e => {
  657. if(e.data.code==0){
  658. let list = e.data.data.list;
  659. for(var i in list) {
  660. console.log(list[i]['child'].length);
  661. if(list[i]['child'].length!=0){
  662. list[i].hasChildren = true;
  663. }
  664. }
  665. resolve(list);
  666. }
  667. }).catch(e => {
  668. });
  669. },
  670. handleClose(formName){
  671. this.$refs[formName].resetFields();
  672. },
  673. handleClick(tab, event) {
  674. console.log(tab, event);
  675. }
  676. },
  677. });
  678. </script>