Răsfoiți Sursa

租户绑定数据源

xuezizhuo 1 an în urmă
părinte
comite
60f3dc96c2

+ 13 - 0
pom.xml

@@ -170,6 +170,19 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <!-- mybatis-plus -->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>3.5.2</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>1.18.24</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 44 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/DataSourceController.java

@@ -0,0 +1,44 @@
+package com.ruoyi.web.controller.system;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.DataSource;
+import com.ruoyi.system.service.IDataSourceService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/dataSource")
+public class DataSourceController extends BaseController {
+
+    @Resource
+    private IDataSourceService dataSourceService;
+
+    /**
+     * 数据源信息列表
+     */
+    @GetMapping("/list")
+    public AjaxResult dataSourceList(){
+        return AjaxResult.success(dataSourceService.list());
+    }
+
+    /**
+     * 新增数据源
+     */
+    @PostMapping("/save")
+    public AjaxResult addDataSource(@RequestBody Map<String,Object> map){
+
+        DataSource dataSource = JSON.parseObject(JSON.toJSONString(map.get("dataSource")), DataSource.class);
+        Long tenantId = (Long)map.get("tenantId");
+
+        if(dataSourceService.selectDatabaseExist(dataSource.getDatabaseIp(),dataSource.getDatabaseName(),dataSource.getPortNumber())>0){
+            return AjaxResult.error("数据源已存在");
+        }
+        return toAjax(dataSourceService.insertDataSource(dataSource,tenantId));
+    }
+
+}

+ 8 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

@@ -4,6 +4,7 @@ import java.util.List;
 import java.util.Set;
 
 import com.ruoyi.common.core.domain.entity.SysTenant;
+import com.ruoyi.common.utils.http.HttpUtils;
 import com.ruoyi.system.service.impl.SysTenantServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -42,6 +43,8 @@ public class SysLoginController
     @Resource
     private SysTenantServiceImpl sysTenantService;
 
+
+
     /**
      * 登录方法
      * 
@@ -78,8 +81,13 @@ public class SysLoginController
         ajax.put("permissions", permissions);
         //租户信息
         if(user.getTenantId() != null){
+            //租户信息
             SysTenant sysTenant = sysTenantService.selectSysTenantByTenantId(user.getTenantId());
             ajax.put("tenant",sysTenant);
+            //调用数据引擎服务切换数据源接口
+            String param = "id="+sysTenant.getDatasourceId();
+            String data = HttpUtils.sendGet("http://localhost:8081/dataSource/changeDataSource",param);
+            System.err.println(data);
         }
         return ajax;
     }

+ 10 - 0
ruoyi-common/pom.xml

@@ -126,6 +126,16 @@
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 55 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/DataSource.java

@@ -0,0 +1,55 @@
+package com.ruoyi.common.core.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@TableName("data_source")
+public class DataSource implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 字典编码
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 数据库名
+     */
+    private String databaseName;
+
+    /**
+     * 数据库IP
+     */
+    private String databaseIp;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 端口号
+     */
+    private Long portNumber;
+
+    /**
+     * 数据库类型
+     */
+    private String databaseType;
+
+
+}

+ 18 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/DataSourceMapper.java

@@ -0,0 +1,18 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.common.core.domain.entity.DataSource;
+import org.apache.ibatis.annotations.Param;
+
+public interface DataSourceMapper extends BaseMapper<DataSource> {
+
+    /**
+     * 查询同一数据源下数据库是否存在
+     */
+    int selectDatabaseExist(@Param("databaseIp") String databaseIp,@Param("databaseName") String databaseName,@Param("portNumber") Long portNumber);
+
+    /**
+     * 新增数据源
+     */
+    int insertDataSource(DataSource dataSource);
+}

+ 18 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/IDataSourceService.java

@@ -0,0 +1,18 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.domain.entity.DataSource;
+
+public interface IDataSourceService extends IService<DataSource> {
+
+    /**
+     * 查询同一数据源下数据库是否存在
+     */
+    int selectDatabaseExist(String databaseIp, String databaseName, Long portNumber);
+
+    /**
+     * 绑定数据源,和租户关联
+     */
+    int insertDataSource(DataSource dataSource,Long tenantId);
+
+}

+ 38 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DataSourceServiceImpl.java

@@ -0,0 +1,38 @@
+package com.ruoyi.system.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.entity.DataSource;
+import com.ruoyi.common.core.domain.entity.SysTenant;
+import com.ruoyi.system.mapper.DataSourceMapper;
+import com.ruoyi.system.service.IDataSourceService;
+import com.ruoyi.system.service.ISysTenantService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSource> implements IDataSourceService {
+
+    @Resource
+    private DataSourceMapper dataSourceMapper;
+
+    @Resource
+    private ISysTenantService sysTenantService;
+
+    @Override
+    public int selectDatabaseExist(String databaseIp, String databaseName, Long portNumber) {
+        return dataSourceMapper.selectDatabaseExist(databaseIp,databaseName,portNumber);
+    }
+
+    @Override
+    public int insertDataSource(DataSource dataSource,Long tenantId) {
+        dataSourceMapper.insertDataSource(dataSource);
+        //租户绑定数据源
+        SysTenant sysTenant = new SysTenant();
+        sysTenant.setTenantId(tenantId);
+        sysTenant.setDatasourceId(dataSource.getId());
+        return sysTenantService.updateSysTenant(sysTenant);
+    }
+
+}

+ 17 - 0
ruoyi-system/src/main/resources/mapper/system/DataSourceMapper.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.DataSourceMapper">
+
+    <select id="selectDatabaseExist" resultType="int">
+        select count(1) from data_source where database_ip = #{databaseIp} and database_name = #{databaseName} and port_number = #{portNumber}
+    </select>
+
+    <insert id="insertDataSource" useGeneratedKeys="true" keyProperty="id">
+        insert into data_source(database_name,database_ip,username,password,port_number,database_type)
+        values (#{databaseName},#{databaseIp},#{username},#{password},#{portNumber},#{databaseType})
+    </insert>
+
+
+</mapper>

+ 9 - 0
ruoyi-ui/src/api/system/tenant.js

@@ -42,3 +42,12 @@ export function delTenant(tenantId) {
     method: 'delete'
   })
 }
+
+//绑定数据源
+export function bindDatasource(data) {
+  return request({
+    url: '/dataSource/save',
+    method: 'post',
+    data: data
+  })
+}

+ 119 - 119
ruoyi-ui/src/views/system/tenant/index.vue

@@ -1,78 +1,31 @@
 <template>
   <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryForm"
-      size="small"
-      :inline="true"
-      v-show="showSearch"
-      label-width="68px"
-    >
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="租户名称" prop="tenantName">
-        <el-input
-          v-model="queryParams.tenantName"
-          placeholder="请输入租户名称"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.tenantName" placeholder="请输入租户名称" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="租户编号" prop="tenantCode">
-        <el-input
-          v-model="queryParams.tenantCode"
-          placeholder="请输入租户编号"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.tenantCode" placeholder="请输入租户编号" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="负责人" prop="owner">
-        <el-input
-          v-model="queryParams.owner"
-          placeholder="请输入负责人"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.owner" placeholder="请输入负责人" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="联系方式" prop="contactInfo">
-        <el-input
-          v-model="queryParams.contactInfo"
-          placeholder="请输入联系方式"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.contactInfo" placeholder="请输入联系方式" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item label="地址" prop="address">
-        <el-input
-          v-model="queryParams.address"
-          placeholder="请输入地址"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+        <el-input v-model="queryParams.address" placeholder="请输入地址" clearable @keyup.enter.native="handleQuery" />
       </el-form-item>
       <el-form-item>
-        <el-button
-          type="primary"
-          icon="el-icon-search"
-          size="mini"
-          @click="handleQuery"
-          >搜索</el-button
-        >
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
-          >重置</el-button
-        >
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
 
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="el-icon-plus"
-          size="mini"
-          @click="handleAdd"
-          v-hasPermi="['system:tenant:add']"
-          >新增</el-button
-        >
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+          v-hasPermi="['system:tenant:add']">新增</el-button>
       </el-col>
       <!-- <el-col :span="1.5">
         <el-button
@@ -86,39 +39,17 @@
         >修改</el-button>
       </el-col> -->
       <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['system:tenant:remove']"
-          >删除</el-button
-        >
+        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
+          v-hasPermi="['system:tenant:remove']">删除</el-button>
       </el-col>
       <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-download"
-          size="mini"
-          @click="handleExport"
-          v-hasPermi="['system:tenant:export']"
-          >导出</el-button
-        >
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
+          v-hasPermi="['system:tenant:export']">导出</el-button>
       </el-col>
-      <right-toolbar
-        :showSearch.sync="showSearch"
-        @queryTable="getList"
-      ></right-toolbar>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table
-      v-loading="loading"
-      :data="tenantList"
-      @selection-change="handleSelectionChange"
-    >
+    <el-table v-loading="loading" :data="tenantList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="租户ID" align="center" prop="tenantId" />
       <el-table-column label="租户名称" align="center" prop="tenantName" />
@@ -126,50 +57,27 @@
       <el-table-column label="负责人" align="center" prop="owner" />
       <el-table-column label="联系方式" align="center" prop="contactInfo" />
       <el-table-column label="地址" align="center" prop="address" />
-      <el-table-column
-        label="操作"
-        align="center"
-        class-name="small-padding fixed-width"
-      >
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-dropdown>
             <el-button type="warning" plain size="small">
               处理<i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item
-                ><el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-edit"
-                  @click="handleUpdate(scope.row)"
-                  v-hasPermi="['system:tenant:edit']"
-                  >修改</el-button
-                ></el-dropdown-item
-              >
-              <el-dropdown-item
-                ><el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-delete"
-                  @click="handleDelete(scope.row)"
-                  v-hasPermi="['system:tenant:remove']"
-                  >删除</el-button
-                ></el-dropdown-item
-              >
+              <el-dropdown-item><el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                  v-hasPermi="['system:tenant:edit']">修改</el-button></el-dropdown-item>
+              <el-dropdown-item><el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                  v-hasPermi="['system:tenant:remove']">删除</el-button></el-dropdown-item>
+              <el-dropdown-item><el-button size="mini" type="text" icon="el-icon-edit" @click="bindDatasource(scope.row)"
+                  v-hasPermi="['system:tenant:edit']">绑定数据源</el-button></el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
       </el-table-column>
     </el-table>
 
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
-      @pagination="getList"
-    />
+    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+      @pagination="getList" />
 
     <!-- 添加或修改租户信息对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
@@ -195,6 +103,37 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 添加或修改数据源信息对话框 -->
+    <el-dialog :title="dataSourceTitle" :visible.sync="dataSourceOpen" width="500px" append-to-body>
+      <el-form ref="dataSourceForm" :model="dataSourceForm" :rules="rules" label-width="90px">
+        <el-form-item label="数据源类型">
+          <el-select v-model="dataSourceForm.databaseType" placeholder="请选择数据源类型">
+            <el-option v-for="item in dict.type.datasource_type" :key="item.value" :label="item.label"
+              :value="item.value"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="数据库名称" prop="databaseName">
+          <el-input v-model="dataSourceForm.databaseName" placeholder="请输入数据库名称" />
+        </el-form-item>
+        <el-form-item label="数据库IP" prop="databaseIp">
+          <el-input v-model="dataSourceForm.databaseIp" placeholder="请输数据库IP" />
+        </el-form-item>
+        <el-form-item label="用户名" prop="username">
+          <el-input v-model="dataSourceForm.username" placeholder="请输入用户名" />
+        </el-form-item>
+        <el-form-item label="密码" prop="password">
+          <el-input v-model="dataSourceForm.password" placeholder="请输入密码" />
+        </el-form-item>
+        <el-form-item label="端口号" prop="portNumber">
+          <el-input v-model="dataSourceForm.portNumber" placeholder="请输入端口号" />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm1">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -205,10 +144,12 @@ import {
   delTenant,
   addTenant,
   updateTenant,
+  bindDatasource,
 } from "@/api/system/tenant";
 
 export default {
   name: "Tenant",
+  dicts: ['datasource_type'],
   data() {
     return {
       // 遮罩层
@@ -250,13 +191,18 @@ export default {
           { required: true, message: "租户编号不能为空", trigger: "blur" },
         ],
       },
+      //数据源表单参数
+      dataSourceForm: {},
+      dataSourceTitle: "",
+      dataSourceOpen: false,
+      fromTenantId: null,
     };
   },
   created() {
     this.getList();
   },
   methods: {
-    handleOpe() {},
+    handleOpe() { },
     /** 查询租户信息列表 */
     getList() {
       this.loading = true;
@@ -285,6 +231,19 @@ export default {
       };
       this.resetForm("form");
     },
+    // 表单重置
+    reset1() {
+      this.dataSourceForm = {
+        id: null,
+        databaseName: null,
+        databaseIp: null,
+        username: null,
+        password: null,
+        portNumber: null,
+        databaseType: null,
+      };
+      this.resetForm("dataSourceForm");
+    },
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
@@ -317,6 +276,20 @@ export default {
         this.title = "修改租户信息";
       });
     },
+    /** 绑定数据源按钮操作 */
+    bindDatasource(row) {
+      this.reset1();
+      this.dataSourceOpen = true;
+      this.dataSourceTitle = "绑定数据源信息";
+      this.fromTenantId = row.tenantId;
+
+      // const tenantId = row.tenantId || this.ids;
+      // getTenant(tenantId).then((response) => {
+      //   this.form = response.data;
+      //   this.open = true;
+      //   this.title = "修改租户信息";
+      // });
+    },
     /** 提交按钮 */
     submitForm() {
       this.$refs["form"].validate((valid) => {
@@ -337,6 +310,33 @@ export default {
         }
       });
     },
+    /** 提交按钮 */
+    submitForm1() {
+      this.$refs["dataSourceForm"].validate((valid) => {
+        console.log(valid);
+        if (valid) {
+          if (this.dataSourceForm.id != null) {
+            // bindDatasource(this.dataSourceForm).then((response) => {
+            //   this.$modal.msgSuccess("修改成功");
+            //   this.dataSourceOpen = false;
+            //   this.getList();
+            // });
+          } else {
+
+            console.log(this.fromTenantId)
+            let query = {
+              tenantId:this.fromTenantId,
+              dataSource: this.dataSourceForm
+            }
+            bindDatasource(query).then((response) => {
+              this.$modal.msgSuccess("新增成功");
+              this.dataSourceOpen = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
     /** 删除按钮操作 */
     handleDelete(row) {
       const tenantIds = row.tenantId || this.ids;
@@ -349,7 +349,7 @@ export default {
           this.getList();
           this.$modal.msgSuccess("删除成功");
         })
-        .catch(() => {});
+        .catch(() => { });
     },
     /** 导出按钮操作 */
     handleExport() {