index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <template>
  2. <div class="admin-client">
  3. <el-form :inline="true">
  4. <el-form-item v-if="$permission('/admin/client/check')">
  5. <el-input v-model="queryParams.name" size="small" placeholder="请输入"></el-input>
  6. </el-form-item>
  7. <el-form-item>
  8. <el-button type="" size="small" @click="getList2" v-if="$permission('/admin/client/check')">查询</el-button>
  9. <el-button type="primary" size="small" @click="handleAdd()" v-if="$permission('/admin/client/add')">新增</el-button>
  10. </el-form-item>
  11. </el-form>
  12. <el-table v-loading="loading" :data="tableData" border header-row-class-name="custom-table-header">
  13. <el-table-column type="index" label="#" width="55" align="center">
  14. <template slot-scope="scope">
  15. <span>{{ (scope.$index + 1) + ((queryParams.current - 1) * queryParams.size) }}</span>
  16. </template>
  17. </el-table-column>
  18. <el-table-column prop="name" label="租户名称" align="center" show-overflow-tooltip></el-table-column>
  19. <el-table-column prop="contacts" label="联系人" align="center" show-overflow-tooltip></el-table-column>
  20. <el-table-column prop="address" label="联系人地址" align="center" show-overflow-tooltip></el-table-column>
  21. <el-table-column prop="type" label="类型" align="center" show-overflow-tooltip>
  22. <template slot-scope="scope">
  23. <span v-if="dictionaries.TENANT_TYPE">
  24. {{(dictionaries.TENANT_TYPE.filter(item=>item.dictChildValue==scope.row.type))[0].dictChildLabel}}
  25. </span>
  26. </template>
  27. </el-table-column>
  28. <el-table-column label="是否启用" align="center" show-overflow-tooltip>
  29. <template slot-scope="scope">
  30. <span v-if="scope.row.state==0">否</span>
  31. <span v-if="scope.row.state==1">是</span>
  32. </template>
  33. </el-table-column>
  34. <el-table-column prop="describe" label="备注" align="center" show-overflow-tooltip></el-table-column>
  35. <el-table-column label="操作" align="center" width="150">
  36. <template slot-scope="scope">
  37. <el-dropdown split-button type="primary" size="small" >
  38. <p v-if="$permission('/admin/client/modify')" @click="handleEdit(scope.row)">编辑</p>
  39. <p v-else :disabled="true">编辑</p>
  40. <!-- <el-button type="primary" size="small" @click="handleEdit(scope.row)" v-if="$permission('/admin/client/modify')">
  41. <span>编辑</span>
  42. </el-button>
  43. <el-button type="primary" size="small" v-else :disabled="true">
  44. <span >编辑</span>
  45. </el-button> -->
  46. <el-dropdown-menu slot="dropdown" class="text-align_center">
  47. <!-- <el-dropdown-item @click.native="handleDetails(scope.row)" v-if="$permission('/admin/client/detail')">详情</el-dropdown-item> -->
  48. <el-dropdown-item @click.native="handleReset(scope.row)" v-if="$permission('/admin/client/reset')">重置密码</el-dropdown-item>
  49. <el-dropdown-item class="color-red" @click.native="handleDelete(scope.row)" divided v-if="$permission('/admin/client/delete')">删除</el-dropdown-item>
  50. </el-dropdown-menu>
  51. </el-dropdown>
  52. </template>
  53. </el-table-column>
  54. </el-table>
  55. <div class="pagination">
  56. <el-pagination :current-page.sync="queryParams.current" :page-size="queryParams.size" :total="total" @current-change="handleCurrentChange" layout="total, prev, pager, next, jumper" background></el-pagination>
  57. </div>
  58. <!-- 新增、编辑租户弹框 -->
  59. <el-dialog :title="title" :visible.sync="visible" width="500px" :before-close="close">
  60. <el-form v-if="visible" :model="ruleForm" :rules="rules" ref="ruleForm" label-width="110px" label-position="left">
  61. <!-- <el-form-item label="租户名称" prop="name">
  62. <el-input v-model="ruleForm.name" placeholder="请输入租户名称"></el-input>
  63. </el-form-item>
  64. <el-form-item label="备注" prop="remark">
  65. <el-input v-model="ruleForm.remark" placeholder="请输入备注" type="textarea"></el-input>
  66. </el-form-item> -->
  67. <el-row :gutter="24">
  68. <el-col :span="24">
  69. <el-form-item label="租户名称" prop="name">
  70. <el-autocomplete
  71. style="width:100%"
  72. v-model="ruleForm.name"
  73. :fetch-suggestions="querySearch"
  74. @input="input"
  75. placeholder="请输入租户名称"
  76. :trigger-on-focus="false"
  77. @select="handleChange"
  78. >
  79. </el-autocomplete>
  80. <!-- <el-input v-model="ruleForm.name" placeholder="请输入名称"></el-input> -->
  81. </el-form-item>
  82. </el-col>
  83. </el-row>
  84. <el-row :gutter="24">
  85. <el-col :span="24">
  86. <el-form-item label="联系人" prop="contacts">
  87. <el-input v-model="ruleForm.contacts" placeholder="请输入联系人"></el-input>
  88. </el-form-item>
  89. </el-col>
  90. </el-row>
  91. <el-row :gutter="24">
  92. <el-col :span="24">
  93. <el-form-item label="联系人邮箱" prop="email">
  94. <el-input v-model="ruleForm.email" placeholder="请输入联系人邮箱"></el-input>
  95. </el-form-item>
  96. </el-col>
  97. </el-row>
  98. <el-row :gutter="24">
  99. <el-col :span="24">
  100. <el-form-item label="联系地址" prop="address">
  101. <el-input type="textarea" v-model="ruleForm.address" placeholder="请输入联系地址"></el-input>
  102. </el-form-item>
  103. </el-col>
  104. </el-row>
  105. <el-row :gutter="24">
  106. <el-col :span="24">
  107. <el-form-item label="类型" prop="type">
  108. <!-- <el-input v-model="ruleForm.type" placeholder="请输入类型"></el-input> -->
  109. <el-select v-model="ruleForm.type" :filterable="true" placeholder="请选择类型" style="width: 100%" @change="getType">
  110. <el-option v-for="item in dictionaries.TENANT_TYPE" :key="item.id" :value="item.dictChildValue" :label="item.dictChildLabel"></el-option>
  111. </el-select>
  112. </el-form-item>
  113. </el-col>
  114. </el-row>
  115. <el-row :gutter="24">
  116. <el-col :span="24">
  117. <el-form-item label="描述" prop="describe">
  118. <el-input type="textarea" v-model="ruleForm.describe" placeholder="请输入描述" maxlength="100" show-word-limit></el-input>
  119. </el-form-item>
  120. </el-col>
  121. </el-row>
  122. <el-row :gutter="24">
  123. <el-col :span="24">
  124. <el-form-item label="用户账号配额" prop="number" >
  125. <el-input-number style="width:100%" controls-position="right" :max="999" :min="1" v-model="ruleForm.number" :step="10" placeholder="请输入用户账号配额"></el-input-number>
  126. </el-form-item>
  127. </el-col>
  128. </el-row>
  129. <el-row :gutter="24">
  130. <el-col :span="24">
  131. <el-form-item label="管理员账号" prop="username">
  132. <el-input v-model="ruleForm.username" placeholder="请输入管理员账号"></el-input>
  133. </el-form-item>
  134. </el-col>
  135. </el-row>
  136. <el-row :gutter="24" v-if="pswdshow">
  137. <el-col :span="24">
  138. <el-form-item label="管理员密码" prop="password">
  139. <el-input v-model="ruleForm.password" placeholder="请输入管理员密码"></el-input>
  140. </el-form-item>
  141. </el-col>
  142. </el-row>
  143. <el-row :gutter="24">
  144. <el-col :span="24">
  145. <el-form-item label="会员类别" prop="tenantVipType">
  146. <el-col style="padding-left: 0px;padding-right: 0px;">
  147. <el-select v-model="ruleForm.tenantVipType" placeholder="请选择会员类别" :filterable="true" style="width: 260px; margin-right: 20px;">
  148. <el-option v-for="item in memberTypes"
  149. :key="item.id"
  150. :label="item.tenantVipName"
  151. :value="item.id">
  152. </el-option>
  153. </el-select>
  154. <el-tooltip content="点击查看当前选择的会员类别及功能权限" placement="top">
  155. <!-- <el-link type="primary" @click="memberTypeBtn">会员类别</el-link> -->
  156. <el-button @click="memberTypeBtn">查看</el-button>
  157. </el-tooltip>
  158. </el-col>
  159. </el-form-item>
  160. </el-col>
  161. </el-row>
  162. <!-- <el-row :gutter="24">
  163. <el-col :span="24">
  164. <el-form-item label="功能权限" prop="function">
  165. <el-cascader
  166. ref="FunctionCascader"
  167. v-model="ruleForm.function"
  168. :options="authority"
  169. :props="{multiple:true,value:'id',label:'name' }"
  170. collapse-tags
  171. placeholder="请输入功能权限"
  172. clearable
  173. @change="downloadChange"
  174. style="width:100%"></el-cascader>
  175. </el-form-item>
  176. </el-col>
  177. </el-row> -->
  178. <el-form-item label="是否启用" prop="state">
  179. <el-switch
  180. :active-value="1"
  181. :inactive-value="0"
  182. v-model="ruleForm.state"
  183. active-color="#13ce66"
  184. inactive-color="#ff4949">
  185. </el-switch>
  186. <!-- <el-input v-model="ruleForm.state" placeholder="请输入状态" type="textarea"></el-input> -->
  187. </el-form-item>
  188. </el-form>
  189. <div slot="footer" class="dialog-footer">
  190. <el-button @click="close">取 消</el-button>
  191. <el-button type="primary" @click="submit" :loading="btnLoading">确 定</el-button>
  192. </div>
  193. </el-dialog>
  194. <el-dialog :title="title" :visible.sync="showvisible" width="700px" class="my-dialog-name" contentStyle="width:400px;" :before-close="close" v-if="ruleForm.apply!=null">
  195. <el-form label-position="left" class="demo-table-expand" label-width="110px">
  196. <el-form-item label="租户名称 :" class="marginB">
  197. <span>{{ruleForm.apply.name}}</span>
  198. </el-form-item>
  199. <el-form-item label="联系人 :" class="marginB">
  200. <span>{{ruleForm.apply.contacts}}</span>
  201. </el-form-item>
  202. <el-form-item label="联系人邮箱 :" class="marginB">
  203. <span>{{ruleForm.apply.email}}</span>
  204. </el-form-item>
  205. <el-form-item label="联系地址 :" class="marginB">
  206. <span>{{ruleForm.apply.address}}</span>
  207. </el-form-item>
  208. <el-form-item label="描述 :" class="marginB">
  209. <span>{{ruleForm.apply.describe}}</span>
  210. </el-form-item>
  211. <el-form-item label="用户账号配额 :" class="marginB">
  212. <span>{{ruleForm.apply.number}}</span>
  213. </el-form-item>
  214. <el-form-item label="管理员 :" class="marginB">
  215. <span>{{ruleForm.apply.username}}</span>
  216. </el-form-item>
  217. <el-form-item label="可用功能权限 :" class="marginB">
  218. <span v-for="item in ruleForm.apply.functionList" :key="item.id">{{item.name}} </span>
  219. </el-form-item>
  220. <el-form-item label="租户状态 :" class="marginB">
  221. <span>{{ruleForm.apply.state === 1 ? '已启用' : '未启用'}}</span>
  222. </el-form-item>
  223. <el-form-item label="租户类型 :" class="marginB">
  224. <span v-if="dictionaries.TENANT_TYPE">
  225. {{((dictionaries.TENANT_TYPE).filter(item=>item.dictChildValue==ruleForm.apply.type))[0].dictChildLabel}}
  226. </span>
  227. </el-form-item>
  228. <!-- <el-form-item label="备注 :" class="marginB">
  229. <span>{{ruleForm.apply.describe}}</span>
  230. </el-form-item> -->
  231. </el-form>
  232. </el-dialog>
  233. <!-- 会员类别管理弹窗 -->
  234. <el-dialog title="会员类别查看" :visible.sync="memberVisible" :before-close="closeMember" append-to-body width="500px">
  235. <!-- <MemberType></MemberType> -->
  236. <el-form :model="memberTableData" label-width="80px" label-position="left">
  237. <el-form-item label="会员类型" prop="tenantVipName">
  238. <!-- <span>{{ memberTableData.tenantVipName }}</span> -->
  239. <el-input v-model="memberTableData.tenantVipName" placeholder="请输入会员类型名称" disabled></el-input>
  240. </el-form-item>
  241. <el-form-item label="创建人" prop="createPersonName">
  242. <!-- <span>{{ memberTableData.createPersonName }}</span> -->
  243. <el-input v-model="memberTableData.createPersonName" placeholder="请输入创建人" disabled></el-input>
  244. </el-form-item>
  245. <el-form-item label="功能权限" prop="functions" style="margin-top: 20px;">
  246. <el-cascader
  247. ref="FunctionCascader"
  248. v-model="memberTableData.functions"
  249. :options="authority"
  250. :props="{multiple:true,value:'id',label:'name' }"
  251. collapse-tags
  252. placeholder="请选择功能权限"
  253. clearable
  254. style="width: 100%;"></el-cascader>
  255. </el-form-item>
  256. <el-form-item label="备注" prop="remark">
  257. <!-- <span>{{ memberTableData.remark }}</span> -->
  258. <el-input v-model="memberTableData.remark" placeholder="请输入备注" type="textarea" maxlength="100"
  259. show-word-limit disabled></el-input>
  260. </el-form-item>
  261. </el-form>
  262. <!-- <div slot="footer" class="dialog-footer">
  263. <el-button @click="closeMember">取 消</el-button>
  264. <el-button type="primary" @click="submitMember">确 定</el-button>
  265. </div> -->
  266. </el-dialog>
  267. </div>
  268. </template>
  269. <script>
  270. // import MemberType from "@/views/memberType/index.vue"
  271. export default {
  272. components: {
  273. // MemberType,
  274. },
  275. data() {
  276. return {
  277. saveNodeTmp:[],
  278. functions:[],
  279. trans: [],
  280. authority: [],
  281. select:'',
  282. pswdshow: false,
  283. showvisible: false,
  284. visible: false,
  285. loading: false,
  286. btnLoading: false,
  287. total: 0,
  288. tableData: [],
  289. memberTypes: [],
  290. memberVisible: false,
  291. MemberLoading: false,
  292. memberTableData: {},
  293. title: '',
  294. queryParams: {
  295. size: 10,
  296. current: 1,
  297. name: ''
  298. },
  299. ruleForm: {
  300. },
  301. rules: {
  302. name: [{ required: true, message: '请输入名称', trigger: 'blur' },],
  303. contacts:[{ required: true, message: '请输入联系人', trigger: 'blur' },],
  304. // email:[{ required: true, message: '请输入联系人邮箱', trigger: 'blur' },],
  305. address: [{ required: true, message: '请输入联系地址', trigger: 'blur' },],
  306. number: [{ required: true, message: '请输入用户账号配额', trigger: 'blur' },],
  307. username:[{ required: true, message: '请输入管理员账号', trigger: 'blur' },],
  308. password:[{ required: true, message: '请输入管理员密码', trigger: 'blur' },],
  309. type:[{ required: true, message: '请选择类型', trigger: 'change' },],
  310. email:[{required:true,message: "请输入邮箱", trigger: "blur"},
  311. {pattern:/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9_\.\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
  312. message:'请输入正确的邮箱格式',trigger:'blur'}],
  313. },
  314. clientList:[],
  315. }
  316. },
  317. mounted() {
  318. this.getList()
  319. this.getFunction()
  320. this.getListMemberType()
  321. this.getNoTenantClients()
  322. // this.translate()
  323. },
  324. created(){
  325. // this.select = this.$store.state.admin.dictionaries
  326. },
  327. computed: {
  328. dictionaries() {
  329. return this.$store.state.admin.dictionaries
  330. },
  331. },
  332. methods: {
  333. querySearch(queryString, cb) {
  334. var clientList = this.clientList;
  335. var results = (queryString ? clientList.filter(this.createFilter(queryString)) : clientList).map(item=>{
  336. return {
  337. value:item.name,
  338. name:item.name,
  339. id:item.id
  340. }
  341. });
  342. // 调用 callback 返回建议列表的数据
  343. cb(results);
  344. },
  345. createFilter(queryString) {
  346. return (clientList) => {
  347. return (clientList.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
  348. };
  349. },
  350. getNoTenantClients(){
  351. this.$api.getNoTenantClients().then(response=>{
  352. this.clientList = response.data
  353. })
  354. },
  355. input() {
  356. this.$set(this.ruleForm, 'clientId', null)
  357. },
  358. handleChange(row) {
  359. this.$set(this.ruleForm, 'clientId', row.id)
  360. this.$set(this.ruleForm, 'name', row.name)
  361. },
  362. getType(val){
  363. // this.getFunction(val)
  364. },
  365. //根据条件查询
  366. getList2(){
  367. this.queryParams.current=1
  368. this.getList()
  369. },
  370. handleAdd() {
  371. this.title = '新增租户'
  372. this.visible = true
  373. this.pswdshow = true
  374. this.ruleForm = {
  375. state:1
  376. }
  377. },
  378. handleEdit(row) {
  379. this.title = '编辑租户'
  380. this.visible = true
  381. this.pswdshow = false
  382. // this.authority = []
  383. // this.getFunction(row.type)
  384. this.ruleForm = { ...row }
  385. },
  386. handleDetails(row) {
  387. this.title = '租户详情'
  388. this.showvisible = true
  389. this.ruleForm.apply = row
  390. },
  391. close() {
  392. this.visible = false
  393. this.showvisible = false
  394. this.pswdshow = false
  395. },
  396. // translate() {
  397. // for (let i = 0; i < this.select.length; i++) {
  398. // this.trans.push(this.select[i].dictChildLabel)
  399. // }
  400. // },
  401. getList() {
  402. this.loading = true
  403. this.$api.getTenantList(this.queryParams).then(response => {
  404. this.tableData = response.data
  405. this.total = response.pageColumn.total
  406. this.loading = false
  407. }).catch(error => {
  408. this.loading = false
  409. });
  410. },
  411. // 请求会员类别权限
  412. getListMemberType() {
  413. this.$api.queryTenantVipType({}).then(res => {
  414. if (res.code == 200) {
  415. this.memberTypes = res.data.list
  416. }
  417. })
  418. },
  419. //会员类别查看按钮
  420. memberTypeBtn() {
  421. this.memberTableData=this.memberTypes.filter(item => {
  422. return item.id==this.ruleForm.tenantVipType
  423. })[0]
  424. // this.memberTableData = a[0]
  425. this.memberVisible=true
  426. },
  427. // 会员类别弹窗确定
  428. // submitMember() {
  429. // this.closeMember()
  430. // },
  431. // 会员类别弹窗取消
  432. closeMember() {
  433. this.memberVisible = false
  434. this.memberTableData={}
  435. },
  436. // getCheckedNodes(){
  437. // var List = this.$refs.FunctionCascader.getCheckedNodes()
  438. // List.forEach(item => {
  439. // });
  440. // },
  441. findAllNode(data) {
  442. if (!this.saveNodeTmp.includes(data.path)) {
  443. if(data.path.length>1){
  444. this.saveNodeTmp.push(data.path)
  445. }
  446. }
  447. if (data.parent) {
  448. this.findAllNode(data.parent)
  449. }
  450. },
  451. // change时
  452. downloadChange(data) {
  453. let readSelectedAllNode = this.$refs.FunctionCascader.getCheckedNodes()
  454. this.saveNodeTmp = []
  455. readSelectedAllNode.forEach(item => {
  456. this.findAllNode(item)
  457. })
  458. this.functions = [...this.saveNodeTmp]
  459. },
  460. getFunction() {
  461. this.$api.getAllFunctionList({}).then(response => {
  462. this.authority = []
  463. this.authority = response.data
  464. // this.tableData = response.data
  465. // this.total=response.pageColumn.total
  466. // this.loading = false
  467. }).catch(error => {
  468. this.loading = true
  469. })
  470. },
  471. handleCurrentChange(val) {
  472. this.queryParams.current = val;
  473. this.getList();
  474. },
  475. submit() {
  476. this.$refs.ruleForm.validate((valid) => {
  477. if (valid) {
  478. // this.ruleForm.function = this.functions
  479. // this.ruleForm.functions=[]
  480. // if(this.ruleForm.hasOwnProperty('function')){
  481. // for(var i =0;i<this.ruleForm.function.length;i++){
  482. // var a =this.ruleForm.function[i].join(',')
  483. // this.ruleForm.functions.push(a)
  484. // }
  485. // }
  486. this.btnLoading = true
  487. if (this.ruleForm.id) {
  488. this.$api.editTenant(this.ruleForm).then(response => {
  489. this.$message.success('编辑成功')
  490. this.btnLoading = false
  491. this.getList()
  492. this.getNoTenantClients()
  493. this.close()
  494. }).catch(error => {
  495. this.btnLoading = false
  496. })
  497. } else {
  498. this.$api.addTenant(this.ruleForm).then(response => {
  499. this.$message.success('新增成功')
  500. this.btnLoading = false
  501. this.getList()
  502. this.getNoTenantClients()
  503. this.close()
  504. }).catch(error => {
  505. this.btnLoading = false
  506. })
  507. }
  508. } else {
  509. return false;
  510. }
  511. });
  512. },
  513. handleReset(row) {
  514. this.$confirm("确认将用户密码重置吗?", "提示", {
  515. confirmButtonText: "确定",
  516. cancelButtonText: "取消",
  517. type: "warning",
  518. }).then(() => {
  519. this.loading = true;
  520. this.$api
  521. .ResetPassword({ userId: row.personnelId })
  522. .then((response) => {
  523. this.$message.success("重置成功");
  524. this.loading = false;
  525. this.getList();
  526. })
  527. .catch((error) => {
  528. this.loading = false;
  529. });
  530. });
  531. },
  532. handleDelete(row) {
  533. this.$confirm('该操作将删除该租户下所有数据,无法撤回,请慎重考虑!是否删除?', '注意!', {
  534. confirmButtonText: '确定',
  535. cancelButtonText: '取消',
  536. type: 'warning',
  537. center: true
  538. }).then(() => {
  539. this.loading = true
  540. this.$api.deleteTenant({ id: row.id }).then(response => {
  541. this.$message.success('删除成功')
  542. if(this.tableData.length==1){
  543. this.queryParams.current -= 1
  544. }
  545. this.loading = false
  546. this.getList()
  547. this.getNoTenantClients()
  548. }).catch(error => {
  549. this.loading = false
  550. })
  551. })
  552. }
  553. }
  554. }
  555. </script>
  556. <style lang="scss">
  557. .el-input-number .el-input__inner{
  558. text-align: left;
  559. padding-left: 0;
  560. }
  561. </style>
  562. <style lang="scss" scoped>
  563. .admin-client {
  564. }
  565. .marginB {
  566. margin-bottom: 0;
  567. }
  568. </style>