SaaS平台开发实战(五):订单服务模块

目录

引读

创建客户

Postman调试

订单服务模块

idea端配置和入口程序

pom.xml

V1.0.0__init_ddl.sql

V1.0.1__create_undo_ddl.sql

application.yml

bootstrap.yml

OrderApplication

Nacos配置

saasdemo-order-dev.yml

shardingsphere-saasdemo-order.yml

构建订单服务模块环境

生成数据表

生成订单模块代码


引读

在上一章我们创建了租户,生成了用户服务模块的代码, 这一章我们将根据商场的业务模型编写订单服务模块。

BUG修复说明:

在上一章中,我们重构了框架代码(框架重构造成的BUG),有另外一个bug漏掉了,请重新拉取最新代码并且编译,删除生成的代码重新生成。

为了更好的服务中国用户,我们今天重新发布了gitee版本(https://gitee.com/kutasms/multienty.git.git)

创建客户

在创建订单服务模块之前,我们需要创建客户信息。

request body:

{
    "nickName": "wangdefa",
    "sex": 0,
    "birthday": null,
    "phoneNumber": "13880985300",
    "inBlackList": false,
    "isMember": false,
    "avatarUrl": "",
    "memberSourceType": 0,
    "growth": 0,
    "credit": 0,
    "status": "NORMAL",
    "tenantId": "1211071336825459910"
}

Postman调试

执行后

数据库中已生成客户数据。


订单服务模块

idea端配置和入口程序

接下来,我们新增订单服务模块

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>SaasDemo</artifactId><version>1.0-SNAPSHOT</version></parent>

    <artifactId>saasmode-order</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>saasdemo-core</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

创建saasdemo-order资源文件和目录

V1.0.0__init_ddl.sql
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;


--
-- Table structure for table `saas_trade`
--
DROP TABLE IF EXISTS `saas_trade`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_trade` (
  `trade_id` bigint(20) NOT NULL COMMENT '交易编号',
  `tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `total_amount` decimal(12,2) DEFAULT NULL COMMENT '总金额',
  `discount_amount` decimal(12,2) DEFAULT NULL COMMENT '优惠金额',
  `paid_amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
  `paid` bit(1) DEFAULT NULL COMMENT '是否已支付',
  `order_count` int DEFAULT NULL COMMENT '订单数量',
  `refunded_count` int DEFAULT NULL COMMENT '已退款数量',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`trade_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易';
/*!40101 SET character_set_client = @saved_cs_client */;


--
-- Table structure for table `saas_order`
--
DROP TABLE IF EXISTS `saas_order`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order` (
  `order_id` bigint(20) NOT NULL COMMENT '订单编号',
  `tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
  `trade_id` bigint NOT NULL COMMENT '交易编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `total_amount` decimal(12,2) DEFAULT NULL COMMENT '总金额',
  `discount_amount` decimal(12,2) DEFAULT NULL COMMENT '优惠金额',
  `paid_amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
  `paid` bit(1) DEFAULT NULL COMMENT '是否已支付',
  `refunded` bit(1) DEFAULT NULL COMMENT '是否已退款',
  `order_type` smallint DEFAULT NULL COMMENT '订单类型',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单';
/*!40101 SET character_set_client = @saved_cs_client */;


--
-- Table structure for table `saas_order_buy_member`
--
DROP TABLE IF EXISTS `saas_order_buy_member`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_buy_member` (
  `order_id` bigint(20) NOT NULL COMMENT '订单编号',
  `tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `member_id` bigint NOT NULL COMMENT '会员编号',
  `member_name` varchar(64) NOT NULL COMMENT '会员名称',
  `member_price` decimal(12,2) NOT NULL COMMENT '会员价格',
  `quantity` int NOT NULL COMMENT '购买数量',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单购买会员';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `saas_order_buy_coupon`
--
DROP TABLE IF EXISTS `saas_order_buy_coupon`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_buy_coupon` (
  `obc_id` bigint(20) NOT NULL COMMENT '优惠券购买编号',
  `order_id` bigint(20) NOT NULL COMMENT '订单编号',
  `tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `coupon_id` bigint NOT NULL COMMENT '优惠券编号',
  `coupon_name` varchar(64) NOT NULL COMMENT '优惠券名称',
  `coupon_price` decimal(12,2) NOT NULL COMMENT '优惠券价格',
  `quantity` int NOT NULL COMMENT '购买数量',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`obc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单购买优惠券';
/*!40101 SET character_set_client = @saved_cs_client */;



--
-- Table structure for table `saas_order_detail`
--
DROP TABLE IF EXISTS `saas_order_detail`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_detail` (
  `order_id` bigint(20) NOT NULL COMMENT '订单编号',
  `tenant_id` bigint(20) DEFAULT NULL COMMENT '租户编号',
  `trade_id` bigint NOT NULL COMMENT '交易编号',
  `received` bit(1) DEFAULT NULL COMMENT '是否已收货',
  `customer_nick` varchar(32) DEFAULT NULL COMMENT '客户昵称',
  `customer_phone` varchar(11) DEFAULT NULL COMMENT '客户手机号',
  `coupon_id` bigint DEFAULT NULL COMMENT '优惠券编号',
  `activity_id` bigint DEFAULT NULL COMMENT '活动编号',
  `activity_type` smallint DEFAULT NULL COMMENT '活动类型',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单详情';
/*!40101 SET character_set_client = @saved_cs_client */;


--
-- Table structure for table `saas_order_item`
--
DROP TABLE IF EXISTS `saas_order_item`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_item` (
  `item_id` bigint NOT NULL COMMENT '订单项编号',
  `order_id` bigint DEFAULT NULL COMMENT '订单编号',
  `product_id` bigint DEFAULT NULL COMMENT '商品编号',
  `sku_id` bigint DEFAULT NULL COMMENT '商品规格编号',
  `tenant_id` bigint DEFAULT NULL COMMENT '租户编号',
  `product_name` varchar(64) DEFAULT NULL COMMENT '商品名称',
  `sku_name` varchar(64) DEFAULT NULL COMMENT '商品规格名称',
  `price` decimal(12,2) DEFAULT NULL COMMENT '商品价格',
  `quantity` int DEFAULT NULL COMMENT '购买数量',
  `total_amount` decimal(12,2) DEFAULT NULL COMMENT '总价',
  `diff_amount` decimal(12,2) DEFAULT NULL COMMENT '金额差异',
  `image` varchar(128) DEFAULT NULL COMMENT '商品主图',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单项';
/*!40101 SET character_set_client = @saved_cs_client */;



--
-- Table structure for table `saas_order_item_attr`
--
DROP TABLE IF EXISTS `saas_order_item_attr`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_order_item_attr` (
  `item_id` bigint(20) NOT NULL COMMENT '订单项编号',
  `tenant_id` bigint(20) DEFAULT NULL COMMENT '租户编号',
  `name` varchar(32) DEFAULT NULL COMMENT '规格名称',
  `value` varchar(128) DEFAULT NULL COMMENT '规格值',
  `code_name` varchar(64) DEFAULT NULL COMMENT '规格代码名称',
  `code_value` varchar(128) DEFAULT NULL COMMENT '规格代码值',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单项属性';
/*!40101 SET character_set_client = @saved_cs_client */;


--
-- Table structure for table `saas_pay_log`
--
DROP TABLE IF EXISTS `saas_pay_log`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `saas_pay_log` (
  `log_id` bigint NOT NULL COMMENT '支付日志编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `tenant_id` bigint DEFAULT NULL COMMENT '租户编号',
  `trade_id` bigint DEFAULT NULL COMMENT '交易编号',
  `order_id` bigint DEFAULT NULL COMMENT '订单编号',
  `amount` decimal(12,2) DEFAULT NULL COMMENT '支付金额',
  `describe` varchar(64) DEFAULT NULL COMMENT '描述',
  `payer_remark` varchar(64) DEFAULT NULL COMMENT '付款方备注',
  `payee_remark` varchar(64) DEFAULT NULL COMMENT '收款方备注',
  `out_trade_no` varchar(32) DEFAULT NULL COMMENT '交易号码',
  `third_no` varchar(48) DEFAULT NULL COMMENT '第三方交易编号',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`log_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付日志';
/*!40101 SET character_set_client = @saved_cs_client */;


--
-- Table structure for table `saas_shopping_cart`
--
DROP TABLE IF EXISTS `saas_shopping_cart`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `saas_shopping_cart` (
  `cart_id` bigint(20) NOT NULL COMMENT '购物车编号',
  `tenant_id` bigint(20) NOT NULL COMMENT '租户编号',
  `product_id` bigint NOT NULL COMMENT '商品编号',
  `sku_id` bigint NOT NULL COMMENT '商品规格编号',
  `customer_id` bigint NOT NULL COMMENT '客户编号',
  `quantity` int DEFAULT NULL COMMENT '数量',
  `status` varchar(32) DEFAULT NULL COMMENT '状态',
  `version` bigint DEFAULT NULL COMMENT '乐观锁版本号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='购物车';
/*!40101 SET character_set_client = @saved_cs_client */;

/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
V1.0.1__create_undo_ddl.sql
--
-- Table structure for table `undo_log`
--
DROP TABLE IF EXISTS `undo_log`;
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
application.yml
spring:
  profiles:
    active: dev

dubbo.application.logger: slf4j
bootstrap.yml
server:
  port: 8877

spring:
  application:
    name: saasdemo-order
  cloud:
    nacos:
      discovery:
        server-addr: nacos.xxxx.com:xxxx
        namespace: xxxxx-xxxx-xxxx-xxxxx
        username: xxxx
        password: xxxxx
      config:
        server-addr: nacos.xxxx.com:xxxx
        namespace: xxxxx-xxxx-xxxx-xxxxx
        username: xxxx
        password: xxxxx
        file-extension: yml
        extension-configs[0]:
          data-id: shardingsphere-saasdemo-order.yml
          group: DEFAULT_GROUP
          refresh: true
        extension-configs[1]:
          data-id: multienty.yml
          group: DEFAULT_GROUP
          refresh: true
        extension-configs[2]:
          data-id: redis.yml
          group: DEFAULT_GROUP
          refresh: true
        extension-configs[3]:
          data-id: rabbitmq.yml
          group: DEFAULT_GROUP
          refresh: true
seata:
  enabled: true
  application-id: seata-server
  # 客户端和服务端在同一个事务组; Seata 事务组编号,用于 TC 集群名, 一定要和 config.tx(nacos) 中配置的相同
  tx-service-group: tx_order_group
  # 自动数据源代理
  enable-auto-data-source-proxy: false
  # 数据源代理模式(分布式事务方案)
  data-source-proxy-mode: AT
  service:
    vgroup-mapping:
      tx_order_group: default
  config:
    # support: nacos, consul, apollo, zk, etcd3, file
    type: nacos
    nacos:
      server-addr: nacos.xxxx.cn:xxxx
      namespace: xxxxx-xxxx-xxxx-xxxxx
      group: SEATA_GROUP
      username: xxxx
      password: xxxx
      data-id: seata-server.properties
      cluster: default
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      server-addr: nacos.xxxx.cn:xxxx
      namespace: xxxxx-xxxx-xxxx-xxxxx
      group: SEATA_GROUP
      username: xxxx
      password: xxxx
      # 默认TC集群名
      cluster: default
      # 服务名,与服务端中registry.conf配置要一致
      application: seata-server
      context-path:

dubbo:
  enabled: true
  metadata-report:
    address: nacos://xxxxx.com:xxxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
    username: xxxxx
    password: xxxxxx
    parameters:
      namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
    retry-times: 30  #重试次数,默认100
    cycle-report: false #关闭定时刷新
  application:
    name: order-provider
    # 禁用QOS同一台机器可能会有端口冲突现象
    qos-enable: false
    qos-accept-foreign-ip: false
    service-discovery:
      migration: FORCE_APPLICATION # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
  protocol:
    name: dubbo
    port: -1
  scan:
    base-packages: org.example.saas.order.dubbo.service.impl
  cloud:
    subscribed-services: saasdemo-user, saasdemo-master
  registry:
    address: nacos://xxxxx.com:xxxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
    parameters:
      namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
  consumer:
    check: false
OrderApplication

添加程序入口

OrderApplication

package org.example.saas.order;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(value = {
        "com.chia.multienty.core",
        "org.example.saas.core",
        "org.example.saas.order",
})
@EnableDubbo
@MapperScan(value={"com.chia.multienty.core.mapper","org.example.saas.core.mapper"})
public class OrderApplication {
    public static void main(String[] args) {

        ConfigurableApplicationContext context = SpringApplication.run(OrderApplication.class, args);

    }
}

好了,idea中差不多了,切换到nacos管理后台,配置订单服务模块

Nacos配置

saasdemo-order-dev.yml

在dev中创建saasdemo-order-dev.yml

spring:
    shardingSphere:
        enabled: true
    rabbitmq:
        enabled: true
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        dynamic:
            enabled: true
            primary: sharding
            datasource:
                ds_root:
                    driver-class-name: com.mysql.cj.jdbc.Driver
                    url: jdbc:mysql://xxxx.xxx:3333/mysql?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
                    username: root
                    password: xxxxxxx


    kuta:
        multi-tenant:
            domain: order.xxxx.xxxx
            security:
                auth:
                    header: X-TOKEN
                    # ALL 接受所有平台token
                    token-prefix: ALL
                    base64-secret: xxxxxxxx
                    # 令牌持有时间(秒)
                    token-holding-time: 86400
                    # 客户持有令牌时间,-1永久
                    customer-token-time: 86400
                    # 续期时长
                    renew-time: 86400
                    # 是否支持多点登陆
                    multipoint-login-enabled: true
                    ignore-paths:
                        - /file/upload
                        - /code/generate
                rsa:
                    private-key: xxxxxxxx
                    public-key: xxxxxxxxx==
                wechat:
                    pay:
                        v3NotifyUrls:
                            order-pay: ${spring.kuta.multi-tenant.domain}/trade/wx/handleWxV3PayNotify/%s
            file:
                # 大写
                storage-mode: LOCAL
                custom:
                    custom-file-upload-service-impl-class: org.example.saas.core.strategy.file.impl.QNYFileUploadServiceImpl
                local:
                    path-prefix: C:\projects\multi-tenant\store
                    url-prefix: https://${spring.kuta.multi-tenant.domain}/local/

        code-generator:
            author: "Multienty Auto Generator"
            root-package: org.example.saas
            common-module-name: saasdemo-core
            table-prefix: saas_
            controller-module-name: saasdemo-order
            # controller save path=project-path(user.dir) + "/" + controller-module-name + controller-file-path-suffix
            controller-file-path-suffix: /src/main/java/org/example/saas/order/controller
            dto-file-path-suffix: /src/main/java/org/example/saas
            # AUTO, NONE, INPUT, ASSIGN_ID, ASSIGN_UUID
            id-type: INPUT
            logic-delete-column-name: deleted
            
            dto-full-package-name: org.example.saas.core.domain.dto
            table-fills:
                version: INSERT
                create_time: INSERT
                update_time: UPDATE
                deleted: INSERT
                status: INSERT
            packages:
                controller: order.controller
                entity: core.pojo
                service: core.service.order
                mapper: core.mapper
                service-impl: core.service.order.impl
                dto: core.domain.dto
                parameter: core.parameter
            formatter:
                controller: "%sController"
                entity: "%s"
                service: "%sService"
                service-impl: "%sServiceImpl"
                mapper: "%sMapper"
                xml: "%sMapper"
            database:
                host: xxxxx.xxxx
                port: 3333
                db-name: saas_order_1
                username: saas_order_1
                password: xxxxx
            package-merge-mapping:
                Trade: order
                Order: order
                OrderDetail: order
                OrderItem: order
                OrderItemAttr: order
                PayLog: order
                ShoppingCart: order
            tables:
                - saas_trade
                - saas_order
                - saas_order_detail
                - saas_order_item
                - saas_order_item_attr
shardingsphere-saasdemo-order.yml

在dev中创建shardingsphere-saasdemo-order.yml

spring:
    shardingsphere:
        enabled: true
        dataSource:
            common:
                type: com.alibaba.druid.pool.DruidDataSource
                validationQuery: SELECT 1 FROM DUAL
            names:
                ds_order_1, ds_order_2
            ds_order_1:
                type: com.alibaba.druid.pool.DruidDataSource
                driverClassName: com.mysql.cj.jdbc.Driver
                url: jdbc:mysql://xxxx:xxxx/saas_order_1?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
                username: saas_order_1
                password: xxxxxxx
            ds_order_2:
                type: com.alibaba.druid.pool.DruidDataSource
                driverClassName: com.mysql.cj.jdbc.Driver
                url: jdbc:mysql://xxxxxx:xxxx/saas_order_2?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
                username: saas_order_2
                password: xxxxxx
        rules:
            sharding:
                tables:
                    saas_trade:
                        actualDataNodes: ds_order_${1..2}.saas_trade_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_trade")}
                        tableStrategy:
                            standard:
                                shardingAlgorithmName: create-time-standard
                                shardingColumn: create_time
                    saas_order:
                        actualDataNodes: ds_order_${1..2}.saas_order_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order")}
                        tableStrategy:
                            standard:
                                shardingAlgorithmName: create-time-standard
                                shardingColumn: create_time
                    saas_order_detail:
                        actualDataNodes: ds_order_${1..2}.saas_order_detail_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_detail")}
                        tableStrategy:
                            standard:
                                shardingAlgorithmName: create-time-standard
                                shardingColumn: create_time
                    saas_order_item:
                        actualDataNodes: ds_order_${1..2}.saas_order_item_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_item")}
                        tableStrategy:
                            standard:
                                shardingAlgorithmName: create-time-standard
                                shardingColumn: create_time
                    saas_order_item_attr:
                        actualDataNodes: ds_order_${1..2}.saas_order_item_attr_${com.chia.multienty.core.sharding.tools.ShardingAlgorithmTool.tableNames("saas_order_item_attr")}
                        tableStrategy:
                            standard:
                                shardingAlgorithmName: create-time-standard
                                shardingColumn: create_time
                shardingAlgorithms:
                    create-time-standard:
                        type: CLASS_BASED
                        props:
                            strategy: standard
                            algorithmClassName: com.chia.multienty.core.sharding.algorithm.CreateTimeShardingAlgorithm
                    order-db-inline:
                        type: INLINE
                        props: 
                            algorithm-expression: ds_order_${tenant_id % 2 + 1}
                defaultDatabaseStrategy:
                    standard:
                        shardingColumn: tenant_id
                        shardingAlgorithmName: order-db-inline
                bindingTables:
                    - saas_order, saas_order_detail, saas_order_item, saas_order_item_attr
        props:
            sql-show: true

构建订单服务模块环境

生成数据表

OK, 订单模块配置完成,启动OrderApplication

订单服务模块数据表已生成

生成订单模块代码

接下来生成订单模块的代码

代码已生成

我们来看看订单服务模块这种分库分表的代码和用户服务模块只分库生成代码的区别

package org.example.saas.core.service.order.impl;

import org.example.saas.core.pojo.Trade;
import org.example.saas.core.mapper.TradeMapper;
import org.example.saas.core.service.order.TradeService;
import com.chia.multienty.core.mybatis.service.impl.KutaBaseServiceImpl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.example.saas.core.domain.dto.TradeDTO;
import org.example.saas.core.parameter.order.TradeDetailGetParameter;
import org.example.saas.core.parameter.order.TradePageGetParameter;
import org.example.saas.core.parameter.order.TradeDeleteParameter;
import org.example.saas.core.parameter.order.TradeSaveParameter;
import org.example.saas.core.parameter.order.TradeUpdateParameter;
import org.example.saas.core.parameter.order.TradeEnableParameter;
import org.example.saas.core.parameter.order.TradeDisableParameter;
import com.github.yulichang.toolkit.MPJWrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import com.chia.multienty.core.domain.constants.MultiTenantConstants;
import com.chia.multienty.core.mybatis.MTLambdaWrapper;
import com.chia.multienty.core.util.ListUtil;
import com.chia.multienty.core.domain.enums.StatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chia.multienty.core.tools.MultiTenantContext;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.chia.multienty.core.tools.IdWorkerProvider;
/**
 * <p>
 * 交易 服务实现类
 * </p>
 *
 * @author Multi Tenant Auto Generator
 * @since 2024-02-25
 */
@Service
@RequiredArgsConstructor
@DS(MultiTenantConstants.DS_SHARDING)
public class TradeServiceImpl extends KutaBaseServiceImpl<TradeMapper, Trade> implements TradeService {


    @Override
    public TradeDTO getDetail(TradeDetailGetParameter parameter) {
        return selectJoinOne(TradeDTO.class,
                        MPJWrappers.<Trade>lambdaJoin()
                        .eq(Trade::getTenantId, parameter.getTenantId())
                        .eq(Trade::getCreateTime, parameter.getCreateTime())
                        .eq(Trade::getTradeId, parameter.getTradeId()));
    }

    @Override
    public void update(TradeUpdateParameter parameter) {
        Trade trade = new Trade();
        BeanUtils.copyProperties(parameter, trade);
        update(trade, new LambdaQueryWrapper<Trade>()
                .eq(Trade::getTenantId, parameter.getTenantId())
                .eq(Trade::getCreateTime, parameter.getCreateTime())
                .eq(Trade::getTradeId, parameter.getTradeId()));
    }

    @Override
    public void delete(TradeDeleteParameter parameter) {
        removeTE(new LambdaQueryWrapper<Trade>()
                .eq(Trade::getTenantId, parameter.getTenantId())
                .eq(Trade::getCreateTime, parameter.getCreateTime())
                .eq(Trade::getTradeId, parameter.getTradeId()));
    }

    @Override
    public IPage<TradeDTO> getPage(TradePageGetParameter parameter) {
        return selectJoinListPage(parameter.getPageObj(), TradeDTO.class,
                new MTLambdaWrapper<Trade>()
                        .solveGenericParameters(parameter)
                        .eq(Trade::getTenantId, parameter.getTenantId())
                        .in(!ListUtil.isEmpty(parameter.getTradeIds()),
                                Trade::getTradeId,
                                parameter.getTradeIds())
        );
    }

    @Override
    public void save(TradeSaveParameter parameter) {
        Trade trade = new Trade();
        BeanUtils.copyProperties(parameter, trade);
        trade.setTradeId(IdWorkerProvider.next());
        saveTE(trade);
        trade.setTenantId(MultiTenantContext.getTenant().getTenantId());
        parameter.setTradeId(trade.getTradeId());
    }


    @Override
    public void enable(TradeEnableParameter parameter) {
        Trade trade = new Trade();
        BeanUtils.copyProperties(parameter, trade);
        trade.setStatus(StatusEnum.NORMAL.getCode());
        update(trade, new LambdaQueryWrapper<Trade>()
                .eq(Trade::getTenantId, parameter.getTenantId())
                .eq(Trade::getCreateTime, parameter.getCreateTime())
                .eq(Trade::getTradeId, parameter.getTradeId()));

    }

    @Override
    public void disable(TradeDisableParameter parameter) {
        Trade trade = new Trade();
        BeanUtils.copyProperties(parameter, trade);
        trade.setStatus(StatusEnum.DISABLED.getCode());
        update(trade, new LambdaQueryWrapper<Trade>()
                .eq(Trade::getTenantId, parameter.getTenantId())
                .eq(Trade::getCreateTime, parameter.getCreateTime())
                .eq(Trade::getTradeId, parameter.getTradeId()));
    }
}

因为我们是用租户编号分库, 按年月组合进行分表,所以在各个接口中均包含了tenantId和createTime字段。

由于篇幅原因,文章到此结束,下一章我们将开始模拟创建订单(因为demo中未演示商品相关模块,所以商品信息我们将模拟填写)

OK,bye!

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Multienty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值