From 5368350f42e698cfa27bf3e55cd9da4fea6767c7 Mon Sep 17 00:00:00 2001 From: Xiaya_kevin <1415130181@qq.com> Date: Tue, 9 Sep 2025 22:07:02 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=88=9B=E5=BB=BAQA=E7=9A=84=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qa-service/docker-compose.yml | 250 ++++++++++++++++++ qa-service/nacos_config.sql | 179 +++++++++++++ qa-service/pom.xml | 53 +++- .../qa-adapter-in/.gitignore | 33 +++ .../in/web/controller/QAController.java | 81 ++++++ .../in/web/dto/CreateQARequestDTO.java | 10 + .../qa/adapter/in/web/dto/QAResponseDTO.java | 18 ++ .../in/web/dto/UpdateQARequestDTO.java | 12 + .../persistence/bridge/CreateQABridge.java | 29 ++ .../persistence/bridge/DeleteQABridge.java | 23 ++ .../persistence/bridge/GetQAByIdBridge.java | 25 ++ .../persistence/bridge/GetQAListBridge.java | 36 +++ .../persistence/bridge/UpdateQABridge.java | 26 ++ .../persistence/convertor/QAConvertor.java | 29 ++ .../out/persistence/entity/QAEntity.java | 23 ++ .../out/persistence/mapper/QAMapper.java | 10 + .../application/command/CreateQACommand.java | 16 ++ .../application/command/UpdateQACommand.java | 15 ++ .../application/port/in/CreateQAUseCase.java | 12 + .../application/port/in/DeleteQAUseCase.java | 8 + .../application/port/in/GetQAByIdUseCase.java | 10 + .../application/port/in/GetQAListUseCase.java | 11 + .../application/port/in/UpdateQAUseCase.java | 10 + .../application/service/CreateQAService.java | 31 +++ .../application/service/DeleteQAService.java | 20 ++ .../application/service/GetQAByIdService.java | 22 ++ .../application/service/GetQAListService.java | 23 ++ .../application/service/UpdateQAService.java | 26 ++ .../src/main/resources/application.properties | 27 ++ .../example/qa/service/common/IdWorker.java | 199 ++++++++++++++ .../com/example/qa/service/domain/QA.java | 48 ++++ .../qa/service/domain/port/CreateQAPort.java | 11 + .../qa/service/domain/port/DeleteQAPort.java | 8 + .../qa/service/domain/port/GetQAByIdPort.java | 10 + .../qa/service/domain/port/GetQAListPort.java | 11 + .../qa/service/domain/port/UpdateQAPort.java | 9 + .../qa/service/domain/valueobject/Answer.java | 10 + .../qa/service/domain/valueobject/QAId.java | 10 + .../service/domain/valueobject/Question.java | 9 + 39 files changed, 1379 insertions(+), 14 deletions(-) create mode 100644 qa-service/docker-compose.yml create mode 100644 qa-service/nacos_config.sql create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/.gitignore create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QAController.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQARequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QAResponseDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQARequestDTO.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQABridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQABridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAByIdBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAListBridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQABridge.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QAConvertor.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QAEntity.java create mode 100644 qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QAMapper.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/command/CreateQACommand.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/command/UpdateQACommand.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/port/in/CreateQAUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/port/in/DeleteQAUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAByIdUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAListUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/port/in/UpdateQAUseCase.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/service/CreateQAService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/service/DeleteQAService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAByIdService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAListService.java create mode 100644 qa-service/qa-service-application/src/main/java/com/example/application/service/UpdateQAService.java create mode 100644 qa-service/qa-service-bootstrap/src/main/resources/application.properties create mode 100644 qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/QA.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQAPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQAPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAByIdPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAListPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQAPort.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QAId.java create mode 100644 qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java diff --git a/qa-service/docker-compose.yml b/qa-service/docker-compose.yml new file mode 100644 index 0000000..b92c130 --- /dev/null +++ b/qa-service/docker-compose.yml @@ -0,0 +1,250 @@ +networks: + app_net: + driver: bridge +services: + # MySQL 主库 + mysql: + image: mysql:8.4 + container_name: mysql + environment: + - MYSQL_ROOT_PASSWORD=root + - TZ=Asia/Shanghai + - MYSQL_CHARSET=utf8mb4 + - MYSQL_COLLATION=utf8mb4_general_ci + - MYSQL_ROOT_HOST=% + - MYSQL_SSL_MODE=REQUIRED + ports: + - "3306:3306" + privileged: true + volumes: + - ./mysql/conf.d:/etc/mysql/conf.d + - ./mysql/data:/var/lib/mysql + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] + interval: 10s + timeout: 5s + retries: 5 + networks: + - app_net + restart: always + redis: + container_name: redis + image: redis:latest + ports: + - "6379:6379" + privileged: true + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] + interval: 5s + timeout: 3s + retries: 5 + networks: + - app_net + restart: always + + rabbitmq: + container_name: rabbitmq + image: rabbitmq:4.1.2-management + ports: + - "5672:5672" + - "15672:15672" + privileged: true + healthcheck: + test: [ "CMD", "rabbitmqctl", "status" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + minio: + image: quay.io/minio/minio:latest + container_name: minio + restart: always + ports: + - "9000:9000" # S3 API 端口 + - "9001:9001" # Web 控制台端口 + environment: + MINIO_ROOT_USER: admin + MINIO_ROOT_PASSWORD: admin123456 + volumes: + - ./minio-data:/data + command: server /data --console-address ":9001" + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9000/minio/health/live" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + # RocketMQ NameServer + rocketmq-namesrv: + image: apache/rocketmq:latest + container_name: rocketmq-namesrv + command: sh mqnamesrv + ports: + - "9876:9876" + environment: + JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m" + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9876" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # RocketMQ Broker + rocketmq-broker: + image: apache/rocketmq:latest + container_name: rocketmq-broker + command: sh mqbroker -c /home/rocketmq/rocketmq-5.3.3/conf/broker.conf + ports: + - "10909:10909" + - "10911:10911" + - "10912:10912" + environment: + JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m" + NAMESRV_ADDR: "rocketmq-namesrv:9876" + volumes: + - ./rocketmq/conf/broker.conf:/home/rocketmq/rocketmq-5.3.3/conf/broker.conf + - ./rocketmq/logs:/home/rocketmq/logs + - ./rocketmq/store:/home/rocketmq/store + depends_on: + - rocketmq-namesrv + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:10911" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # Elasticsearch + elasticsearch: + image: elasticsearch:7.17.28 + container_name: elasticsearch + environment: + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms512m -Xmx512m + - xpack.security.enabled=false + ports: + - "9200:9200" + - "9300:9300" + volumes: + - ./es/data:/usr/share/elasticsearch/data + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:9200" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + + # Nginx + nginx: + image: nginx:latest + container_name: nginx + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/conf.d:/etc/nginx/conf.d + - ./nginx/html:/usr/share/nginx/html + - ./nginx/logs:/var/log/nginx + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + nacos: + container_name: nacos + image: nacos/nacos-server:v3.0.2 + ports: + - "8848:8848" + - "8080:8080" + - "9848:9848" + - "9849:9849" + environment: + - TZ=Asia/Shanghai + - MODE=standalone + - PREFER_HOST_MODE=hostname + - SPRING_DATASOURCE_PLATFORM=mysql + - MYSQL_SERVICE_HOST=mysql + - MYSQL_SERVICE_DB_NAME=nacos_config + - MYSQL_SERVICE_PORT=3306 + - MYSQL_SERVICE_USER=root + - MYSQL_SERVICE_PASSWORD=root + - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + - NACOS_AUTH_IDENTITY_KEY=2222 + - NACOS_AUTH_IDENTITY_VALUE=2xxx + - NACOS_AUTH_TOKEN=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg= + volumes: + - ./nacos/logs:/home/nacos/logs + depends_on: + mysql: + condition: service_healthy + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8848/nacos" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + privileged: true + restart: always + # Seata + seata-server: + image: seataio/seata-server:1.6.0 + container_name: seata-server + ports: + - "7091:7091" + - "8091:8091" + networks: + - app_net + restart: always + + # Sentinel + sentinel: + image: bladex/sentinel-dashboard:latest + container_name: sentinel + ports: + - "8858:8858" + environment: + - JAVA_OPTS=-Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8858" ] + interval: 30s + timeout: 10s + retries: 3 + networks: + - app_net + restart: always + leaf-server: + image: registry.cn-hangzhou.aliyuncs.com/itheima/meituan-leaf:1.0.1 + container_name: leaf-server + ports: + - "8090:8080" + environment: + - SPRING_PROFILES_ACTIVE=prod + volumes: + - ./leaf/application.properties:/leaf-server/config/application.properties + networks: + - app_net + + zookeeper: + image: bitnami/zookeeper:latest + container_name: zookeeper + ports: + - "2181:2181" + environment: + - ALLOW_ANONYMOUS_LOGIN=yes + networks: + - app_net + restart: always \ No newline at end of file diff --git a/qa-service/nacos_config.sql b/qa-service/nacos_config.sql new file mode 100644 index 0000000..433a90b --- /dev/null +++ b/qa-service/nacos_config.sql @@ -0,0 +1,179 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******************************************/ +/* 表名称 = config_info */ +/******************************************/ +CREATE TABLE `config_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) DEFAULT NULL COMMENT 'group_id', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description', + `c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage', + `effect` varchar(64) DEFAULT NULL COMMENT '配置生效的描述', + `type` varchar(64) DEFAULT NULL COMMENT '配置的类型', + `c_schema` text COMMENT '配置的模式', + `encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; + +/******************************************/ +/* 表名称 = config_info since 2.5.0 */ +/******************************************/ +CREATE TABLE `config_info_gray` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `src_user` text COMMENT 'src_user', + `src_ip` varchar(100) DEFAULT NULL COMMENT 'src_ip', + `gmt_create` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_create', + `gmt_modified` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'gmt_modified', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `gray_name` varchar(128) NOT NULL COMMENT 'gray_name', + `gray_rule` text NOT NULL COMMENT 'gray_rule', + `encrypted_data_key` varchar(256) NOT NULL DEFAULT '' COMMENT 'encrypted_data_key', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfogray_datagrouptenantgray` (`data_id`,`group_id`,`tenant_id`,`gray_name`), + KEY `idx_dataid_gmt_modified` (`data_id`,`gmt_modified`), + KEY `idx_gmt_modified` (`gmt_modified`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='config_info_gray'; + +/******************************************/ +/* 表名称 = config_tags_relation */ +/******************************************/ +CREATE TABLE `config_tags_relation` ( + `id` bigint(20) NOT NULL COMMENT 'id', + `tag_name` varchar(128) NOT NULL COMMENT 'tag_name', + `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `nid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增长标识', + PRIMARY KEY (`nid`), + UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation'; + +/******************************************/ +/* 表名称 = group_capacity */ +/******************************************/ +CREATE TABLE `group_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_group_id` (`group_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表'; + +/******************************************/ +/* 表名称 = his_config_info */ +/******************************************/ +CREATE TABLE `his_config_info` ( + `id` bigint(20) unsigned NOT NULL COMMENT 'id', + `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'nid, 自增标识', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `content` longtext NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + `src_user` text COMMENT 'source user', + `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', + `op_type` char(10) DEFAULT NULL COMMENT 'operation type', + `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', + `encrypted_data_key` varchar(1024) NOT NULL DEFAULT '' COMMENT '密钥', + `publish_type` varchar(50) DEFAULT 'formal' COMMENT 'publish type gray or formal', + `gray_name` varchar(50) DEFAULT NULL COMMENT 'gray name', + `ext_info` longtext DEFAULT NULL COMMENT 'ext info', + PRIMARY KEY (`nid`), + KEY `idx_gmt_create` (`gmt_create`), + KEY `idx_gmt_modified` (`gmt_modified`), + KEY `idx_did` (`data_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造'; + + +/******************************************/ +/* 表名称 = tenant_capacity */ +/******************************************/ +CREATE TABLE `tenant_capacity` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID', + `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', + `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', + `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', + `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数', + `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', + `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', + `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表'; + + +CREATE TABLE `tenant_info` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', + `kp` varchar(128) NOT NULL COMMENT 'kp', + `tenant_id` varchar(128) default '' COMMENT 'tenant_id', + `tenant_name` varchar(128) default '' COMMENT 'tenant_name', + `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', + `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', + `gmt_create` bigint(20) NOT NULL COMMENT '创建时间', + `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), + KEY `idx_tenant_id` (`tenant_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info'; + +CREATE TABLE `users` ( + `username` varchar(50) NOT NULL PRIMARY KEY COMMENT 'username', + `password` varchar(500) NOT NULL COMMENT 'password', + `enabled` boolean NOT NULL COMMENT 'enabled' +); + +CREATE TABLE `roles` ( + `username` varchar(50) NOT NULL COMMENT 'username', + `role` varchar(50) NOT NULL COMMENT 'role', + UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE +); + +CREATE TABLE `permissions` ( + `role` varchar(50) NOT NULL COMMENT 'role', + `resource` varchar(128) NOT NULL COMMENT 'resource', + `action` varchar(8) NOT NULL COMMENT 'action', + UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE +); + diff --git a/qa-service/pom.xml b/qa-service/pom.xml index 0b70349..28b1393 100644 --- a/qa-service/pom.xml +++ b/qa-service/pom.xml @@ -8,25 +8,37 @@ qa-service qa-service - 17 + 21 UTF-8 UTF-8 - 3.0.2 + 3.2.4 + 2023.0.1.0 + 2023.0.1 + + pom + + + qa-service-bootstrap + qa-service-adapter + qa-service-application + qa-service-domain + qa-service-common + + + - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + org.springframework.boot spring-boot-dependencies @@ -34,6 +46,19 @@ pom import + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.14 + @@ -44,8 +69,8 @@ maven-compiler-plugin 3.8.1 - 17 - 17 + 21 + 21 UTF-8 @@ -54,7 +79,7 @@ spring-boot-maven-plugin ${spring-boot.version} - com.example.qa.service.QaServiceApplication + com.example.user-service.user-serviceApplication true diff --git a/qa-service/qa-service-adapter/qa-adapter-in/.gitignore b/qa-service/qa-service-adapter/qa-adapter-in/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QAController.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QAController.java new file mode 100644 index 0000000..f966d20 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/controller/QAController.java @@ -0,0 +1,81 @@ +package com.example.qa.adapter.in.web.controller; + +import com.example.application.command.CreateQACommand; +import com.example.application.command.UpdateQACommand; +import com.example.application.port.in.*; +import com.example.qa.adapter.in.web.dto.CreateQARequestDTO; +import com.example.qa.adapter.in.web.dto.QAResponseDTO; +import com.example.qa.adapter.in.web.dto.UpdateQARequestDTO; +import com.example.qa.service.domain.QA; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Slf4j +@RequestMapping("/qas") +@RestController +@RequiredArgsConstructor + +public class QAController { + private final CreateQAUseCase createQAUseCase; + private final DeleteQAUseCase deleteQAUseCase; + private final GetQAByIdUseCase getQAByIdUseCase; + private final GetQAListUseCase getQAListUseCase; + private final UpdateQAUseCase updateQAUseCase; + /** + * @author wangqingqing + */ + @GetMapping("") + public List getQAs(){ + return getQAListUseCase.getQAs(); + } + + /** + * @author yangwenkai + * 创建QA的方法 + */ + @PostMapping() + public QA createQA(@RequestBody CreateQARequestDTO createQARequestDTO){ + CreateQACommand command = CreateQACommand.builder() + .question(createQARequestDTO.question()) + .answer(createQARequestDTO.answer()) + .build(); + return createQAUseCase.createQA(command); + } + /** + * @author qiuyujie + */ + @DeleteMapping("{id}") + public String deleteQA(@PathVariable("id") long id){ + deleteQAUseCase.deleteQA(id); + return "success"; + } + /** + * @author lizishan + */ + @PutMapping("") + public QA updateQA(@RequestBody UpdateQARequestDTO updateQARequestDTO){ + UpdateQACommand command= UpdateQACommand.builder() + .id(updateQARequestDTO.id()) + .question(updateQARequestDTO.question()) + .answer(updateQARequestDTO.answer()) + .build(); + QA qa = updateQAUseCase.updateQA(command); + return qa; + } + /** + * @author dengli + */ + @GetMapping("{id}") + public QAResponseDTO getQAById(@PathVariable("id")long id){ + QA qa=getQAByIdUseCase.getQAById(id); + QAResponseDTO qaresponseDTO=new QAResponseDTO( + qa.getId().id(), + qa.getQuestion().question(), + qa.getAnswer().answer() + ); + return qaresponseDTO; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQARequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQARequestDTO.java new file mode 100644 index 0000000..fff7426 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/CreateQARequestDTO.java @@ -0,0 +1,10 @@ +package com.example.qa.adapter.in.web.dto; + +/** + * @author yangwenkai + * 创建QA的传输数据 + */ +public record CreateQARequestDTO( + String question, + String answer) { +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QAResponseDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QAResponseDTO.java new file mode 100644 index 0000000..50e781d --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/QAResponseDTO.java @@ -0,0 +1,18 @@ +package com.example.qa.adapter.in.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +/** + * @author yangwenkai + * QA的封装响应参数 + */ +public class QAResponseDTO { + private Long id; + private String question; + private String answer; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQARequestDTO.java b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQARequestDTO.java new file mode 100644 index 0000000..b18c0f8 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-in/qa-adapter-in-web/src/main/java/com/example/qa/adapter/in/web/dto/UpdateQARequestDTO.java @@ -0,0 +1,12 @@ +package com.example.qa.adapter.in.web.dto; + +/** + * @author yangwenkai + * 修改QA的传输数据 + */ +public record UpdateQARequestDTO( + long id, + String question, + String answer +) { +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQABridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQABridge.java new file mode 100644 index 0000000..f3fa09d --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/CreateQABridge.java @@ -0,0 +1,29 @@ +package com.example.qa.adapter.out.persistence.bridge; + +import com.example.qa.adapter.out.persistence.convertor.QAConvertor; +import com.example.qa.adapter.out.persistence.entity.QAEntity; +import com.example.qa.adapter.out.persistence.mapper.QAMapper; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.CreateQAPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +/** + * @author yangwenkai + * 创建QA的桥接类 + */ +public class CreateQABridge implements CreateQAPort { + @Resource + private QAMapper qAMapper; + + @Override + public QA createQA(QA qa) { + QAEntity qaEntity = QAConvertor.toEntity(qa); + int result = qAMapper.insert(qaEntity); + //result 是受影响的行数 + return qa; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQABridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQABridge.java new file mode 100644 index 0000000..014a230 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/DeleteQABridge.java @@ -0,0 +1,23 @@ +package com.example.qa.adapter.out.persistence.bridge; + + +import com.example.qa.adapter.out.persistence.mapper.QAMapper; +import com.example.qa.service.domain.port.DeleteQAPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +/** + * @author qiuyujie + */ +public class DeleteQABridge implements DeleteQAPort { + @Resource + private QAMapper QAMapper; + @Override + public void deleteQA(Long id) { + int result = QAMapper.deleteById(id); + log.info("result:{}",result); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAByIdBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAByIdBridge.java new file mode 100644 index 0000000..37bad7c --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAByIdBridge.java @@ -0,0 +1,25 @@ +package com.example.qa.adapter.out.persistence.bridge; + +import com.example.qa.adapter.out.persistence.convertor.QAConvertor; +import com.example.qa.adapter.out.persistence.entity.QAEntity; +import com.example.qa.adapter.out.persistence.mapper.QAMapper; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.GetQAByIdPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +/** + * @author dengli + */ +public class GetQAByIdBridge implements GetQAByIdPort { + @Resource + private QAMapper QAMapper; + @Override + public QA getQAById(long id) { + QAEntity QAEntity = QAMapper.selectById(id); + return QAConvertor.toDomain(QAEntity); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAListBridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAListBridge.java new file mode 100644 index 0000000..ebbbd26 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/GetQAListBridge.java @@ -0,0 +1,36 @@ +package com.example.qa.adapter.out.persistence.bridge; + + +import com.example.qa.adapter.out.persistence.convertor.QAConvertor; +import com.example.qa.adapter.out.persistence.entity.QAEntity; +import com.example.qa.adapter.out.persistence.mapper.QAMapper; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.GetQAListPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +/** + * @author wangqingqing + */ +public class GetQAListBridge implements GetQAListPort { + + @Resource + private QAMapper QAMapper; + + @Override + public List getQAs() { + List entities = QAMapper.selectList(null); + + ArrayList list = new ArrayList<>(); + + entities.forEach(QAEntity -> { + QA QA = QAConvertor.toDomain(QAEntity); + list.add(QA); + }); + return list; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQABridge.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQABridge.java new file mode 100644 index 0000000..91aecb9 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/bridge/UpdateQABridge.java @@ -0,0 +1,26 @@ +package com.example.qa.adapter.out.persistence.bridge; + +import com.example.qa.adapter.out.persistence.convertor.QAConvertor; +import com.example.qa.adapter.out.persistence.mapper.QAMapper; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.UpdateQAPort; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +/** + * @author lizishan + */ +public class UpdateQABridge implements UpdateQAPort { + @Resource + private QAMapper QAMapper; + + @Override + public QA updateQA(QA QA) { + int result = QAMapper.updateById(QAConvertor.toEntity(QA)); + log.info("result:{}",result); + return QA; + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QAConvertor.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QAConvertor.java new file mode 100644 index 0000000..57df73a --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/convertor/QAConvertor.java @@ -0,0 +1,29 @@ +package com.example.qa.adapter.out.persistence.convertor; + +import com.example.qa.adapter.out.persistence.entity.QAEntity; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.QAId; +import com.example.qa.service.domain.valueobject.Question; + +/** + * @author yangwenkai + * QA的数据转换 + */ +public class QAConvertor { + public static QA toDomain(QAEntity qaEntity) { + return new QA( + new QAId(qaEntity.getId()), + new Question(qaEntity.getQuestion()), + new Answer(qaEntity.getAnswer()) + ); + } + + public static QAEntity toEntity(QA qa) { + return new QAEntity( + qa.getId().getValue(), + qa.getQuestion().getValue(), + qa.getAnswer().getValue() + ); + } +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QAEntity.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QAEntity.java new file mode 100644 index 0000000..82acdb6 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/entity/QAEntity.java @@ -0,0 +1,23 @@ +package com.example.qa.adapter.out.persistence.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName("qa") +/** + * @author yangwenkai + * QA的实体类 + */ +public class QAEntity { + @TableId(type = IdType.ASSIGN_ID) + private long id; + private String question; + private String answer; +} diff --git a/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QAMapper.java b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QAMapper.java new file mode 100644 index 0000000..fa3c1c1 --- /dev/null +++ b/qa-service/qa-service-adapter/qa-adapter-out/qa-adapter-out-persistence/src/main/java/com/example/qa/adapter/out/persistence/mapper/QAMapper.java @@ -0,0 +1,10 @@ +package com.example.qa.adapter.out.persistence.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.example.qa.adapter.out.persistence.entity.QAEntity; + +/** + * @author lizishan + */ +public interface QAMapper extends BaseMapper { +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/command/CreateQACommand.java b/qa-service/qa-service-application/src/main/java/com/example/application/command/CreateQACommand.java new file mode 100644 index 0000000..8688eec --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/command/CreateQACommand.java @@ -0,0 +1,16 @@ +package com.example.application.command; + + +import lombok.Builder; + +@Builder +/** + * @author yangwenkai + * 创建QA的封装参数 + */ +public record CreateQACommand( + Long id, + String question, + String answer +) { +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/command/UpdateQACommand.java b/qa-service/qa-service-application/src/main/java/com/example/application/command/UpdateQACommand.java new file mode 100644 index 0000000..b86e3d9 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/command/UpdateQACommand.java @@ -0,0 +1,15 @@ +package com.example.application.command; + +import lombok.Builder; + +@Builder +/** + * @author yangwenkai + * 修改QA的封装参数 + */ +public record UpdateQACommand ( + long id, + String question, + String answer +) { +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/port/in/CreateQAUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/CreateQAUseCase.java new file mode 100644 index 0000000..6960f96 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/CreateQAUseCase.java @@ -0,0 +1,12 @@ +package com.example.application.port.in; + +import com.example.application.command.CreateQACommand; +import com.example.qa.service.domain.QA; + +/** + * @author yangwenkai + * 创建QA的接口 + */ +public interface CreateQAUseCase { + QA createQA(CreateQACommand command); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/port/in/DeleteQAUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/DeleteQAUseCase.java new file mode 100644 index 0000000..3da4cda --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/DeleteQAUseCase.java @@ -0,0 +1,8 @@ +package com.example.application.port.in; + +/** + * @author qiuyujie + */ +public interface DeleteQAUseCase { + void deleteQA(long id); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAByIdUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAByIdUseCase.java new file mode 100644 index 0000000..62b69d5 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAByIdUseCase.java @@ -0,0 +1,10 @@ +package com.example.application.port.in; + +import com.example.qa.service.domain.QA; + +/** + * @author dengli + */ +public interface GetQAByIdUseCase { + QA getQAById(long id); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAListUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAListUseCase.java new file mode 100644 index 0000000..987e33c --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/GetQAListUseCase.java @@ -0,0 +1,11 @@ +package com.example.application.port.in; + +import com.example.qa.service.domain.QA; + +import java.util.List; +/** + * @author wangqingqing + */ +public interface GetQAListUseCase { + List getQAs(); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/port/in/UpdateQAUseCase.java b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/UpdateQAUseCase.java new file mode 100644 index 0000000..39a9c6c --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/port/in/UpdateQAUseCase.java @@ -0,0 +1,10 @@ +package com.example.application.port.in; + +import com.example.application.command.UpdateQACommand; +import com.example.qa.service.domain.QA; +/** + * @author lizishan + */ +public interface UpdateQAUseCase { + QA updateQA(UpdateQACommand command); +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/service/CreateQAService.java b/qa-service/qa-service-application/src/main/java/com/example/application/service/CreateQAService.java new file mode 100644 index 0000000..2a6a447 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/service/CreateQAService.java @@ -0,0 +1,31 @@ +package com.example.application.service; + +import com.example.application.command.CreateQACommand; +import com.example.application.port.in.CreateQAUseCase; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.CreateQAPort; +import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.Question; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +/** + * @author yangwenkai + * 创建QA的实现类 + */ +public class CreateQAService implements CreateQAUseCase { + @Resource + private CreateQAPort createQAPort; + + @Override + public QA createQA(CreateQACommand createQACommand) { + QA qa = new QA( + new Question(createQACommand.question()), + new Answer(createQACommand.answer()) + ); + return createQAPort.createQA(qa); + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/service/DeleteQAService.java b/qa-service/qa-service-application/src/main/java/com/example/application/service/DeleteQAService.java new file mode 100644 index 0000000..1d8fab5 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/service/DeleteQAService.java @@ -0,0 +1,20 @@ +package com.example.application.service; + +import com.example.application.port.in.DeleteQAUseCase; +import com.example.qa.service.domain.port.DeleteQAPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +/** + * @author qiuyujie + */ +public class DeleteQAService implements DeleteQAUseCase { + @Resource + private DeleteQAPort deleteQAPort; + + @Override + public void deleteQA(long id) { + deleteQAPort.deleteQA(id); + } +} \ No newline at end of file diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAByIdService.java b/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAByIdService.java new file mode 100644 index 0000000..b224f7b --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAByIdService.java @@ -0,0 +1,22 @@ +package com.example.application.service; + +import com.example.application.port.in.GetQAByIdUseCase; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.GetQAByIdPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +/** + * @author dengli + */ +public class GetQAByIdService implements GetQAByIdUseCase { + + @Resource + private GetQAByIdPort getQAByIdPort; + @Override + public QA getQAById(long id) { + return getQAByIdPort.getQAById(id); + } +} + diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAListService.java b/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAListService.java new file mode 100644 index 0000000..fb72ee6 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/service/GetQAListService.java @@ -0,0 +1,23 @@ +package com.example.application.service; + +import com.example.application.port.in.GetQAListUseCase; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.GetQAListPort; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.List; +/** + * @author wangqingqing + */ +@Service +public class GetQAListService implements GetQAListUseCase { + + @Resource + GetQAListPort getQAListPort; + @Override + public List getQAs() { + List QAs = QA.getQAs(getQAListPort); + return QAs; + } +} diff --git a/qa-service/qa-service-application/src/main/java/com/example/application/service/UpdateQAService.java b/qa-service/qa-service-application/src/main/java/com/example/application/service/UpdateQAService.java new file mode 100644 index 0000000..d908f68 --- /dev/null +++ b/qa-service/qa-service-application/src/main/java/com/example/application/service/UpdateQAService.java @@ -0,0 +1,26 @@ +package com.example.application.service; + +import com.example.application.command.UpdateQACommand; +import com.example.application.port.in.UpdateQAUseCase; +import com.example.qa.service.domain.QA; +import com.example.qa.service.domain.port.UpdateQAPort; +import com.example.qa.service.domain.valueobject.*; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +/** + * @author lizishan + */ +@Service +public class UpdateQAService implements UpdateQAUseCase { + @Resource + private UpdateQAPort updateQAPort; + + @Override + public QA updateQA(UpdateQACommand command) { + QA QA = new QA( + new QAId(command.id()), + new Question(command.question()), + new Answer(command.answer())); + return updateQAPort.updateQA(QA); + } +} diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties new file mode 100644 index 0000000..e073491 --- /dev/null +++ b/qa-service/qa-service-bootstrap/src/main/resources/application.properties @@ -0,0 +1,27 @@ +server.port=28080 + +spring.application.name=user-service + + +# Nacos认证信息 +spring.cloud.nacos.discovery.username=nacos +spring.cloud.nacos.discovery.password=nacos +# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 +spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 +# 注册到 nacos 的指定 namespace,默认为 public +spring.cloud.nacos.discovery.namespace=public + +# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html +# Nacos认证信息 +spring.cloud.nacos.config.username=nacos +spring.cloud.nacos.config.password=nacos +spring.cloud.nacos.config.contextPath=/nacos +# 设置配置中心服务端地址 +spring.cloud.nacos.config.server-addr=192.168.168.128::8848 +# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 +# spring.cloud.nacos.config.namespace= +spring.config.import=nacos:${spring.application.name}.properties?refresh=true + + + + diff --git a/qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java b/qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java new file mode 100644 index 0000000..ac96e23 --- /dev/null +++ b/qa-service/qa-service-common/src/main/java/com/example/qa/service/common/IdWorker.java @@ -0,0 +1,199 @@ +package com.example.qa.service.common; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; + +/** + * @author wuyunbin + *

名称:IdWorker.java

+ *

描述:分布式自增长ID

+ *
+ *     Twitter的 Snowflake JAVA实现方案
+ * 
+ * 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用: + * 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000 + * 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间, + * 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识), + * 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。 + * 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分), + * 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。 + *

+ * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) + * @author Polim + */ +public class IdWorker { + /** + * 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + */ + private final static long TWEPOCH = 1288834974657L; + + /** + * 机器标识位数 + */ + private final static long WORKER_ID_BITS = 5L; + + /** + * 数据中心标识位数 + */ + private final static long DATA_CENTER_ID_BITS = 5L; + + /** + * 机器ID最大值 + */ + private final static long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS); + + /** + * 数据中心ID最大值 + */ + private final static long MAX_DATACENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS); + + /** + * 毫秒内自增位 + */ + private final static long SEQUENCE_BITS = 12L; + + /** + * 机器ID偏左移12位 + */ + private final static long WORKER_ID_SHIFT = SEQUENCE_BITS; + + /** + * 数据中心ID左移17位 + */ + private final static long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; + + /** + * 时间毫秒左移22位 + */ + private final static long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS; + + private final static long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); + + /** + * 上次生产id时间戳 + */ + private static long lastTimestamp = -1L; + + /** + * 0,并发控制 + */ + private long sequence = 0L; + + private final long workerId; + + /** + * 数据标识id部分 + */ + private final long datacenterId; + + public IdWorker() { + this.datacenterId = getDatacenterId(); + this.workerId = getMaxWorkerId(datacenterId); + } + + /** + * @param workerId 工作机器ID + * @param datacenterId 序列号 + */ + public IdWorker(long workerId, long datacenterId) { + if (workerId > MAX_WORKER_ID || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID)); + } + if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", MAX_DATACENTER_ID)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + * 获取下一个ID + * + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + // 当前毫秒内,则+1 + sequence = (sequence + 1) & SEQUENCE_MASK; + if (sequence == 0) { + // 当前毫秒内计数满了,则等待下一秒 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0L; + } + lastTimestamp = timestamp; + // ID偏移组合生成最终的ID,并返回ID + + return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) + | (datacenterId << DATACENTER_ID_SHIFT) + | (workerId << WORKER_ID_SHIFT) | sequence; + } + + private long tilNextMillis(final long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + /** + *

+ * 获取 MAX_WORKER_ID + *

+ */ + protected static long getMaxWorkerId(long datacenterId) { + StringBuilder mpid = new StringBuilder(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (!name.isEmpty()) { + /* + * GET jvmPid + */ + mpid.append(name.split("@")[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (IdWorker.MAX_WORKER_ID + 1); + } + + /** + *

+ * 数据标识id部分 + *

+ */ + protected static long getDatacenterId() { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + id = ((0x000000FF & (long) mac[mac.length - 1]) + | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (IdWorker.MAX_DATACENTER_ID + 1); + } + } catch (Exception e) { + System.out.println(" getDatacenterId: " + e.getMessage()); + } + return id; + } + + + + +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/QA.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/QA.java new file mode 100644 index 0000000..c40b3bb --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/QA.java @@ -0,0 +1,48 @@ +package com.example.qa.service.domain; + +import com.example.qa.service.common.IdWorker; +import com.example.qa.service.domain.port.GetQAListPort; +import com.example.qa.service.domain.valueobject.Answer; +import com.example.qa.service.domain.valueobject.QAId; +import com.example.qa.service.domain.valueobject.Question; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +@Setter +@Getter +@ToString +/** + * @author yangwenkai + * QA类 + */ +public class QA { + private QAId id; + private Question question; + private Answer answer; + + public QA() { + } + + public QA(QAId id, Question question, Answer answer) { + this.id = id; + this.question = question; + this.answer = answer; + } + + public QA(Question question, Answer answer) { + this.id= genId(); + this.question = question; + this.answer = answer; + } + + public static List getQAs(GetQAListPort getQAListPort){ + return getQAListPort.getQAs(); + } + + public QAId genId(){ + return new QAId(new IdWorker().nextId()); + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQAPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQAPort.java new file mode 100644 index 0000000..aeb293a --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/CreateQAPort.java @@ -0,0 +1,11 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.QA; + +/** + * @author yangwenkai + * 创建QA的端口 + */ +public interface CreateQAPort { + QA createQA(QA qa); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQAPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQAPort.java new file mode 100644 index 0000000..2ea8e47 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/DeleteQAPort.java @@ -0,0 +1,8 @@ +package com.example.qa.service.domain.port; + +/** + * @author qiuyujie + */ +public interface DeleteQAPort { + void deleteQA(Long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAByIdPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAByIdPort.java new file mode 100644 index 0000000..fdc3b92 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAByIdPort.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.QA; + +/** + * @author dengli + */ +public interface GetQAByIdPort { + QA getQAById(long id); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAListPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAListPort.java new file mode 100644 index 0000000..3fc891d --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/GetQAListPort.java @@ -0,0 +1,11 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.QA; + +import java.util.List; +/** + * @author wangqingqing + */ +public interface GetQAListPort { + List getQAs(); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQAPort.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQAPort.java new file mode 100644 index 0000000..5713b79 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/port/UpdateQAPort.java @@ -0,0 +1,9 @@ +package com.example.qa.service.domain.port; + +import com.example.qa.service.domain.QA; +/** + * @author lizishan + */ +public interface UpdateQAPort { + QA updateQA(QA qa); +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java new file mode 100644 index 0000000..8a34b3c --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Answer.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.valueobject; + +/** + * @author qiuyujie + */ +public record Answer(String answer) { + public String getValue() { + return answer; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QAId.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QAId.java new file mode 100644 index 0000000..a423600 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/QAId.java @@ -0,0 +1,10 @@ +package com.example.qa.service.domain.valueobject; + +/** + * @author dengli + */ +public record QAId(long id) { + public long getValue() { + return id; + } +} diff --git a/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java new file mode 100644 index 0000000..773a8f9 --- /dev/null +++ b/qa-service/qa-service-domain/src/main/java/com/example/qa/service/domain/valueobject/Question.java @@ -0,0 +1,9 @@ +package com.example.qa.service.domain.valueobject; +/** + * @author wangqingqing + */ +public record Question(String question) { + public String getValue() { + return question; + } +} -- Gitee From 1d805cee0913e3c0b73de462ba03a9ebecc02f84 Mon Sep 17 00:00:00 2001 From: Xiaya_kevin <1415130181@qq.com> Date: Wed, 10 Sep 2025 17:36:41 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix(qa-service-bootstrap):=20AI=E8=AF=B4?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E5=8F=8C=E5=86=92=E5=8F=B7=E8=A6=81=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E4=B8=80=E4=B8=AA=E5=86=92=E5=8F=B7=EF=BC=9B=E6=8A=8A?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=BC=8F=E6=8E=89=E7=9A=84user=E6=94=B9?= =?UTF-8?q?=E5=9B=9E=E6=9D=A5=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 8 ------ .idea/encodings.xml | 4 --- .idea/gradle.xml | 6 ----- .idea/misc.xml | 6 ----- qa-service/pom.xml | 2 +- .../src/main/resources/application.properties | 27 ------------------- 6 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/misc.xml delete mode 100644 qa-service/qa-service-bootstrap/src/main/resources/application.properties diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index a1757ae..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index da0415a..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index c4be5fb..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 7280f00..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/qa-service/pom.xml b/qa-service/pom.xml index 28b1393..7ba8bd5 100644 --- a/qa-service/pom.xml +++ b/qa-service/pom.xml @@ -79,7 +79,7 @@ spring-boot-maven-plugin ${spring-boot.version} - com.example.user-service.user-serviceApplication + com.example.qa-service.qa-serviceApplication true diff --git a/qa-service/qa-service-bootstrap/src/main/resources/application.properties b/qa-service/qa-service-bootstrap/src/main/resources/application.properties deleted file mode 100644 index e073491..0000000 --- a/qa-service/qa-service-bootstrap/src/main/resources/application.properties +++ /dev/null @@ -1,27 +0,0 @@ -server.port=28080 - -spring.application.name=user-service - - -# Nacos认证信息 -spring.cloud.nacos.discovery.username=nacos -spring.cloud.nacos.discovery.password=nacos -# Nacos 服务发现与注册配置,其中子属性 server-addr 指定 Nacos 服务器主机和端口 -spring.cloud.nacos.discovery.server-addr=192.168.168.128:8848 -# 注册到 nacos 的指定 namespace,默认为 public -spring.cloud.nacos.discovery.namespace=public - -# Nacos帮助文档: https://nacos.io/zh-cn/docs/concepts.html -# Nacos认证信息 -spring.cloud.nacos.config.username=nacos -spring.cloud.nacos.config.password=nacos -spring.cloud.nacos.config.contextPath=/nacos -# 设置配置中心服务端地址 -spring.cloud.nacos.config.server-addr=192.168.168.128::8848 -# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可 -# spring.cloud.nacos.config.namespace= -spring.config.import=nacos:${spring.application.name}.properties?refresh=true - - - - -- Gitee From 5b0f51a02dccd55b6ec78a2d95a353b184cb4527 Mon Sep 17 00:00:00 2001 From: Xiaya_kevin <1415130181@qq.com> Date: Thu, 11 Sep 2025 11:22:55 +0800 Subject: [PATCH 3/4] =?UTF-8?q?feat(user):=20AI=E7=9A=843=E7=A7=8D?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E6=B3=A8=E5=85=A5=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/user/service/domain/User.java | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index e5e3e37..9e8aebc 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -21,10 +21,25 @@ public class User { private Email email; //todo 需要修改会Password类型 private String password; + + // 字段注入方式 - 通过@Resource或@Autowired注解注入 + private GetUserByNamePort getUserByNamePort; + private GetUserListPort getUserListPort; public User() { } + // 构造函数注入方式 + public User(UserId id, UserName name, UserAge age, Email email, + GetUserByNamePort getUserByNamePort, GetUserListPort getUserListPort) { + this.id = id; + this.name = name; + this.age = age; + this.email = email; + this.getUserByNamePort = getUserByNamePort; + this.getUserListPort = getUserListPort; + } + public User(UserId id, UserName name, UserAge age, Email email) { this.id = id; this.name = name; @@ -39,14 +54,42 @@ public class User { this.email = email; } + // Setter方法注入方式 + public void setGetUserByNamePort(GetUserByNamePort getUserByNamePort) { + this.getUserByNamePort = getUserByNamePort; + } + + public void setGetUserListPort(GetUserListPort getUserListPort) { + this.getUserListPort = getUserListPort; + } + + // 使用字段注入的业务方法 + public User getUserByNameWithFieldInjection(String name) { + if (getUserByNamePort == null) { + throw new IllegalStateException("GetUserByNamePort依赖未注入"); + } + return getUserByNamePort.getUserByName(name); + } + + // 使用构造函数注入的业务方法 + public static User getUserByNameWithConstructorInjection(String name, GetUserByNamePort getUserByNamePort) { + return getUserByNamePort.getUserByName(name); + } + + // 使用setter注入的业务方法 + public User getUserByNameWithSetterInjection(String name) { + if (getUserByNamePort == null) { + throw new IllegalStateException("GetUserByNamePort依赖未注入,请先调用setGetUserByNamePort方法"); + } + return getUserByNamePort.getUserByName(name); + } public static List getUsers(GetUserListPort getUserListPort){ return getUserListPort.getUsers(); } - public static User getUserByName(String name, GetUserByNamePort getUserByNamePort){ - User user = getUserByNamePort.getUserByName(name,getUserByNamePort); + User user = getUserByNamePort.getUserByName(name); return user; } -- Gitee From 846bfdd0b5e45c297aa130a4e24a0370573d1b8f Mon Sep 17 00:00:00 2001 From: Xiaya_kevin <1415130181@qq.com> Date: Thu, 11 Sep 2025 11:51:56 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat(user):=20AI=E7=9A=84=E9=9D=99=E6=80=81?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/user/service/domain/User.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java index 9e8aebc..0de0058 100644 --- a/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java +++ b/user-service/user-service-domain/src/main/java/com/example/user/service/domain/User.java @@ -1,9 +1,11 @@ package com.example.user.service.domain; import com.example.user.service.common.IdWorker; +import com.example.user.service.domain.port.GetUserByIdPort; import com.example.user.service.domain.port.GetUserByNamePort; import com.example.user.service.domain.port.GetUserListPort; import com.example.user.service.domain.valueobject.*; +import jakarta.annotation.Resource; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -88,8 +90,24 @@ public class User { return getUserListPort.getUsers(); } - public static User getUserByName(String name, GetUserByNamePort getUserByNamePort){ - User user = getUserByNamePort.getUserByName(name); + @Resource + private GetUserByIdPort getUserByIdPort; + + // 静态字段注入 - 用于静态方法 + private static GetUserByNamePort staticGetUserByNamePort; + + // 静态注入方法 - 由Spring容器调用 + @Resource + public void setStaticGetUserByNamePort(GetUserByNamePort getUserByNamePort) { + User.staticGetUserByNamePort = getUserByNamePort; + } + + // 静态方法 - 只使用name参数,通过静态字段获取依赖 + public static User getUserByName(String name){ + if (staticGetUserByNamePort == null) { + throw new IllegalStateException("GetUserByNamePort依赖未注入,请确保Spring容器已初始化"); + } + User user = staticGetUserByNamePort.getUserByName(name); return user; } -- Gitee