index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. <template>
  2. <div class="app-container">
  3. <el-form
  4. :model="queryParams"
  5. ref="queryForm"
  6. size="small"
  7. :inline="true"
  8. v-show="showSearch"
  9. label-width="68px"
  10. >
  11. <el-form-item label="租户名称" prop="tenantName">
  12. <el-input
  13. v-model="queryParams.tenantName"
  14. placeholder="请输入租户名称"
  15. clearable
  16. @keyup.enter.native="handleQuery"
  17. />
  18. </el-form-item>
  19. <el-form-item label="租户编号" prop="tenantCode">
  20. <el-input
  21. v-model="queryParams.tenantCode"
  22. placeholder="请输入租户编号"
  23. clearable
  24. @keyup.enter.native="handleQuery"
  25. />
  26. </el-form-item>
  27. <el-form-item label="负责人" prop="owner">
  28. <el-input
  29. v-model="queryParams.owner"
  30. placeholder="请输入负责人"
  31. clearable
  32. @keyup.enter.native="handleQuery"
  33. />
  34. </el-form-item>
  35. <el-form-item label="联系方式" prop="contactInfo">
  36. <el-input
  37. v-model="queryParams.contactInfo"
  38. placeholder="请输入联系方式"
  39. clearable
  40. @keyup.enter.native="handleQuery"
  41. />
  42. </el-form-item>
  43. <el-form-item label="地址" prop="address">
  44. <el-input
  45. v-model="queryParams.address"
  46. placeholder="请输入地址"
  47. clearable
  48. @keyup.enter.native="handleQuery"
  49. />
  50. </el-form-item>
  51. <el-form-item>
  52. <el-button
  53. type="primary"
  54. icon="el-icon-search"
  55. size="mini"
  56. @click="handleQuery"
  57. >搜索</el-button
  58. >
  59. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
  60. >重置</el-button
  61. >
  62. </el-form-item>
  63. </el-form>
  64. <el-row :gutter="10" class="mb8">
  65. <el-col :span="1.5">
  66. <el-button
  67. type="primary"
  68. plain
  69. icon="el-icon-plus"
  70. size="mini"
  71. @click="handleAdd"
  72. v-hasPermi="['system:tenant:add']"
  73. >新增
  74. </el-button>
  75. </el-col>
  76. <!-- <el-col :span="1.5">
  77. <el-button
  78. type="success"
  79. plain
  80. icon="el-icon-edit"
  81. size="mini"
  82. :disabled="single"
  83. @click="handleUpdate"
  84. v-hasPermi="['system:tenant:edit']"
  85. >修改</el-button>
  86. </el-col> -->
  87. <el-col :span="1.5">
  88. <el-button
  89. type="danger"
  90. plain
  91. icon="el-icon-delete"
  92. size="mini"
  93. :disabled="multiple"
  94. @click="handleDelete"
  95. v-hasPermi="['system:tenant:remove']"
  96. >删除
  97. </el-button>
  98. </el-col>
  99. <el-col :span="1.5">
  100. <el-button
  101. type="warning"
  102. plain
  103. icon="el-icon-download"
  104. size="mini"
  105. @click="handleExport"
  106. v-hasPermi="['system:tenant:export']"
  107. >导出
  108. </el-button>
  109. <el-button
  110. type="warning"
  111. plain
  112. icon="el-icon-download"
  113. size="mini"
  114. @click="handleTest"
  115. >test
  116. </el-button>
  117. </el-col>
  118. <right-toolbar
  119. :showSearch.sync="showSearch"
  120. @queryTable="getList"
  121. ></right-toolbar>
  122. </el-row>
  123. <el-table
  124. v-loading="loading"
  125. :data="tenantList"
  126. @selection-change="handleSelectionChange"
  127. >
  128. <el-table-column type="selection" width="55" align="center" />
  129. <el-table-column label="租户ID" align="center" prop="tenantId" />
  130. <el-table-column label="租户名称" align="center" prop="tenantName" />
  131. <el-table-column label="租户编号" align="center" prop="tenantCode" />
  132. <el-table-column label="负责人" align="center" prop="owner" />
  133. <el-table-column label="联系方式" align="center" prop="contactInfo" />
  134. <el-table-column label="地址" align="center" prop="address" />
  135. <el-table-column
  136. label="操作"
  137. align="center"
  138. class-name="small-padding fixed-width"
  139. >
  140. <template slot-scope="scope">
  141. <el-dropdown>
  142. <el-button type="warning" plain size="small">
  143. 处理<i class="el-icon-arrow-down el-icon--right"></i>
  144. </el-button>
  145. <el-dropdown-menu slot="dropdown">
  146. <el-dropdown-item>
  147. <el-button
  148. size="mini"
  149. type="text"
  150. icon="el-icon-edit"
  151. @click="handleUpdate(scope.row)"
  152. v-hasPermi="['system:tenant:edit']"
  153. >修改
  154. </el-button>
  155. </el-dropdown-item>
  156. <el-dropdown-item>
  157. <el-button
  158. size="mini"
  159. type="text"
  160. icon="el-icon-delete"
  161. @click="handleDelete(scope.row)"
  162. v-hasPermi="['system:tenant:remove']"
  163. >删除
  164. </el-button>
  165. </el-dropdown-item>
  166. <el-dropdown-item>
  167. <el-button
  168. size="mini"
  169. type="text"
  170. icon="el-icon-edit"
  171. @click="bindDatasource(scope.row)"
  172. v-show="scope.row.datasourceId == null"
  173. >绑定数据源
  174. </el-button>
  175. </el-dropdown-item>
  176. </el-dropdown-menu>
  177. </el-dropdown>
  178. </template>
  179. </el-table-column>
  180. </el-table>
  181. <pagination
  182. v-show="total > 0"
  183. :total="total"
  184. :page.sync="queryParams.pageNum"
  185. :limit.sync="queryParams.pageSize"
  186. @pagination="getList"
  187. />
  188. <!-- 添加或修改租户信息对话框 -->
  189. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  190. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  191. <el-form-item label="租户名称" prop="tenantName">
  192. <el-input v-model="form.tenantName" placeholder="请输入租户名称" />
  193. </el-form-item>
  194. <el-form-item label="租户编号" prop="tenantCode">
  195. <el-input v-model="form.tenantCode" placeholder="请输入租户编号" />
  196. </el-form-item>
  197. <el-form-item label="负责人" prop="owner">
  198. <el-input v-model="form.owner" placeholder="请输入负责人" />
  199. </el-form-item>
  200. <el-form-item label="联系方式" prop="contactInfo">
  201. <el-input v-model="form.contactInfo" placeholder="请输入联系方式" />
  202. </el-form-item>
  203. <el-form-item label="地址" prop="address">
  204. <el-input v-model="form.address" placeholder="请输入地址" />
  205. </el-form-item>
  206. </el-form>
  207. <div slot="footer" class="dialog-footer">
  208. <el-button type="primary" @click="submitForm">确 定</el-button>
  209. <el-button @click="cancel">取 消</el-button>
  210. </div>
  211. </el-dialog>
  212. <!-- 添加或修改数据源信息对话框 -->
  213. <el-dialog
  214. :title="dataSourceTitle"
  215. :visible.sync="dataSourceOpen"
  216. width="500px"
  217. append-to-body
  218. class="loadingClass"
  219. >
  220. <el-radio-group
  221. v-model="dataSourceType"
  222. class="mb5"
  223. @input="dataSourceTypeChange"
  224. >
  225. <el-radio-button :label="true">公网</el-radio-button>
  226. <el-radio-button :label="false">内网</el-radio-button>
  227. </el-radio-group>
  228. <el-form
  229. ref="dataSourceForm"
  230. :model="dataSourceForm"
  231. :rules="dataSourceFormRules"
  232. label-width="120px"
  233. >
  234. <el-form-item label="数据源类型" prop="databaseType">
  235. <el-select
  236. v-model="dataSourceForm.databaseType"
  237. :placeholder="palcemsg"
  238. @change="selecthandle"
  239. :disabled="dataSourceType"
  240. >
  241. <el-option
  242. v-for="item in dict.type.datasource_type"
  243. :key="item.value"
  244. :label="item.label"
  245. :value="item.value"
  246. ></el-option>
  247. </el-select>
  248. </el-form-item>
  249. <el-form-item label="数据库名称" prop="databaseName">
  250. <el-input
  251. v-model="dataSourceForm.databaseName"
  252. placeholder="请输入数据库名称"
  253. />
  254. </el-form-item>
  255. <el-form-item label="租户管理员账号" prop="tenantAccount">
  256. <el-input
  257. v-model="dataSourceForm.tenantAccount"
  258. placeholder="请输入租户管理员账号"
  259. />
  260. </el-form-item>
  261. <!-- !dataSourceType -->
  262. <el-form-item
  263. label="数据库IP"
  264. v-show="!dataSourceType"
  265. prop="databaseIp"
  266. >
  267. <el-input
  268. v-model="dataSourceForm.databaseIp"
  269. placeholder="请输数据库IP"
  270. />
  271. </el-form-item>
  272. <el-form-item label="用户名" v-show="!dataSourceType" prop="username">
  273. <el-input
  274. v-model="dataSourceForm.username"
  275. placeholder="请输入用户名"
  276. />
  277. </el-form-item>
  278. <el-form-item label="密码" v-show="!dataSourceType" prop="password">
  279. <el-input
  280. v-model="dataSourceForm.password"
  281. placeholder="请输入密码"
  282. />
  283. </el-form-item>
  284. <el-form-item label="端口号" v-show="!dataSourceType" prop="portNumber">
  285. <el-input
  286. v-model="dataSourceForm.portNumber"
  287. placeholder="请输入端口号"
  288. />
  289. </el-form-item>
  290. </el-form>
  291. <div slot="footer" class="dialog-footer">
  292. <el-button
  293. type="primary"
  294. @click="submitForm1"
  295. :disabled="dialogLoading"
  296. :loading="dialogLoading"
  297. >{{ dialogLoading ? "绑定中" : "确 定" }}</el-button
  298. >
  299. <el-button @click="cancel1">取 消</el-button>
  300. </div>
  301. </el-dialog>
  302. </div>
  303. </template>
  304. <script>
  305. import {
  306. listTenant,
  307. getTenant,
  308. delTenant,
  309. addTenant,
  310. updateTenant,
  311. bindDatasource,
  312. selectAllUser,
  313. createTenant,
  314. initTenantMenuData,
  315. } from "@/api/system/tenant";
  316. import { getDataSourceInfo, insertDataSource } from "@/api/system/data";
  317. import { servicesLoading } from "@/utils/ruoyi";
  318. export default {
  319. name: "Tenant",
  320. dicts: [
  321. "datasource_type",
  322. "sqlserver_connection_information",
  323. "mysql_connection_information",
  324. "dm_connection_information",
  325. "orcale_connection_information",
  326. ],
  327. data() {
  328. return {
  329. // 弹窗的加载提示
  330. dialogLoading: false,
  331. // 遮罩层
  332. loading: true,
  333. // 选中数组
  334. ids: [],
  335. // 非单个禁用
  336. single: true,
  337. // 非多个禁用
  338. multiple: true,
  339. // 显示搜索条件
  340. showSearch: true,
  341. // 总条数
  342. total: 0,
  343. // 租户信息表格数据
  344. tenantList: [],
  345. // 弹出层标题
  346. title: "",
  347. // 是否显示弹出层
  348. open: false,
  349. // 所有用户信息
  350. allUser: [],
  351. // 查询参数
  352. queryParams: {
  353. pageNum: 1,
  354. pageSize: 10,
  355. tenantName: null,
  356. tenantCode: null,
  357. owner: null,
  358. contactInfo: null,
  359. address: null,
  360. },
  361. // 当前编辑租户的信息
  362. currentTenantInfo: {},
  363. // 表单参数
  364. form: {},
  365. // 表单校验
  366. rules: {
  367. tenantName: [
  368. { required: true, message: "租户名称不能为空", trigger: "blur" },
  369. ],
  370. tenantCode: [
  371. { required: true, message: "租户编号不能为空", trigger: "blur" },
  372. ],
  373. },
  374. //数据源表单参数
  375. dataSourceType: true, //true:公网 false:内网
  376. dataSourceForm: {
  377. databaseType: "",
  378. databaseName: "",
  379. tenantAccount: "",
  380. databaseIp: "",
  381. username: "",
  382. password: "",
  383. portNumber: "",
  384. },
  385. dataSourceTitle: "",
  386. dataSourceOpen: false,
  387. fromTenantId: null,
  388. dataSourceFormRules: {
  389. databaseType: [
  390. { required: true, message: "数据源类型不能为空", trigger: "change" },
  391. ],
  392. databaseName: [
  393. { required: true, message: "数据库名不能为空", trigger: "blur" },
  394. ],
  395. tenantAccount: [
  396. { required: true, message: "租户账号不能为空", trigger: "change" },
  397. { validator: this.tenantAccountValidator, trigger: "blur" },
  398. ],
  399. databaseIp: [
  400. { required: true, message: "数据库IP不能为空", trigger: "blur" },
  401. ],
  402. username: [
  403. { required: true, message: "用户名不能为空", trigger: "blur" },
  404. ],
  405. password: [
  406. { required: true, message: "密码不能为空", trigger: "blur" },
  407. ],
  408. portNumber: [
  409. { required: true, message: "端口号不能为空", trigger: "blur" },
  410. ],
  411. },
  412. };
  413. },
  414. computed: {
  415. palcemsg() {
  416. return this.dataSourceType ? "mysql" : "请选择数据源类型";
  417. },
  418. },
  419. created() {
  420. this.getList();
  421. this.selectAllUser();
  422. },
  423. methods: {
  424. // 获取所用用户名,作校验用
  425. async selectAllUser() {
  426. let res = await selectAllUser();
  427. if (res.code == 200) {
  428. this.allUser = res.data;
  429. } else {
  430. console.log(res.msg);
  431. }
  432. },
  433. // 租户名自定义校验规则
  434. tenantAccountValidator(rule, value, callback) {
  435. let isRepeat = this.allUser.filter((item) => item.userName == value);
  436. if (isRepeat.length !== 0) {
  437. callback(new Error("租户账号重复"));
  438. } else {
  439. callback();
  440. }
  441. },
  442. // 数据源类型改变回调
  443. dataSourceTypeChange(type) {
  444. this.$nextTick(() => {
  445. this.$refs.dataSourceForm.resetFields();
  446. this.dataSourceForm.databaseType = "mysql";
  447. this.selecthandle("mysql");
  448. });
  449. },
  450. handleOpe() {},
  451. /** 查询租户信息列表 */
  452. getList() {
  453. this.loading = true;
  454. listTenant(this.queryParams).then((response) => {
  455. this.tenantList = response.rows;
  456. this.total = response.total;
  457. this.loading = false;
  458. });
  459. },
  460. // 取消按钮
  461. cancel() {
  462. this.open = false;
  463. this.reset();
  464. },
  465. // 绑定数据源取消按钮
  466. cancel1() {
  467. this.dataSourceOpen = false;
  468. this.reset1();
  469. },
  470. // 表单重置
  471. reset() {
  472. this.form = {
  473. tenantId: null,
  474. tenantName: null,
  475. tenantCode: null,
  476. owner: null,
  477. contactInfo: null,
  478. address: null,
  479. createBy: null,
  480. createTime: null,
  481. };
  482. this.resetForm("form");
  483. },
  484. // 表单重置
  485. reset1() {
  486. this.dataSourceType = true;
  487. this.dataSourceForm = {
  488. id: null,
  489. databaseName: null,
  490. databaseIp: null,
  491. tenantAccount: "",
  492. username: null,
  493. password: null,
  494. portNumber: null,
  495. databaseType: "mysql",
  496. };
  497. // this.resetForm("dataSourceForm");
  498. },
  499. /** 搜索按钮操作 */
  500. handleQuery() {
  501. this.queryParams.pageNum = 1;
  502. this.getList();
  503. },
  504. /** 重置按钮操作 */
  505. resetQuery() {
  506. this.resetForm("queryForm");
  507. this.handleQuery();
  508. },
  509. // 多选框选中数据
  510. handleSelectionChange(selection) {
  511. this.ids = selection.map((item) => item.tenantId);
  512. this.single = selection.length !== 1;
  513. this.multiple = !selection.length;
  514. },
  515. /** 新增按钮操作 */
  516. handleAdd() {
  517. this.reset();
  518. this.open = true;
  519. this.title = "添加租户信息";
  520. },
  521. /** 修改按钮操作 */
  522. handleUpdate(row) {
  523. this.reset();
  524. const tenantId = row.tenantId || this.ids;
  525. getTenant(tenantId).then((response) => {
  526. this.form = response.data;
  527. this.open = true;
  528. this.title = "修改租户信息";
  529. });
  530. },
  531. /** 绑定数据源按钮操作 */
  532. bindDatasource(row) {
  533. this.currentTenantInfo = row;
  534. console.log(row);
  535. this.reset1();
  536. this.dataSourceOpen = true;
  537. this.dataSourceTitle = row.tenantName + "配置数据库";
  538. this.fromTenantId = row.tenantId;
  539. this.dataSourceTypeChange();
  540. // const tenantId = row.tenantId || this.ids;
  541. // getTenant(tenantId).then((response) => {
  542. // this.form = response.data;
  543. // this.open = true;
  544. // this.title = "修改租户信息";
  545. // });
  546. },
  547. /** 提交按钮 */
  548. submitForm() {
  549. this.$refs["form"].validate((valid) => {
  550. if (valid) {
  551. if (this.form.tenantId != null) {
  552. updateTenant(this.form).then((response) => {
  553. this.$modal.msgSuccess("修改成功");
  554. this.open = false;
  555. this.getList();
  556. });
  557. } else {
  558. addTenant(this.form).then((response) => {
  559. this.$modal.msgSuccess("新增成功");
  560. this.open = false;
  561. this.getList();
  562. });
  563. }
  564. }
  565. });
  566. },
  567. /** 提交按钮 */
  568. submitForm1() {
  569. this.$refs["dataSourceForm"].validate((valid) => {
  570. if (valid) {
  571. // const loading = servicesLoading(
  572. // ".loadingClass",
  573. // "正在绑定数据源",
  574. // true
  575. // );
  576. this.dialogLoading = true;
  577. if (this.dataSourceForm.id != null) {
  578. // bindDatasource(this.dataSourceForm).then((response) => {
  579. // this.$modal.msgSuccess("修改成功");
  580. // this.dataSourceOpen = false;
  581. // this.getList();
  582. // });
  583. } else {
  584. let query = {
  585. tenantId: this.fromTenantId,
  586. dataSource: this.dataSourceForm,
  587. };
  588. bindDatasource(query).then((response) => {
  589. if (response.code == 200) {
  590. let data = {
  591. userName: this.dataSourceForm.tenantAccount,
  592. nickName: this.currentTenantInfo.tenantName,
  593. userType: "01",
  594. tenantId: this.currentTenantInfo.tenantId,
  595. password: "123456",
  596. };
  597. createTenant(data).then(async (res) => {
  598. if (res.code == 200) {
  599. let resp = await initTenantMenuData(
  600. this.currentTenantInfo.tenantId
  601. );
  602. if ((resp.code = 200)) {
  603. this.$modal.msgSuccess("新增成功");
  604. this.dataSourceOpen = false;
  605. // loading.close();
  606. this.getList();
  607. }
  608. }
  609. });
  610. }
  611. });
  612. }
  613. }
  614. });
  615. },
  616. /** 删除按钮操作 */
  617. handleDelete(row) {
  618. const tenantIds = row.tenantId || this.ids;
  619. this.$modal
  620. .confirm('是否确认删除租户信息编号为"' + tenantIds + '"的数据项?')
  621. .then(function () {
  622. return delTenant(tenantIds);
  623. })
  624. .then(() => {
  625. this.getList();
  626. this.$modal.msgSuccess("删除成功");
  627. })
  628. .catch(() => {});
  629. },
  630. /** 导出按钮操作 */
  631. handleExport() {
  632. this.download(
  633. "system/tenant/export",
  634. {
  635. ...this.queryParams,
  636. },
  637. `tenant_${new Date().getTime()}.xlsx`
  638. );
  639. },
  640. /**
  641. * 选择数据源校验名称
  642. */
  643. selecthandle(row) {
  644. let sql = {
  645. sqlserver: "sqlserver_connection_information",
  646. mysql: "mysql_connection_information",
  647. dm: "dm_connection_information",
  648. oracle: "oracle_connection_information",
  649. };
  650. let qar = {};
  651. this.dict.type[sql[row]].forEach((item) => {
  652. qar[item.label] = item.value;
  653. });
  654. if (this.dataSourceType) {
  655. let { databaseIp, password, portNumber, username } = qar;
  656. Object.assign(this.dataSourceForm, {
  657. databaseIp,
  658. password,
  659. portNumber,
  660. username,
  661. });
  662. }
  663. getDataSourceInfo(qar).then((res) => {
  664. console.log(res);
  665. });
  666. },
  667. handleTest() {
  668. let formdata = {
  669. databaseType: "mysql",
  670. databaseName: "test1111",
  671. databaseIp: "127.0.0.1",
  672. username: "testname",
  673. password: "123123",
  674. portNumber: "3306",
  675. };
  676. insertDataSource(formdata).then((res) => {
  677. console.log(res);
  678. });
  679. },
  680. },
  681. };
  682. </script>