无关风月
2024-09-10 5d02cf6ba780f088b24f62cf8db94bf63707db57
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/XinQuanHealing

# Conflicts:
# xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/Course.java
# xinquan-auth/src/main/resources/bootstrap.yml
# xinquan-gateway/src/main/resources/bootstrap.yml
3 文件已重命名
30个文件已修改
25个文件已添加
1289 ■■■■■ 已修改文件
.gitignore 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/docker-compose.yml 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/Course.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/Meditation.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/factory/RemoteMeditationFallbackFactory.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/feign/RemoteMeditationService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/Order.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/factory/RemoteOrderFallbackFactory.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/feign/RemoteOrderService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/resources/bootstrap.yml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ChargeTypeEnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/OrderFromEnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PaymentStatusEnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PaymentTypeEnum.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/vo/ClientCourseVO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/bootstrap.yml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/resources/bootstrap.yml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientHomeController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/inner/InnerMeditationController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationUserFavorite.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationDetailsVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationEverydayVO.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationEverydayServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMusicMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/NotifyController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/inner/InnerOrderController.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/OrderPaymentRecord.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/vo/ClientPlaceOrderVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/utils/JuHeFuUtil.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/utils/OrderUtil.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/resources/mapper/order/OrderMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/resources/mapper/order/OrderPaymentRecordMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientNoticeRecordController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerNoticeRecordController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/NoticeRecord.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/NoticeRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/NoticeRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/NoticeRecordServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/NoticeRecordMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svgo.yml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/src/main/resources/bootstrap.yml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -40,7 +40,7 @@
*.log
*.xml.versionsBackup
*.swp
*.yml
!*/build/*.java
!*/build/*.html
docker/docker-compose.yml
New file
@@ -0,0 +1,140 @@
version : '3.8'
services:
  xinquan-nacos:
    container_name: xinquan-nacos
    image: nacos/nacos-server
    build:
      context: ./nacos
    environment:
      - MODE=standalone
    volumes:
      - ./nacos/logs/:/home/nacos/logs
      - ./nacos/conf/application.properties:/home/nacos/conf/application.properties
    ports:
      - "8848:8848"
      - "9848:9848"
      - "9849:9849"
    depends_on:
      - xinquan-mysql
  xinquan-mysql:
    container_name: xinquan-mysql
    image: mysql:5.7
    build:
      context: ./mysql
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/logs
      - ./mysql/data:/var/lib/mysql
    command: [
          'mysqld',
          '--innodb-buffer-pool-size=80M',
          '--character-set-server=utf8mb4',
          '--collation-server=utf8mb4_unicode_ci',
          '--default-time-zone=+8:00',
          '--lower-case-table-names=1'
        ]
    environment:
      MYSQL_DATABASE: 'ry-cloud'
      MYSQL_ROOT_PASSWORD: password
  xinquan-redis:
    container_name: xinquan-redis
    image: redis
    build:
      context: ./redis
    ports:
      - "6379:6379"
    volumes:
      - ./redis/conf/redis.conf:/home/xinquan/redis/redis.conf
      - ./redis/data:/data
    command: redis-server /home/xinquan/redis/redis.conf
  xinquan-nginx:
    container_name: xinquan-nginx
    image: nginx
    build:
      context: ./nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/html/dist:/home/xinquan/projects/xinquan-ui
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/logs:/var/log/nginx
      - ./nginx/conf.d:/etc/nginx/conf.d
    depends_on:
      - xinquan-gateway
    links:
      - xinquan-gateway
  xinquan-gateway:
    container_name: xinquan-gateway
    build:
      context: ./xinquan/gateway
      dockerfile: dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - xinquan-redis
    links:
      - xinquan-redis
  xinquan-auth:
    container_name: xinquan-auth
    build:
      context: ./xinquan/auth
      dockerfile: dockerfile
    ports:
      - "9200:9200"
    depends_on:
      - xinquan-redis
    links:
      - xinquan-redis
  xinquan-modules-system:
    container_name: xinquan-modules-system
    build:
      context: ./xinquan/modules/system
      dockerfile: dockerfile
    ports:
      - "9201:9201"
    depends_on:
      - xinquan-redis
      - xinquan-mysql
    links:
      - xinquan-redis
      - xinquan-mysql
  xinquan-modules-gen:
    container_name: xinquan-modules-gen
    build:
      context: ./xinquan/modules/gen
      dockerfile: dockerfile
    ports:
      - "9202:9202"
    depends_on:
      - xinquan-mysql
    links:
      - xinquan-mysql
  xinquan-modules-job:
    container_name: xinquan-modules-job
    build:
      context: ./xinquan/modules/job
      dockerfile: dockerfile
    ports:
      - "9203:9203"
    depends_on:
      - xinquan-mysql
    links:
      - xinquan-mysql
  xinquan-modules-file:
    container_name: xinquan-modules-file
    build:
      context: ./xinquan/modules/file
      dockerfile: dockerfile
    ports:
      - "9300:9300"
    volumes:
    - ./xinquan/uploadPath:/home/xinquan/uploadPath
  xinquan-visual-monitor:
    container_name: xinquan-visual-monitor
    build:
      context: ./xinquan/visual/monitor
      dockerfile: dockerfile
    ports:
      - "9100:9100"
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/domain/Course.java
File was renamed from xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/Course.java
@@ -1,6 +1,8 @@
package com.xinquan.course.domain;
package com.xinquan.course.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -8,6 +10,7 @@
import com.xinquan.user.api.domain.AppUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -61,6 +64,14 @@
    @TableField("charge_type")
    private Integer chargeType;
    @ApiModelProperty(value = "通用价格")
    @TableField("general_price")
    private BigDecimal generalPrice;
    @ApiModelProperty(value = "IOS内购价格")
    @TableField("ios_price")
    private BigDecimal iosPrice;
    @ApiModelProperty(value = "排序权重")
    @TableField("sort_num")
    private Integer sortNum;
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java
@@ -1,14 +1,20 @@
package com.xinquan.course.api.feign;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.factory.RemoteCourseFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestHeader;
/**
 * @author mitao
 * @date 2024/8/21
 */
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.COURSE_SERVICE, fallbackFactory = RemoteCourseFallbackFactory.class)
@FeignClient(contextId = "remoteCourseService", value = ServiceNameConstants.COURSE_SERVICE, fallbackFactory = RemoteCourseFallbackFactory.class)
public interface RemoteCourseService {
    R<Course> getCourseById(Long targetId,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/domain/Meditation.java
File was renamed from xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/Meditation.java
@@ -1,4 +1,4 @@
package com.xinquan.meditation.domain;
package com.xinquan.meditation.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/factory/RemoteMeditationFallbackFactory.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.meditation.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import org.springframework.cloud.openfeign.FallbackFactory;
/**
 * @author mitao
 * @date 2024/9/9
 */
public class RemoteMeditationFallbackFactory implements FallbackFactory<RemoteMeditationService> {
    @Override
    public RemoteMeditationService create(Throwable cause) {
        return new RemoteMeditationService() {
            @Override
            public R<Meditation> getMeditationById(Long targetId, String source) {
                return R.fail("获取冥想音频失败");
            }
        };
    }
}
xinquan-api/xinquan-api-meditation/src/main/java/com/xinquan/meditation/api/feign/RemoteMeditationService.java
New file
@@ -0,0 +1,29 @@
package com.xinquan.meditation.api.feign;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.factory.RemoteMeditationFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author mitao
 * @date 2024/9/9
 */
@FeignClient(contextId = "remoteMeditationService", value = ServiceNameConstants.MEDITATION_SERVICE, fallbackFactory = RemoteMeditationFallbackFactory.class)
public interface RemoteMeditationService {
    /**
     * 根据id获取冥想音频
     *
     * @param targetId 冥想音频id
     * @return 冥想音频
     */
    @GetMapping("/inner/meditation/meditation/getMeditationById")
    R<Meditation> getMeditationById(@RequestParam("targetId") Long targetId,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/domain/Order.java
File was renamed from xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/Order.java
@@ -1,4 +1,4 @@
package com.xinquan.order.domain;
package com.xinquan.order.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/factory/RemoteOrderFallbackFactory.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.order.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.feign.RemoteOrderService;
import java.util.List;
import org.springframework.cloud.openfeign.FallbackFactory;
/**
 * @author mitao
 * @date 2024/9/9
 */
public class RemoteOrderFallbackFactory implements FallbackFactory<RemoteOrderService> {
    @Override
    public RemoteOrderService create(Throwable cause) {
        return new RemoteOrderService() {
            @Override
            public R<List<Order>> getOrderListByType(Long userId, Integer orderFrom,
                    String source) {
                return R.fail("获取订单列表失败");
            }
        };
    }
}
xinquan-api/xinquan-api-order/src/main/java/com/xinquan/order/api/feign/RemoteOrderService.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.order.api.feign;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.factory.RemoteOrderFallbackFactory;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author mitao
 * @date 2024/9/9
 */
@FeignClient(contextId = "remoteOrderService", value = ServiceNameConstants.ORDER_SERVICE, fallbackFactory = RemoteOrderFallbackFactory.class)
public interface RemoteOrderService {
    @PostMapping("/inner/order/order/getOrderListByType")
    R<List<Order>> getOrderListByType(@RequestParam("userId") Long userId,
            @RequestParam("orderFrom") Integer orderFrom,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-auth/src/main/resources/bootstrap.yml
@@ -79,4 +79,7 @@
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
meditation:
  secret: V8EZaYQ2gGzFaH7GPLZbw7KGYMRZ8MpF
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java
@@ -137,4 +137,8 @@
     * 默认密码
     */
    public static final String DEFAULT_PASSWORD = "123456";
    /**
     * 支付回调地址
     */
    public static final String PAYMENT_NOTIFY_URL = "/client/order/notify";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ChargeTypeEnum.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ChargeTypeEnum {
    FREE(1, "免费"),
    FREE_FOR_VIP(2, "会员免费"),
    SEPARATE_CHARGE(3, "单独收费");
    private final Integer code;
    private final String desc;
    public static ChargeTypeEnum getEnumByCode(Integer code) {
        for (ChargeTypeEnum e : ChargeTypeEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/OrderFromEnum.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum OrderFromEnum {
    MEDITATION(1, "冥想订单"),
    COURSE(2, "课程订单"),
    VIP(3, "会员订单");
    private final Integer code;
    private final String desc;
    public static OrderFromEnum getEnumByCode(Integer code) {
        for (OrderFromEnum e : OrderFromEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PaymentStatusEnum.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum PaymentStatusEnum {
    TO_BE_PAID(1, "待支付"),
    COMPLETED(2, "已完成"),
    CANCELED(3, "已取消");
    private final Integer code;
    private final String desc;
    public static PaymentStatusEnum getEnumByCode(Integer code) {
        for (PaymentStatusEnum e : PaymentStatusEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PaymentTypeEnum.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum PaymentTypeEnum {
    WECHAT_PAY(1, "微信支付"),
    ALI_PAY(2, "支付宝支付"),
    IOS_PAY(3, "IOS内购支付"),
    BALANCE_PAY(4, "余额支付");
    private final Integer code;
    private final String desc;
    public static PaymentTypeEnum getEnumByCode(Integer code) {
        for (PaymentTypeEnum e : PaymentTypeEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-gateway/src/main/resources/bootstrap.yml
@@ -2,7 +2,7 @@
spring:
  application:
    # 应用名称
    name: xinquan-auth
    name: xinquan-gateway
  main:
    allow-bean-definition-overriding: true
  profiles:
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/vo/ClientCourseVO.java
@@ -2,6 +2,7 @@
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import lombok.Data;
/**
@@ -35,6 +36,12 @@
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    private Integer chargeType;
    @ApiModelProperty(value = "通用价格")
    private BigDecimal generalPrice;
    @ApiModelProperty(value = "IOS内购价格")
    private BigDecimal iosPrice;
    @ApiModelProperty(value = "排序权重")
    private Integer sortNum;
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseMapper.java
@@ -1,7 +1,7 @@
package com.xinquan.course.mapper;
import com.xinquan.course.domain.Course;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.course.api.domain.Course;
/**
 * <p>
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseService.java
@@ -2,7 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.domain.Course;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.vo.ClientCourseVO;
/**
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseServiceImpl.java
@@ -5,7 +5,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.course.domain.Course;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.domain.vo.ClientCourseVO;
import com.xinquan.course.mapper.CourseMapper;
import com.xinquan.course.service.CourseService;
xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseMapper.xml
@@ -3,7 +3,7 @@
<mapper namespace="com.xinquan.course.mapper.CourseMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.course.domain.Course">
    <resultMap id="BaseResultMap" type="com.xinquan.course.api.domain.Course">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
@@ -17,6 +17,8 @@
        <result column="listing_status" property="listingStatus" />
        <result column="recommend" property="recommend" />
        <result column="charge_type" property="chargeType" />
        <result column="general_price" property="generalPrice"/>
        <result column="ios_price" property="iosPrice"/>
        <result column="sort_num" property="sortNum" />
        <result column="tutor" property="tutor" />
        <result column="cover_url" property="coverUrl" />
@@ -36,7 +38,7 @@
        create_time,
        update_by,
        update_time,
        id, course_type, cate_id, course_title, description, listing_status, recommend, charge_type, sort_num, tutor, cover_url, detail_url, brief_introduction, wx_qr_code, address, address_detail, longitude, latitude
        id, course_type, cate_id, course_title, description, listing_status, recommend, charge_type, general_price,ios_price,sort_num, tutor, cover_url, detail_url, brief_introduction, wx_qr_code, address, address_detail, longitude, latitude
    </sql>
</mapper>
xinquan-modules/xinquan-gen/src/main/resources/bootstrap.yml
New file
@@ -0,0 +1,36 @@
# Tomcat
server:
  port: 9202
# Spring
spring:
  application:
    # 应用名称
    name: xinquan-gen
  profiles:
    # 环境配置
    active: dev
---
spring:
  config:
    activate:
      on-profile: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 192.168.110.64:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: 8ebd2324-30b4-477b-af79-b46e717c4fbe
      config:
        # 配置中心地址
        server-addr: 192.168.110.64:8848
        namespace: 8ebd2324-30b4-477b-af79-b46e717c4fbe
        group: DEFAULT_GROUP
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
xinquan-modules/xinquan-job/src/main/resources/bootstrap.yml
New file
@@ -0,0 +1,25 @@
# Tomcat
server:
  port: 9203
# Spring
spring:
  application:
    # 应用名称
    name: xinquan-job
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientHomeController.java
@@ -181,8 +181,7 @@
            @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)
    })
    public R<PageDTO<ClientMeditationVO>> search(@RequestParam String condition,
            @RequestParam Integer
                    pageCurr, @RequestParam Integer pageSize) {
            @RequestParam Integer                    pageCurr, @RequestParam Integer pageSize) {
        return R.ok(meditationService.search(condition, pageCurr, pageSize));
    }
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/inner/InnerMeditationController.java
New file
@@ -0,0 +1,39 @@
package com.xinquan.meditation.controller.inner;
import com.xinquan.common.core.domain.R;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.service.MeditationService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 首页背景音乐用户关系表         前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/inner/meditation/meditation")
public class InnerMeditationController {
    private final MeditationService meditationService;
    /**
     * 根据id获取冥想音频
     *
     * @param targetId 冥想音频id
     * @return 冥想音频
     */
    @GetMapping("/getMeditationById")
    R<Meditation> getMeditationById(@RequestParam("targetId") Long targetId) {
        return R.ok(meditationService.getById(targetId));
    }
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java
@@ -1,13 +1,14 @@
package com.xinquan.meditation.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.time.LocalTime;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -37,11 +38,13 @@
    @ApiModelProperty(value = "播放时间段开始")
    @TableField("start_play_time")
    private LocalDateTime startPlayTime;
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime startPlayTime;
    @ApiModelProperty(value = "播放时间段结束")
    @TableField("end_play_time")
    private LocalDateTime endPlayTime;
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime endPlayTime;
    @ApiModelProperty(value = "每日冥想背景图片")
    @TableField("image_url")
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationUserFavorite.java
@@ -49,7 +49,6 @@
     * 创建时间
     */
    @ApiModelProperty(value = "记录创建时间,前端忽略")
    // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationDetailsVO.java
@@ -22,4 +22,7 @@
    @ApiModelProperty(value = "是否收藏 1:是 2:否")
    private Integer favorite;
    @ApiModelProperty(value = "提问数")
    private Long questionCount;
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationEverydayVO.java
@@ -1,9 +1,10 @@
package com.xinquan.meditation.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.LocalTime;
import lombok.Data;
/**
@@ -23,10 +24,12 @@
    private Long meditationId;
    @ApiModelProperty(value = "播放时间段开始")
    private LocalDateTime startPlayTime;
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime startPlayTime;
    @ApiModelProperty(value = "播放时间段结束")
    private LocalDateTime endPlayTime;
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime endPlayTime;
    @ApiModelProperty(value = "每日冥想背景图片")
    private String imageUrl;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/vo/ClientMeditationVO.java
@@ -34,6 +34,9 @@
    @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费")
    private Integer chargeType;
    @ApiModelProperty(value = "是否已付费 1:是 2:否")
    private Integer paidStatus = 2;
    @ApiModelProperty(value = "通用价格", notes = "价格设定为单独收费")
    private BigDecimal generalPrice;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMapper.java
@@ -1,7 +1,7 @@
package com.xinquan.meditation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.meditation.domain.Meditation;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.vo.ClientMeditationVO;
import java.util.List;
import java.util.Set;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationService.java
@@ -2,7 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.meditation.domain.Meditation;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.vo.ClientMeditationAndCateVO;
import com.xinquan.meditation.domain.vo.ClientMeditationDetailsVO;
import com.xinquan.meditation.domain.vo.ClientMeditationQuestionVO;
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationEverydayServiceImpl.java
@@ -1,15 +1,15 @@
package com.xinquan.meditation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.utils.DateUtils;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.meditation.domain.Meditation;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.MeditationEveryday;
import com.xinquan.meditation.domain.vo.ClientMeditationEverydayVO;
import com.xinquan.meditation.domain.vo.ClientMeditationVO;
import com.xinquan.meditation.mapper.MeditationEverydayMapper;
import com.xinquan.meditation.mapper.MeditationMapper;
import com.xinquan.meditation.service.MeditationEverydayService;
import java.time.LocalDateTime;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -37,11 +37,11 @@
    public ClientMeditationEverydayVO getTodayMeditation() {
        ClientMeditationEverydayVO vo = null;
        // 当前时间
        LocalDateTime now = LocalDateTime.now();
        String now = DateUtils.dateTimeNow("HH:mm:ss");
        // 查询播放时间段在当前时间的每日冥想
        Optional<MeditationEveryday> meditationEverydayOpt = this.lambdaQuery()
                .le(MeditationEveryday::getStartPlayTime, now)
                .ge(MeditationEveryday::getEndPlayTime, now)
                .gt(MeditationEveryday::getEndPlayTime, now)
                .orderByDesc(MeditationEveryday::getUpdateTime)
                .last("limit 1").oneOpt();
        if (!meditationEverydayOpt.isPresent()) {
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java
@@ -5,12 +5,13 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.enums.DisabledEnum;
import com.xinquan.common.core.enums.OrderFromEnum;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.core.utils.page.CollUtils;
import com.xinquan.common.core.utils.page.PageDTO;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.meditation.domain.Meditation;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.domain.MeditationCategory;
import com.xinquan.meditation.domain.MeditationMusic;
import com.xinquan.meditation.domain.MeditationQuestion;
@@ -28,6 +29,8 @@
import com.xinquan.meditation.service.MeditationQuestionLikeService;
import com.xinquan.meditation.service.MeditationService;
import com.xinquan.meditation.service.MeditationUserFavoriteService;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.api.feign.RemoteOrderService;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
@@ -61,7 +64,7 @@
    private final MeditationQuestionMapper meditationQuestionMapper;
    private final MeditationQuestionLikeService meditationQuestionLikeService;
    private final MeditationUserFavoriteService meditationUserFavoriteService;
    private final RemoteOrderService remoteOrderService;
    /**
     * 获取私人订制
     *
@@ -79,6 +82,30 @@
                    .collect(Collectors.toSet());
            // 查询冥想列表
            voList = baseMapper.getMeditationListByTagId(tagIdSet, sanskritFlag);
        }
        voList = handlePaidMeditation(voList);
        return voList;
    }
    /**
     * 处理已付费冥想音频
     *
     * @param voList
     * @return
     */
    private List<ClientMeditationVO> handlePaidMeditation(List<ClientMeditationVO> voList) {
        // 远程调用订单服务,查询用户已付费冥想
        Long userId = SecurityUtils.getUserId();
        List<Order> orderList = remoteOrderService.getOrderListByType(userId,
                OrderFromEnum.MEDITATION.getCode(),
                SecurityConstants.INNER).getData();
        List<Long> meditationIdList = orderList.stream().map(Order::getBusinessId)
                .collect(Collectors.toList());
        if (CollUtils.isNotEmpty(meditationIdList)) {
            voList = voList.stream()
                    .filter(meditationVO -> meditationIdList.contains(meditationVO.getId()))
                    .peek(meditationVO -> meditationVO.setPaidStatus(1))
                    .collect(Collectors.toList());
        }
        return voList;
    }
@@ -102,6 +129,7 @@
            // 对象拷贝
            voList = BeanUtils.copyList(list, ClientMeditationVO.class);
        }
        handlePaidMeditation(voList);
        return voList;
    }
@@ -205,6 +233,7 @@
        });*/
        // 将实体类转换为VO
        pageDTO = PageDTO.of(page, ClientMeditationVO.class);
        handlePaidMeditation(pageDTO.getList());
        return pageDTO;
    }
@@ -235,6 +264,10 @@
                .eq(MeditationUserFavorite::getMeditationId, id)
                .eq(MeditationUserFavorite::getAppUserId, SecurityUtils.getUserId())
                .count() > 0 ? 1 : 2);
        // 获取提问数
        vo.setQuestionCount(meditationQuestionMapper.selectCount(
                Wrappers.lambdaQuery(MeditationQuestion.class)
                        .eq(MeditationQuestion::getMeditationId, id)));
        return vo;
    }
@@ -256,7 +289,7 @@
                .last("limit 1").oneOpt();
        if (userOperationOpt.isPresent()) {
            meditationUserFavoriteService.removeById(userOperationOpt.get());
            // 增加收藏数
            // 减少收藏数
            meditation.setFavoriteCount(meditation.getFavoriteCount() - 1);
        } else {
            // 增加收藏记录
@@ -264,7 +297,7 @@
            meditationUserFavorite.setMeditationId(id);
            meditationUserFavorite.setAppUserId(SecurityUtils.getUserId());
            meditationUserFavoriteService.save(meditationUserFavorite);
            // 减少收藏数
            // 增加收藏数
            meditation.setFavoriteCount(meditation.getFavoriteCount() + 1);
        }
        this.updateById(meditation);
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMapper.xml
@@ -3,7 +3,7 @@
<mapper namespace="com.xinquan.meditation.mapper.MeditationMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.Meditation">
    <resultMap id="BaseResultMap" type="com.xinquan.meditation.api.domain.Meditation">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
@@ -24,6 +24,7 @@
        <result column="detail_description" property="detailDescription" />
        <result column="cover_description" property="coverDescription" />
        <result column="tutor_audio_url" property="tutorAudioUrl" />
        <result column="tutor_audio_duration" property="tutorAudioDuration"/>
        <result column="favorite_count" property="favoriteCount" />
    </resultMap>
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMusicMapper.xml
@@ -7,6 +7,7 @@
        <id column="id" property="id" />
        <result column="meditation_id" property="meditationId" />
        <result column="music_url" property="musicUrl" />
        <result column="music_duration" property="musicDuration"/>
    </resultMap>
    <!-- 通用查询结果列 -->
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java
@@ -2,12 +2,16 @@
import com.xinquan.common.core.domain.R;
import com.xinquan.order.domain.vo.ClientPlaceOrderVO;
import com.xinquan.order.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -26,10 +30,39 @@
    private OrderService orderService;
    @PostMapping("/createOrder")
    @ApiOperation(value = "创建订单")
    public R<?> createOrder() {
        return R.ok();
    /**
     * 创建待支付订单
     *
     * @param targetId    目标id
     * @param orderFrom   订单来源 1=冥想音频 2=课程
     * @param receiverId  被赠送课程APP用户id
     * @param balanceFlag 是否使用余额抵扣 1=是 2=否
     * @param payType     支付方式 1=微信 2=支付宝
     * @return 下单返回数据视图对象
     * @see com.xinquan.order.domain.vo.ClientPlaceOrderVO
     */
    @PostMapping("/placeOrder")
    @ApiOperation(value = "创建待支付订单", notes = "微信|支付宝")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "targetId", value = "目标id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "orderFrom", value = "订单来源 1=冥想音频 2=课程", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "receiverId", value = "被赠送课程APP用户id", dataType = "Long", required = false),
            @ApiImplicitParam(name = "balanceFlag", value = "是否使用余额抵扣 1=是 2=否", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "payType", value = "支付方式 1=微信 2=支付宝", dataType = "Integer", required = true)
    })
    public R<ClientPlaceOrderVO> placeOrder(
            @RequestParam(value = "targetId") Long targetId,
            @RequestParam(value = "orderFrom") Integer orderFrom,
            @RequestParam(value = "receiverId", required = false) Long receiverId,
            @RequestParam(value = "balanceFlag") Integer balanceFlag,
            @RequestParam(value = "payType") Integer payType) {
        try {
            return R.ok(
                    orderService.placeOrder(targetId, orderFrom, receiverId,
                            balanceFlag, payType));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/NotifyController.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.order.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 支付回调控制器
 *
 * @author mitao
 * @date 2024/9/9
 */
@RestController
@RequestMapping("/client/order/notify")
public class NotifyController {
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/inner/InnerOrderController.java
New file
@@ -0,0 +1,45 @@
package com.xinquan.order.controller.inner;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.security.annotation.InnerAuth;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.service.OrderService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 订单表 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/inner/order/order")
public class InnerOrderController {
    private final OrderService orderService;
    /**
     * 根据类型获取已完成的订单列表
     *
     * @param userId    用户id
     * @param orderFrom 订单来源
     * @return
     */
    @InnerAuth
    @PostMapping("/getOrderListByType")
    R<List<Order>> getOrderListByType(@RequestParam("userId") Long userId,
            @RequestParam("orderFrom") Integer orderFrom) {
        return R.ok(orderService.getOrderListByType(userId, orderFrom));
    }
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/OrderPaymentRecord.java
@@ -1,13 +1,13 @@
package com.xinquan.order.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -35,7 +35,7 @@
    @TableField("order_id")
    private Long orderId;
    @ApiModelProperty(value = "支付类型 1=微信支付 2=支付宝支付 3=余额支付    4=IOS内购支付")
    @ApiModelProperty(value = "支付类型 1=微信支付 2=支付宝支付 3=IOS内购支付 4=余额支付")
    @TableField("payment_type")
    private Integer paymentType;
@@ -43,9 +43,11 @@
    @TableField("pay_amount")
    private BigDecimal payAmount;
    @ApiModelProperty(value = "支付商户订单号")
    @ApiModelProperty(value = "第三方支付订单号")
    @TableField("pay_order_no")
    private String payOrderNo;
    @ApiModelProperty(value = "支付状态 1=待支付 2=已完成 3=已取消")
    @TableField("payment_status")
    private Integer paymentStatus;
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/vo/ClientPlaceOrderVO.java
New file
@@ -0,0 +1,31 @@
package com.xinquan.order.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/9/9
 */
@Data
@ApiModel("下单返回数据视图对象")
public class ClientPlaceOrderVO implements Serializable {
    private static final long serialVersionUID = -7087327695114447889L;
    @ApiModelProperty("订单id")
    private Long id;
    @ApiModelProperty(value = "订单编号")
    private String orderNo;
    @ApiModelProperty(value = "金额为零无需支付 1是 2否")
    private Integer zeroFlag;
    @ApiModelProperty("支付宝支付链接")
    private String qrcodeUrl;
    @ApiModelProperty("微信支付信息,用于唤起微信支付")
    private String payInfo;
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderMapper.java
@@ -1,7 +1,7 @@
package com.xinquan.order.mapper;
import com.xinquan.order.domain.Order;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.order.api.domain.Order;
/**
 * <p>
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderService.java
@@ -1,7 +1,9 @@
package com.xinquan.order.service;
import com.xinquan.order.domain.Order;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.domain.vo.ClientPlaceOrderVO;
import java.util.List;
/**
 * <p>
@@ -13,4 +15,26 @@
 */
public interface OrderService extends IService<Order> {
    /**
     * 创建待支付订单
     *
     * @param targetId    目标id
     * @param orderFrom   订单来源 1=冥想音频 2=课程
     * @param receiverId  被赠送课程APP用户id
     * @param balanceFlag 是否使用余额抵扣 1=是 2=否
     * @param payType     支付方式 1=微信 2=支付宝
     * @return 下单返回数据视图对象
     * @see com.xinquan.order.domain.vo.ClientPlaceOrderVO
     */
    ClientPlaceOrderVO placeOrder(Long targetId, Integer orderFrom, Long receiverId,
            Integer balanceFlag, Integer payType) throws Exception;
    /**
     * 根据类型获取已完成的订单列表
     *
     * @param userId    用户id
     * @param orderFrom 订单来源
     * @return
     */
    List<Order> getOrderListByType(Long userId, Integer orderFrom);
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java
@@ -1,10 +1,37 @@
package com.xinquan.order.service.impl;
import com.xinquan.order.domain.Order;
import com.xinquan.order.mapper.OrderMapper;
import com.xinquan.order.service.OrderService;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.enums.ChargeTypeEnum;
import com.xinquan.common.core.enums.DisabledEnum;
import com.xinquan.common.core.enums.PaymentStatusEnum;
import com.xinquan.common.core.enums.PaymentTypeEnum;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.core.utils.ip.IpUtils;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.course.api.domain.Course;
import com.xinquan.course.api.feign.RemoteCourseService;
import com.xinquan.meditation.api.domain.Meditation;
import com.xinquan.meditation.api.feign.RemoteMeditationService;
import com.xinquan.order.api.domain.Order;
import com.xinquan.order.domain.OrderPaymentRecord;
import com.xinquan.order.domain.vo.ClientPlaceOrderVO;
import com.xinquan.order.mapper.OrderMapper;
import com.xinquan.order.service.OrderPaymentRecordService;
import com.xinquan.order.service.OrderService;
import com.xinquan.order.utils.JuHeFuUtil;
import com.xinquan.order.utils.OrderUtil;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import java.math.BigDecimal;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * <p>
@@ -15,6 +42,206 @@
 * @since 2024-08-21
 */
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    private final RemoteMeditationService remoteMeditationService;
    private final RemoteCourseService remoteCourseService;
    private final RemoteAppUserService remoteAppUserService;
    private final OrderPaymentRecordService orderPaymentRecordService;
    /**
     * 创建待支付订单
     *
     * @param targetId    目标id
     * @param orderFrom   订单来源 1=冥想音频 2=课程
     * @param receiverId  被赠送课程APP用户id
     * @param balanceFlag 是否使用余额抵扣 1=是 2=否
     * @param payType     支付方式 1=微信 2=支付宝
     * @return 下单返回数据视图对象
     * @see com.xinquan.order.domain.vo.ClientPlaceOrderVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ClientPlaceOrderVO placeOrder(Long targetId, Integer orderFrom, Long receiverId,
            Integer balanceFlag, Integer payType) throws Exception {
        // 获取当前登录用户id
        Long userId = SecurityUtils.getUserId();
        // 获取用户信息
        AppUser appUser = getAppUserById(userId);
        ClientPlaceOrderVO clientPlaceOrderVO = new ClientPlaceOrderVO();
        Order order = new Order();
        // 购买冥想音频
        if (orderFrom == 1) {
            Meditation meditation = remoteMeditationService.getMeditationById(targetId,
                    SecurityConstants.INNER).getData();
            String meditationTitle = meditation.getMeditationTitle();
            String detailDescription = meditation.getDetailDescription();
            String wxOpenId = appUser.getWxOpenId();
            // 创建订单
            String orderNo = OrderUtil.getOrderNoForPrefix("MX");
            order.setOrderFrom(orderFrom);
            order.setBizOrderNo(orderNo);
            order.setBusinessId(meditation.getId());
            order.setAppUserId(userId);
            order.setTotalAmount(meditation.getGeneralPrice());
            this.save(order);
            Long orderId = order.getId();
            clientPlaceOrderVO.setOrderNo(orderNo);
            clientPlaceOrderVO.setId(orderId);
            // 如果冥想音频价格设定为单独收费,且需要使用余额抵扣
            if (balanceFlag.equals(1) && meditation.getChargeType()
                    .equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) {
                BigDecimal needPayAmount = handleBalancePayment(appUser,
                        meditation.getGeneralPrice(),
                        orderId);
                if (needPayAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    clientPlaceOrderVO.setZeroFlag(DisabledEnum.YES.getCode());
                    return clientPlaceOrderVO;
                }
                // 创建支付订单
                createPayment(payType, orderNo, needPayAmount, meditationTitle, detailDescription,
                        wxOpenId, orderId, clientPlaceOrderVO);
            } else {
                // 创建支付订单
                createPayment(payType, orderNo, meditation.getGeneralPrice(), meditationTitle,
                        detailDescription, wxOpenId, orderId, clientPlaceOrderVO);
            }
        } else {
            // 购买课程
            Course course = remoteCourseService.getCourseById(targetId,
                    SecurityConstants.INNER).getData();
            String courseTitle = course.getCourseTitle();
            String wxOpenId = appUser.getWxOpenId();
            String description = course.getDescription();
            // 创建订单
            String orderNo = OrderUtil.getOrderNoForPrefix("KC");
            order.setOrderFrom(orderFrom);
            order.setBizOrderNo(orderNo);
            order.setBusinessId(course.getId());
            order.setAppUserId(userId);
            order.setTotalAmount(course.getGeneralPrice());
            this.save(order);
            Long orderId = order.getId();
            clientPlaceOrderVO.setOrderNo(orderNo);
            clientPlaceOrderVO.setId(orderId);
            if (balanceFlag.equals(1) && course.getChargeType()
                    .equals(ChargeTypeEnum.SEPARATE_CHARGE.getCode())) {
                BigDecimal needPayAmount = handleBalancePayment(appUser, course.getGeneralPrice(),
                        orderId);
                if (needPayAmount.compareTo(BigDecimal.ZERO) <= 0) {
                    clientPlaceOrderVO.setZeroFlag(DisabledEnum.YES.getCode());
                    return clientPlaceOrderVO;
                }
                // 创建支付订单
                createPayment(payType, orderNo, needPayAmount, courseTitle, description,
                        wxOpenId, orderId, clientPlaceOrderVO);
            } else {
                // 创建支付订单
                createPayment(payType, orderNo, course.getGeneralPrice(), courseTitle,
                        description, wxOpenId, orderId, clientPlaceOrderVO);
            }
        }
        return clientPlaceOrderVO;
    }
    /**
     * 处理余额抵扣
     *
     * @param appUser      app用户
     * @param generalPrice 通用价格
     * @param orderId      订单号
     * @return 需要支付的金额
     */
    @NotNull
    private BigDecimal handleBalancePayment(AppUser appUser, BigDecimal generalPrice,
            Long orderId) {
        if (appUser.getBalance().compareTo(BigDecimal.ZERO) < 0) {
            throw new ServiceException("用户可用余额不足,请重新选择支付方案");
        }
        // 更新用户余额
        remoteAppUserService.updateAppUser(
                AppUserDTO.builder().balance(
                                appUser.getBalance().subtract(generalPrice))
                        .build(), SecurityConstants.INNER);
        OrderPaymentRecord balancePaymentRecord = new OrderPaymentRecord();
        balancePaymentRecord.setOrderId(orderId);
        balancePaymentRecord.setPaymentType(PaymentTypeEnum.BALANCE_PAY.getCode());
        balancePaymentRecord.setPaymentStatus(PaymentStatusEnum.COMPLETED.getCode());
        orderPaymentRecordService.save(balancePaymentRecord);
        // 计算除去余额还需支付的金额
        return generalPrice
                .subtract(appUser.getBalance());
    }
    /**
     * 获取登录用户信息
     *
     * @param userId APP用户id
     * @return AppUser
     */
    private AppUser getAppUserById(Long userId) {
        return remoteAppUserService.getUserByCondition(
                AppUserDTO.builder().id(userId).build(),
                SecurityConstants.INNER).getData();
    }
    /**
     * 创建支付订单
     *
     * @param payType            支付方式 1=微信 2=支付宝
     * @param orderNo            订单编号
     * @param needPayAmount      支付金额
     * @param goodsTitle         商品标题
     * @param goodsDesc          商品描述
     * @param wxOpenId           微信openId
     * @param orderId            订单id
     * @param clientPlaceOrderVO 下单返回数据视图对象
     * @throws Exception
     */
    private void createPayment(Integer payType, String orderNo, BigDecimal needPayAmount,
            String goodsTitle, String goodsDesc, String wxOpenId, Long orderId,
            ClientPlaceOrderVO clientPlaceOrderVO) throws Exception {
        // 截取前42个字符 商品描述信息,微信小程序和微信公众号该字段,最大长度 42 个字符
        goodsDesc = goodsDesc.substring(0, 42);
        // 调用第三方支付获取支付信息
        JSONObject payInfo = JuHeFuUtil.createPayment(orderNo, payType,
                needPayAmount.toString(), goodsTitle, goodsDesc,
                IpUtils.getIpAddr(), wxOpenId, Constants.PAYMENT_NOTIFY_URL);
        // 第三方支付记录
        OrderPaymentRecord paymentRecord = new OrderPaymentRecord();
        paymentRecord.setOrderId(orderId);
        if (payType == 1) {
            clientPlaceOrderVO.setPayInfo(payInfo.getString("pay_info"));
            paymentRecord.setPaymentType(PaymentTypeEnum.WECHAT_PAY.getCode());
        } else {
            clientPlaceOrderVO.setQrcodeUrl(payInfo.getString("qrcode_url"));
            paymentRecord.setPaymentType(PaymentTypeEnum.ALI_PAY.getCode());
        }
        paymentRecord.setPaymentStatus(PaymentStatusEnum.TO_BE_PAID.getCode());
        orderPaymentRecordService.save(paymentRecord);
        // 设置订单是否需要支付标识
        clientPlaceOrderVO.setZeroFlag(DisabledEnum.NO.getCode());
    }
    /**
     * 根据类型获取已完成的订单列表
     *
     * @param userId    用户id
     * @param orderFrom 订单来源
     * @return
     */
    @Override
    public List<Order> getOrderListByType(Long userId, Integer orderFrom) {
        return this.lambdaQuery().eq(Order::getAppUserId, userId).eq(Order::getOrderFrom, orderFrom)
                .eq(Order::getPaymentStatus, PaymentStatusEnum.COMPLETED.getCode()).list();
    }
}
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/utils/JuHeFuUtil.java
@@ -106,7 +106,7 @@
     * @return JSONObject
     * @throws Exception
     */
    public JSONObject createPayment(String orderNo, Integer payChannel, String payAmt,
    public static JSONObject createPayment(String orderNo, Integer payChannel, String payAmt,
            String goodsTitle, String goodsDesc, String deviceIp, String openId,
            String notifyUrl) throws Exception {
        JSONObject data = new JSONObject();
@@ -153,7 +153,7 @@
     * @param orderNo   订单号
     * @return
     */
    public boolean refund(String paymentId, String orderNo) throws Exception {
    public static boolean refund(String paymentId, String orderNo) throws Exception {
        JSONObject data = new JSONObject();
        data.put("payment_id", paymentId);
        data.put("order_no", orderNo);
@@ -185,7 +185,7 @@
     * @return
     * @throws Exception
     */
    public boolean merchantPay(String orderNo, String payAmt, String cardName, String cardId,
    public static boolean merchantPay(String orderNo, String payAmt, String cardName, String cardId,
            String cardType)
            throws Exception {
        JSONObject data = new JSONObject();
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/utils/OrderUtil.java
New file
@@ -0,0 +1,54 @@
package com.xinquan.order.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 订单处理工具类
 */
public class OrderUtil {
    /* 订单号 */
    private static long orderNum = 0l;
    /* 日期 */
    private static String date;
    /**
     * 生成不重复的订单号 【纯数字】
     *
     * @return
     */
    public static synchronized String getOrderNo() {
        String str = new SimpleDateFormat("yyMMddHHmm").format(new Date());
        if (date == null || !date.equals(str)) {
            date = str;
            orderNum = 0l;
        }
        orderNum++;
        long orderNo = Long.parseLong((date)) * 10000;
        orderNo += orderNum;
        return orderNo + "";
    }
    /**
     * 生成不重复的订单号 【含前缀】
     *
     * @param prefix
     * @return
     */
    public static synchronized String getOrderNoForPrefix(String prefix) {
        return prefix + getOrderNo();
    }
    /**
     * 生成不重复的订单号 【含后缀】
     *
     * @param suffix
     * @return
     */
    public static synchronized String getOrderNoForSuffix(String suffix) {
        return getOrderNo() + suffix;
    }
}
xinquan-modules/xinquan-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -3,7 +3,7 @@
<mapper namespace="com.xinquan.order.mapper.OrderMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.order.domain.Order">
    <resultMap id="BaseResultMap" type="com.xinquan.order.api.domain.Order">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
xinquan-modules/xinquan-order/src/main/resources/mapper/order/OrderPaymentRecordMapper.xml
@@ -14,6 +14,7 @@
        <result column="payment_type" property="paymentType" />
        <result column="pay_amount" property="payAmount" />
        <result column="pay_order_no" property="payOrderNo" />
        <result column="payment_status" property="paymentStatus"/>
    </resultMap>
    <!-- 通用查询结果列 -->
@@ -23,7 +24,7 @@
        create_time,
        update_by,
        update_time,
        id, order_id, payment_type, pay_amount, pay_order_no
        id, order_id, payment_type, pay_amount, pay_order_no,payment_status
    </sql>
</mapper>
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientNoticeRecordController.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.user.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
@RestController
@RequestMapping("/client/user/notice-record")
public class ClientNoticeRecordController {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerNoticeRecordController.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.user.controller.inner;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
@RestController
@RequestMapping("/inner/user/notice-record")
public class InnerNoticeRecordController {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/NoticeRecord.java
New file
@@ -0,0 +1,58 @@
package com.xinquan.user.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 *
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_notice_record")
@ApiModel(value = "NoticeRecord对象", description = "")
public class NoticeRecord extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "APP用户id")
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "冥想提问id 类型为回复通知时使用")
    @TableField("meditation_question_id")
    private Long meditationQuestionId;
    @ApiModelProperty(value = "查看状态 1:未读 2:已读    ")
    @TableField("read_status")
    private Integer readStatus;
    @ApiModelProperty(value = "通知类型 1=系统通知 2=回复通知")
    @TableField("notice_type")
    private Integer noticeType;
    @ApiModelProperty(value = "通知标题")
    @TableField("title")
    private String title;
    @ApiModelProperty(value = "通知内容")
    @TableField("content")
    private String content;
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/NoticeRecordMapper.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.user.domain.NoticeRecord;
/**
 * <p>
 * Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
public interface NoticeRecordMapper extends BaseMapper<NoticeRecord> {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/NoticeRecordService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.user.domain.NoticeRecord;
/**
 * <p>
 * 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
public interface NoticeRecordService extends IService<NoticeRecord> {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/NoticeRecordServiceImpl.java
New file
@@ -0,0 +1,21 @@
package com.xinquan.user.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.user.domain.NoticeRecord;
import com.xinquan.user.mapper.NoticeRecordMapper;
import com.xinquan.user.service.NoticeRecordService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-09-09
 */
@Service
public class NoticeRecordServiceImpl extends
        ServiceImpl<NoticeRecordMapper, NoticeRecord> implements NoticeRecordService {
}
xinquan-modules/xinquan-user/src/main/resources/mapper/user/NoticeRecordMapper.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinquan.user.mapper.NoticeRecordMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.user.domain.NoticeRecord">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="app_user_id" property="appUserId" />
        <result column="meditation_question_id" property="meditationQuestionId" />
        <result column="read_status" property="readStatus" />
        <result column="notice_type" property="noticeType" />
        <result column="title" property="title" />
        <result column="content" property="content" />
    </resultMap>
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        del_flag,
        create_by,
        create_time,
        update_by,
        update_time,
        id, app_user_id, meditation_question_id, read_status, notice_type, title, content
    </sql>
</mapper>
xinquan-ui/src/assets/icons/svgo.yml
New file
@@ -0,0 +1,22 @@
# replace default config
# multipass: true
# full: true
plugins:
  # - name
  #
  # or:
  # - name: false
  # - name: true
  #
  # or:
  # - name:
  #     param1: 1
  #     param2: 2
- removeAttrs:
    attrs:
      - 'fill'
      - 'fill-rule'
xinquan-visual/xinquan-monitor/src/main/resources/bootstrap.yml
New file
@@ -0,0 +1,25 @@
# Tomcat
server:
  port: 9100
# Spring
spring:
  application:
    # 应用名称
    name: xinquan-monitor
  profiles:
    # 环境配置
    active: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}