From e4f9152bcacf02be0cb376dcb225eaf444b8951b Mon Sep 17 00:00:00 2001
From: seatonwan9
Date: 星期四, 14 八月 2025 00:21:05 +0800
Subject: [PATCH] 提交源码

---
 src/main/java/com/webmanage/controller/ApprovalController.java            |  113 
 src/main/java/com/webmanage/service/impl/ApprovalRecordServiceImpl.java   |  170 +
 src/main/java/com/webmanage/service/ApprovalRecordService.java            |   45 
 src/main/java/com/webmanage/service/PointsRuleDetailService.java          |   11 
 src/main/java/com/webmanage/controller/PointsController.java              |  275 +
 src/main/java/com/webmanage/controller/FileController.java                |  156 
 src/main/java/com/webmanage/entity/Points.java                            |   73 
 src/main/java/com/webmanage/mapper/OrderAttachmentMapper.java             |   20 
 src/main/java/com/webmanage/mapper/UserPointsMapper.java                  |   26 
 src/main/java/com/webmanage/controller/CartController.java                |  214 +
 src/main/java/com/webmanage/vo/OrderEvaluationVO.java                     |   63 
 src/main/resources/application-dev.yml                                    |  128 
 src/main/resources/mapper/ApprovalRecordMapper.xml                        |  117 
 src/main/java/com/webmanage/dto/PointsFlowQueryDTO.java                   |   48 
 src/main/java/com/webmanage/service/PointsRuleService.java                |   49 
 src/main/java/com/webmanage/mapper/OrderEvaluationMapper.java             |   18 
 src/main/java/com/webmanage/mapper/PointsMapper.java                      |   24 
 src/main/java/com/webmanage/dto/AddPointsFlowDTO.java                     |   41 
 src/main/java/com/webmanage/dto/PointsRuleDetailDTO.java                  |   56 
 src/main/java/com/webmanage/service/PointsFlowService.java                |   56 
 src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java        |  422 ++
 src/main/java/com/webmanage/controller/ProductPricingController.java      |  164 +
 src/main/java/com/webmanage/service/OrderInfoService.java                 |   65 
 src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java       |  401 ++
 src/main/java/com/webmanage/mapper/ProductPricingMapper.java              |   39 
 src/main/java/com/webmanage/common/FileUploadException.java               |   40 
 src/main/java/com/webmanage/dto/PointsQueryDTO.java                       |   50 
 src/main/java/com/webmanage/entity/PointsFlow.java                        |   89 
 pom.xml                                                                   |  144 
 src/main/java/com/webmanage/controller/OrderController.java               |  182 +
 src/main/java/com/webmanage/entity/Cart.java                              |  112 
 src/main/resources/mapper/PointsFlowMapper.xml                            |   40 
 src/main/java/com/webmanage/dto/PointsRuleDTO.java                        |   54 
 src/main/java/com/webmanage/mapper/OrderDetailMapper.java                 |   20 
 src/main/java/com/webmanage/config/MybatisPlusConfig.java                 |   50 
 src/main/resources/mapper/PointsMapper.xml                                |   54 
 src/main/java/com/webmanage/common/BusinessException.java                 |   40 
 src/main/resources/mapper/CartMapper.xml                                  |   73 
 src/main/java/com/webmanage/dto/PointsOperateDTO.java                     |   18 
 src/main/java/com/webmanage/vo/PointsStatsVO.java                         |   50 
 src/main/resources/mapper/OrderEvaluationMapper.xml                       |   42 
 src/main/java/com/webmanage/service/impl/PointsRuleServiceImpl.java       |  185 +
 src/main/java/com/webmanage/mapper/PointsRuleMapper.java                  |   15 
 src/main/java/com/webmanage/service/MinioService.java                     |  151 
 src/main/resources/sql/trade_module.sql                                   |  403 ++
 src/main/java/com/webmanage/common/PageResult.java                        |   64 
 src/main/java/com/webmanage/common/GlobalExceptionHandler.java            |  115 
 src/main/java/com/webmanage/service/CartService.java                      |   73 
 src/main/java/com/webmanage/entity/OrderDetail.java                       |  105 
 src/main/java/com/webmanage/dto/PointsDTO.java                            |   41 
 src/main/resources/application.yml                                        |  133 
 src/main/resources/mapper/OrderDetailMapper.xml                           |   46 
 src/main/java/com/webmanage/entity/PointsRule.java                        |   83 
 src/main/java/com/webmanage/dto/CreateOrderDTO.java                       |   50 
 src/main/java/com/webmanage/mapper/PointsFlowMapper.java                  |   32 
 src/main/java/com/webmanage/service/impl/PointsRuleDetailServiceImpl.java |   17 
 src/main/java/com/webmanage/entity/PointsRuleDetail.java                  |   87 
 src/main/java/com/webmanage/service/OrderNoService.java                   |   16 
 src/main/java/com/webmanage/service/UserPointsService.java                |   28 
 src/main/java/com/webmanage/service/impl/OrderNoServiceImpl.java          |   50 
 src/main/java/com/webmanage/entity/OrderInfo.java                         |  144 
 src/main/java/com/webmanage/entity/UserPoints.java                        |   83 
 src/main/java/com/webmanage/service/ProductPricingService.java            |   48 
 src/main/java/com/webmanage/service/impl/PointsServiceImpl.java           |   38 
 src/main/java/com/webmanage/WebManageApplication.java                     |   21 
 src/main/java/com/webmanage/entity/PointsRuleEntity.java                  |   66 
 src/main/java/com/webmanage/service/impl/CartServiceImpl.java             |  488 +++
 src/main/java/com/webmanage/entity/OrderEvaluation.java                   |   88 
 src/main/resources/mapper/UserPointsMapper.xml                            |   23 
 src/main/java/com/webmanage/service/impl/UserPointsServiceImpl.java       |  127 
 src/main/resources/mapper/OrderAttachmentMapper.xml                       |   42 
 src/main/java/com/webmanage/mapper/ApprovalRecordMapper.java              |   51 
 src/main/java/com/webmanage/mapper/PointsRuleDetailMapper.java            |   15 
 src/main/java/com/webmanage/vo/OrderDetailVO.java                         |   83 
 src/main/java/com/webmanage/dto/CreateOrderItemDTO.java                   |   65 
 src/main/java/com/webmanage/dto/CartItemDTO.java                          |   73 
 src/main/java/com/webmanage/vo/PointsDetailVO.java                        |   28 
 src/main/java/com/webmanage/mapper/CartMapper.java                        |   35 
 src/main/resources/mapper/OrderInfoMapper.xml                             |  193 +
 src/main/java/com/webmanage/dto/PointsMainQueryDTO.java                   |   51 
 src/main/resources/mapper/ProductPricingMapper.xml                        |   81 
 src/main/java/com/webmanage/util/SnowflakeIdWorker.java                   |  101 
 src/main/java/com/webmanage/mapper/OrderInfoMapper.java                   |   46 
 src/main/java/com/webmanage/vo/OrderDetailItemVO.java                     |   66 
 src/main/java/com/webmanage/dto/ApprovalActionDTO.java                    |   55 
 src/main/resources/sql/数据库表说明.md                                          |  142 
 src/main/java/com/webmanage/config/JacksonConfig.java                     |   43 
 src/main/java/com/webmanage/service/PointsService.java                    |   17 
 src/main/java/com/webmanage/common/Result.java                            |   97 
 src/main/java/com/webmanage/config/MinioConfig.java                       |   50 
 src/main/java/com/webmanage/entity/ApprovalRecord.java                    |   88 
 src/main/java/com/webmanage/service/impl/ProductPricingServiceImpl.java   |  188 +
 src/main/java/com/webmanage/dto/ApprovalQueryDTO.java                     |   60 
 src/main/java/com/webmanage/dto/CartQueryDTO.java                         |   29 
 src/main/java/com/webmanage/vo/CartVO.java                                |   35 
 src/main/java/com/webmanage/vo/OrderAttachmentVO.java                     |   63 
 src/main/java/com/webmanage/config/RedisConfig.java                       |   47 
 src/main/java/com/webmanage/entity/ProductPricing.java                    |  144 
 src/main/resources/sql/init.sql                                           |  501 +++
 src/main/java/com/webmanage/entity/OrderAttachment.java                   |   88 
 src/main/java/com/webmanage/vo/CartItemVO.java                            |   73 
 src/main/java/com/webmanage/dto/OrderQueryDTO.java                        |   66 
 102 files changed, 9,388 insertions(+), 0 deletions(-)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..1c94aa9
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
+         http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.6.10</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>com.webmanage</groupId>
+    <artifactId>web-manage-back</artifactId>
+    <version>1.0.0</version>
+    <name>web-manage-back</name>
+    <description>绉垎绠$悊绯荤粺鍚庣</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <mybatis-plus.version>3.5.1</mybatis-plus.version>
+        <postgresql.version>42.3.3</postgresql.version>
+        <druid.version>1.2.8</druid.version>
+        <minio.version>8.4.3</minio.version>
+        <fastjson.version>2.0.7</fastjson.version>
+        <hutool.version>5.8.0</hutool.version>
+        <knife4j.version>3.0.3</knife4j.version>
+        <okhttp.version>4.10.0</okhttp.version>
+    </properties>
+
+    <dependencies>
+        <!-- Spring Boot Starter -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- Spring Boot Starter Data Redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- Spring Boot Starter Validation -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+        <!-- MyBatis Plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+
+        <!-- PostgreSQL Driver -->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>${postgresql.version}</version>
+        </dependency>
+
+        <!-- Druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+
+        <!-- MinIO -->
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>${minio.version}</version>
+        </dependency>
+        <!-- 寮哄埗缁熶竴OkHttp鐗堟湰 -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>${okhttp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp-urlconnection</artifactId>
+            <version>${okhttp.version}</version>
+        </dependency>
+
+        <!-- FastJSON -->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+
+        <!-- Hutool -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+
+        <!-- Knife4j API鏂囨。 -->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>${knife4j.version}</version>
+        </dependency>
+
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- Spring Boot Test -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!--鍒嗛〉鎻掍欢-->
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/src/main/java/com/webmanage/WebManageApplication.java b/src/main/java/com/webmanage/WebManageApplication.java
new file mode 100644
index 0000000..4af56a8
--- /dev/null
+++ b/src/main/java/com/webmanage/WebManageApplication.java
@@ -0,0 +1,21 @@
+package com.webmanage;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 绉垎绠$悊绯荤粺鍚姩绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@SpringBootApplication
+@MapperScan("com.webmanage.mapper")
+public class WebManageApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(WebManageApplication.class, args);
+        System.out.println("绉垎绠$悊绯荤粺鍚姩鎴愬姛锛�");
+    }
+}
diff --git a/src/main/java/com/webmanage/common/BusinessException.java b/src/main/java/com/webmanage/common/BusinessException.java
new file mode 100644
index 0000000..8824d41
--- /dev/null
+++ b/src/main/java/com/webmanage/common/BusinessException.java
@@ -0,0 +1,40 @@
+package com.webmanage.common;
+
+/**
+ * 涓氬姟寮傚父绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+public class BusinessException extends RuntimeException {
+    
+    private Integer code;
+    
+    public BusinessException(String message) {
+        super(message);
+        this.code = 500;
+    }
+    
+    public BusinessException(Integer code, String message) {
+        super(message);
+        this.code = code;
+    }
+    
+    public BusinessException(String message, Throwable cause) {
+        super(message, cause);
+        this.code = 500;
+    }
+    
+    public BusinessException(Integer code, String message, Throwable cause) {
+        super(message, cause);
+        this.code = code;
+    }
+    
+    public Integer getCode() {
+        return code;
+    }
+    
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+}
diff --git a/src/main/java/com/webmanage/common/FileUploadException.java b/src/main/java/com/webmanage/common/FileUploadException.java
new file mode 100644
index 0000000..b9bf2b4
--- /dev/null
+++ b/src/main/java/com/webmanage/common/FileUploadException.java
@@ -0,0 +1,40 @@
+package com.webmanage.common;
+
+/**
+ * 鏂囦欢涓婁紶寮傚父绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+public class FileUploadException extends RuntimeException {
+    
+    private Integer code;
+    
+    public FileUploadException(String message) {
+        super(message);
+        this.code = 400;
+    }
+    
+    public FileUploadException(Integer code, String message) {
+        super(message);
+        this.code = code;
+    }
+    
+    public FileUploadException(String message, Throwable cause) {
+        super(message, cause);
+        this.code = 400;
+    }
+    
+    public FileUploadException(Integer code, String message, Throwable cause) {
+        super(message, cause);
+        this.code = code;
+    }
+    
+    public Integer getCode() {
+        return code;
+    }
+    
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+}
diff --git a/src/main/java/com/webmanage/common/GlobalExceptionHandler.java b/src/main/java/com/webmanage/common/GlobalExceptionHandler.java
new file mode 100644
index 0000000..b448615
--- /dev/null
+++ b/src/main/java/com/webmanage/common/GlobalExceptionHandler.java
@@ -0,0 +1,115 @@
+package com.webmanage.common;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.BindException;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.stream.Collectors;
+
+/**
+ * 鍏ㄥ眬寮傚父澶勭悊鍣�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    /**
+     * 澶勭悊鍙傛暟鏍¢獙寮傚父
+     */
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
+        String message = e.getBindingResult().getFieldErrors().stream()
+                .map(FieldError::getDefaultMessage)
+                .collect(Collectors.joining(", "));
+        log.warn("鍙傛暟鏍¢獙澶辫触: {}", message);
+        return Result.error(400, "鍙傛暟鏍¢獙澶辫触: " + message);
+    }
+
+    /**
+     * 澶勭悊缁戝畾寮傚父
+     */
+    @ExceptionHandler(BindException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleBindException(BindException e) {
+        String message = e.getBindingResult().getFieldErrors().stream()
+                .map(FieldError::getDefaultMessage)
+                .collect(Collectors.joining(", "));
+        log.warn("鍙傛暟缁戝畾澶辫触: {}", message);
+        return Result.error(400, "鍙傛暟缁戝畾澶辫触: " + message);
+    }
+
+    /**
+     * 澶勭悊绾︽潫杩濆弽寮傚父
+     */
+    @ExceptionHandler(ConstraintViolationException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleConstraintViolationException(ConstraintViolationException e) {
+        String message = e.getConstraintViolations().stream()
+                .map(ConstraintViolation::getMessage)
+                .collect(Collectors.joining(", "));
+        log.warn("绾︽潫鏍¢獙澶辫触: {}", message);
+        return Result.error(400, "绾︽潫鏍¢獙澶辫触: " + message);
+    }
+
+    /**
+     * 澶勭悊鍙傛暟绫诲瀷涓嶅尮閰嶅紓甯�
+     */
+    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
+        log.warn("鍙傛暟绫诲瀷涓嶅尮閰�: {}", e.getMessage());
+        return Result.error(400, "鍙傛暟绫诲瀷涓嶅尮閰�: " + e.getName());
+    }
+
+    /**
+     * 澶勭悊涓氬姟寮傚父
+     */
+    @ExceptionHandler(BusinessException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleBusinessException(BusinessException e) {
+        log.warn("涓氬姟寮傚父: {}", e.getMessage());
+        return Result.error(e.getCode(), e.getMessage());
+    }
+
+    /**
+     * 澶勭悊鏂囦欢涓婁紶寮傚父
+     */
+    @ExceptionHandler(FileUploadException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Result<String> handleFileUploadException(FileUploadException e) {
+        log.warn("鏂囦欢涓婁紶寮傚父: {}", e.getMessage());
+        return Result.error(e.getCode(), e.getMessage());
+    }
+
+    /**
+     * 澶勭悊閫氱敤杩愯鏃跺紓甯�
+     */
+    @ExceptionHandler(RuntimeException.class)
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    public Result<String> handleRuntimeException(RuntimeException e) {
+        log.error("杩愯鏃跺紓甯�: ", e);
+        return Result.error(500, "绯荤粺鍐呴儴閿欒: " + e.getMessage());
+    }
+
+    /**
+     * 澶勭悊閫氱敤寮傚父
+     */
+    @ExceptionHandler(Exception.class)
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    public Result<String> handleException(Exception e) {
+        log.error("绯荤粺寮傚父: ", e);
+        return Result.error(500, "绯荤粺寮傚父锛岃鑱旂郴绠$悊鍛�");
+    }
+}
diff --git a/src/main/java/com/webmanage/common/PageResult.java b/src/main/java/com/webmanage/common/PageResult.java
new file mode 100644
index 0000000..0f0a7ec
--- /dev/null
+++ b/src/main/java/com/webmanage/common/PageResult.java
@@ -0,0 +1,64 @@
+package com.webmanage.common;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 鍒嗛〉缁撴灉
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+public class PageResult<T> {
+    
+    /**
+     * 鏁版嵁鍒楄〃
+     */
+    private List<T> list;
+    
+    /**
+     * 鎬昏褰曟暟
+     */
+    private Long total;
+    
+    /**
+     * 褰撳墠椤电爜
+     */
+    private Long pageNum;
+    
+    /**
+     * 姣忛〉澶у皬
+     */
+    private Long pageSize;
+    
+    /**
+     * 鎬婚〉鏁�
+     */
+    private Long pages;
+    
+    public PageResult() {}
+    
+    public PageResult(List<T> list, Long total, Long pageNum, Long pageSize) {
+        this.list = list;
+        this.total = total;
+        this.pageNum = pageNum;
+        this.pageSize = pageSize;
+        this.pages = (total + pageSize - 1) / pageSize;
+    }
+    
+    public PageResult(List<T> list, Long total, Long pageNum, Long pageSize, Long pages) {
+        this.list = list;
+        this.total = total;
+        this.pageNum = pageNum;
+        this.pageSize = pageSize;
+        this.pages = pages;
+    }
+    
+    /**
+     * 鍒涘缓鍒嗛〉缁撴灉
+     */
+    public static <T> PageResult<T> of(List<T> list, Long total, Long pageNum, Long pageSize) {
+        return new PageResult<>(list, total, pageNum, pageSize);
+    }
+}
diff --git a/src/main/java/com/webmanage/common/Result.java b/src/main/java/com/webmanage/common/Result.java
new file mode 100644
index 0000000..04b6e66
--- /dev/null
+++ b/src/main/java/com/webmanage/common/Result.java
@@ -0,0 +1,97 @@
+package com.webmanage.common;
+
+import lombok.Data;
+
+/**
+ * 缁熶竴杩斿洖缁撴灉
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+public class Result<T> {
+    
+    /**
+     * 鐘舵�佺爜
+     */
+    private Integer code;
+    
+    /**
+     * 杩斿洖娑堟伅
+     */
+    private String msg;
+    
+    /**
+     * 杩斿洖鏁版嵁
+     */
+    private T data;
+    
+    /**
+     * 鏃堕棿鎴�
+     */
+    private Long timestamp;
+    
+    public Result() {
+        this.timestamp = System.currentTimeMillis();
+    }
+    
+    public Result(Integer code, String msg) {
+        this();
+        this.code = code;
+        this.msg = msg;
+    }
+    
+    public Result(Integer code, String msg, T data) {
+        this(code, msg);
+        this.data = data;
+    }
+    
+    /**
+     * 鎴愬姛杩斿洖
+     */
+    public static <T> Result<T> success() {
+        return new Result<>(200, "鎿嶄綔鎴愬姛");
+    }
+    
+    /**
+     * 鎴愬姛杩斿洖
+     */
+    public static <T> Result<T> success(String msg) {
+        return new Result<>(200, msg);
+    }
+    
+    /**
+     * 鎴愬姛杩斿洖
+     */
+    public static <T> Result<T> success(T data) {
+        return new Result<>(200, "鎿嶄綔鎴愬姛", data);
+    }
+    
+    /**
+     * 鎴愬姛杩斿洖
+     */
+    public static <T> Result<T> success(String msg, T data) {
+        return new Result<>(200, msg, data);
+    }
+    
+    /**
+     * 澶辫触杩斿洖
+     */
+    public static <T> Result<T> error() {
+        return new Result<>(500, "鎿嶄綔澶辫触");
+    }
+    
+    /**
+     * 澶辫触杩斿洖
+     */
+    public static <T> Result<T> error(String msg) {
+        return new Result<>(500, msg);
+    }
+    
+    /**
+     * 澶辫触杩斿洖
+     */
+    public static <T> Result<T> error(Integer code, String msg) {
+        return new Result<>(code, msg);
+    }
+}
diff --git a/src/main/java/com/webmanage/config/JacksonConfig.java b/src/main/java/com/webmanage/config/JacksonConfig.java
new file mode 100644
index 0000000..3152853
--- /dev/null
+++ b/src/main/java/com/webmanage/config/JacksonConfig.java
@@ -0,0 +1,43 @@
+package com.webmanage.config;
+
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @ClassName JacksonConfig
+ * @Description TODO
+ * @Author wangxudong
+ * @Date 2025/8/13 22:52
+ * @Version 1.0
+ **/
+@Configuration
+public class JacksonConfig {
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
+        return builder -> {
+            // Java 8鏃ユ湡鏃堕棿鏍煎紡
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+            builder.serializers(
+                    new LocalDateTimeSerializer(formatter),
+                    new LocalDateSerializer(DateTimeFormatter.ISO_DATE),
+                    new LocalTimeSerializer(DateTimeFormatter.ISO_TIME)
+            );
+
+            builder.deserializers(
+                    new LocalDateTimeDeserializer(formatter),
+                    new LocalDateDeserializer(DateTimeFormatter.ISO_DATE),
+                    new LocalTimeDeserializer(DateTimeFormatter.ISO_TIME)
+            );
+        };
+    }
+}
diff --git a/src/main/java/com/webmanage/config/MinioConfig.java b/src/main/java/com/webmanage/config/MinioConfig.java
new file mode 100644
index 0000000..29f0bdf
--- /dev/null
+++ b/src/main/java/com/webmanage/config/MinioConfig.java
@@ -0,0 +1,50 @@
+package com.webmanage.config;
+
+import io.minio.MinioClient;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * MinIO閰嶇疆绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "minio")
+public class MinioConfig {
+
+    /**
+     * MinIO鏈嶅姟鍦板潃
+     */
+    private String endpoint;
+
+    /**
+     * 璁块棶瀵嗛挜
+     */
+    private String accessKey;
+
+    /**
+     * 绉樺瘑瀵嗛挜
+     */
+    private String secretKey;
+
+    /**
+     * 榛樿瀛樺偍妗跺悕绉�
+     */
+    private String bucketName;
+
+    /**
+     * 鍒涘缓MinIO瀹㈡埛绔�
+     */
+    @Bean
+    public MinioClient minioClient() {
+        return MinioClient.builder()
+                .endpoint(endpoint)
+                .credentials(accessKey, secretKey)
+                .build();
+    }
+}
diff --git a/src/main/java/com/webmanage/config/MybatisPlusConfig.java b/src/main/java/com/webmanage/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..1b867ba
--- /dev/null
+++ b/src/main/java/com/webmanage/config/MybatisPlusConfig.java
@@ -0,0 +1,50 @@
+package com.webmanage.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+/**
+ * MyBatis Plus閰嶇疆绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+    /**
+     * 鍒嗛〉鎻掍欢
+     */
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
+        return interceptor;
+    }
+
+    /**
+     * 鑷姩濉厖澶勭悊鍣�
+     */
+    @Component
+    public static class MyMetaObjectHandler implements MetaObjectHandler {
+
+        @Override
+        public void insertFill(MetaObject metaObject) {
+            this.strictInsertFill(metaObject, "createdAt", LocalDateTime.class, LocalDateTime.now());
+            this.strictInsertFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
+        }
+
+        @Override
+        public void updateFill(MetaObject metaObject) {
+            this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/config/RedisConfig.java b/src/main/java/com/webmanage/config/RedisConfig.java
new file mode 100644
index 0000000..65383b7
--- /dev/null
+++ b/src/main/java/com/webmanage/config/RedisConfig.java
@@ -0,0 +1,47 @@
+package com.webmanage.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis閰嶇疆绫�
+ */
+@Configuration
+public class RedisConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 浣跨敤Jackson2JsonRedisSerializer鏉ュ簭鍒楀寲鍜屽弽搴忓垪鍖杛edis鐨剉alue鍊�
+        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
+
+        // 浣跨敤StringRedisSerializer鏉ュ簭鍒楀寲鍜屽弽搴忓垪鍖杛edis鐨刱ey鍊�
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+
+        // key閲囩敤String鐨勫簭鍒楀寲鏂瑰紡
+        template.setKeySerializer(stringRedisSerializer);
+        // hash鐨刱ey涔熼噰鐢⊿tring鐨勫簭鍒楀寲鏂瑰紡
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value搴忓垪鍖栨柟寮忛噰鐢╦ackson
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        // hash鐨剉alue搴忓垪鍖栨柟寮忛噰鐢╦ackson
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        template.afterPropertiesSet();
+
+        return template;
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/ApprovalController.java b/src/main/java/com/webmanage/controller/ApprovalController.java
new file mode 100644
index 0000000..69474b2
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/ApprovalController.java
@@ -0,0 +1,113 @@
+package com.webmanage.controller;
+
+import com.webmanage.common.Result;
+import com.webmanage.dto.ApprovalActionDTO;
+import com.webmanage.dto.ApprovalQueryDTO;
+import com.webmanage.entity.ApprovalRecord;
+import com.webmanage.service.ApprovalRecordService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 瀹℃壒绠$悊Controller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/approval")
+@Api(tags = "瀹℃壒绠$悊")
+@Validated
+public class ApprovalController {
+
+    @Resource
+    private ApprovalRecordService approvalRecordService;
+
+    @PostMapping("/page")
+    @ApiOperation("鍒嗛〉鏌ヨ瀹℃壒璁板綍")
+    public Result<Object> getApprovalRecordPage(@Valid @RequestBody ApprovalQueryDTO queryDTO) {
+        try {
+            return Result.success(approvalRecordService.getApprovalRecordPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ瀹℃壒璁板綍澶辫触", e);
+            return Result.error("鏌ヨ瀹℃壒璁板綍澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/pending/page")
+    @ApiOperation("鍒嗛〉鏌ヨ寰呭鎵硅鍗�")
+    public Result<Object> getPendingApprovalPage(@Valid @RequestBody ApprovalQueryDTO queryDTO) {
+        try {
+            return Result.success(approvalRecordService.getPendingApprovalPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ寰呭鎵硅鍗曞け璐�", e);
+            return Result.error("鏌ヨ寰呭鎵硅鍗曞け璐ワ細" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/order/{orderId}")
+    @ApiOperation("鏍规嵁璁㈠崟ID鏌ヨ瀹℃壒璁板綍")
+    public Result<Object> getApprovalRecordsByOrderId(@ApiParam("璁㈠崟ID") @PathVariable String orderId) {
+        try {
+            List<ApprovalRecord> records = approvalRecordService.getApprovalRecordsByOrderId(orderId);
+            return Result.success(records);
+        } catch (Exception e) {
+            log.error("鏌ヨ璁㈠崟瀹℃壒璁板綍澶辫触", e);
+            return Result.error("鏌ヨ璁㈠崟瀹℃壒璁板綍澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/approve")
+    @ApiOperation("瀹℃壒璁㈠崟")
+    public Result<Object> approveOrder(@Valid @RequestBody ApprovalActionDTO actionDTO) {
+        try {
+            boolean result = approvalRecordService.approveOrder(actionDTO);
+            if (result) {
+                return Result.success("瀹℃壒鎴愬姛");
+            } else {
+                return Result.error("瀹℃壒澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("瀹℃壒璁㈠崟澶辫触", e);
+            return Result.error("瀹℃壒璁㈠崟澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/authorize/{approvalId}")
+    @ApiOperation("鎺堟潈瀹℃壒")
+    public Result<Object> authorizeApproval(@ApiParam("瀹℃壒璁板綍ID") @PathVariable Long approvalId,
+                                          @ApiParam("鎺堟潈浜篒D") @RequestParam @NotNull Long authorizerId,
+                                          @ApiParam("鎺堟潈浜哄鍚�") @RequestParam @NotNull String authorizerName,
+                                          @ApiParam("鎺堟潈鎰忚") @RequestParam String authorizationOpinion) {
+        try {
+            boolean result = approvalRecordService.authorizeApproval(approvalId, authorizerId, authorizerName, authorizationOpinion);
+            if (result) {
+                return Result.success("鎺堟潈鎴愬姛");
+            } else {
+                return Result.error("鎺堟潈澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鎺堟潈瀹℃壒澶辫触", e);
+            return Result.error("鎺堟潈瀹℃壒澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/status/{orderId}")
+    @ApiOperation("鑾峰彇璁㈠崟褰撳墠瀹℃壒鐘舵��")
+    public Result<Object> getOrderCurrentApprovalStatus(@ApiParam("璁㈠崟ID") @PathVariable String orderId) {
+        try {
+            String status = approvalRecordService.getOrderCurrentApprovalStatus(orderId);
+            return Result.success(status);
+        } catch (Exception e) {
+            log.error("鑾峰彇璁㈠崟瀹℃壒鐘舵�佸け璐�", e);
+            return Result.error("鑾峰彇璁㈠崟瀹℃壒鐘舵�佸け璐ワ細" + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/CartController.java b/src/main/java/com/webmanage/controller/CartController.java
new file mode 100644
index 0000000..1452cfc
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/CartController.java
@@ -0,0 +1,214 @@
+package com.webmanage.controller;
+
+import com.webmanage.common.Result;
+import com.webmanage.dto.CartItemDTO;
+import com.webmanage.dto.CartQueryDTO;
+import com.webmanage.service.CartService;
+import com.webmanage.vo.CartVO;
+import com.webmanage.vo.CartItemVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 璐墿杞︾鐞咰ontroller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/cart")
+@Api(tags = "璐墿杞︾鐞�")
+@Validated
+public class CartController {
+    
+    @Resource
+    private CartService cartService;
+    
+    @PostMapping("/add")
+    @ApiOperation("娣诲姞鍟嗗搧鍒拌喘鐗╄溅")
+    public Result<Object> addToCart(@Valid @RequestBody CartItemDTO cartItemDTO,
+                                   @RequestParam @NotNull Long userId,
+                                   @RequestParam @NotNull Long unitId) {
+        try {
+            boolean result = cartService.addToCart(userId, unitId, cartItemDTO);
+            if (result) {
+                return Result.success("娣诲姞鍟嗗搧鍒拌喘鐗╄溅鎴愬姛");
+            } else {
+                return Result.error("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触", e);
+            return Result.error("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触锛�" + e.getMessage());
+        }
+    }
+    
+    @DeleteMapping("/remove")
+    @ApiOperation("浠庤喘鐗╄溅绉婚櫎鍟嗗搧")
+    public Result<Object> removeFromCart(@RequestParam @NotNull Long userId,
+                                        @RequestParam @NotNull Long unitId,
+                                        @RequestParam @NotNull Long pricingId) {
+        try {
+            boolean result = cartService.removeFromCart(userId, unitId, pricingId);
+            if (result) {
+                return Result.success("浠庤喘鐗╄溅绉婚櫎鍟嗗搧鎴愬姛");
+            } else {
+                return Result.error("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触", e);
+            return Result.error("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触锛�" + e.getMessage());
+        }
+    }
+    
+    @PutMapping("/update")
+    @ApiOperation("鏇存柊璐墿杞﹀晢鍝佹暟閲�")
+    public Result<Object> updateCartItemQuantity(@RequestParam @NotNull Long userId,
+                                               @RequestParam @NotNull Long unitId,
+                                               @RequestParam @NotNull Long pricingId,
+                                               @RequestParam @NotNull @Min(1) Integer quantity) {
+        try {
+            boolean result = cartService.updateCartItemQuantity(userId, unitId, pricingId, quantity);
+            if (result) {
+                return Result.success("鏇存柊璐墿杞﹀晢鍝佹暟閲忔垚鍔�");
+            } else {
+                return Result.error("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐�");
+            }
+        } catch (Exception e) {
+            log.error("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
+            return Result.error("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @DeleteMapping("/clear")
+    @ApiOperation("娓呯┖璐墿杞�")
+    public Result<Object> clearCart(@RequestParam @NotNull Long userId,
+                                   @RequestParam @NotNull Long unitId) {
+        try {
+            boolean result = cartService.clearCart(userId, unitId);
+            if (result) {
+                return Result.success("娓呯┖璐墿杞︽垚鍔�");
+            } else {
+                return Result.error("娓呯┖璐墿杞﹀け璐�");
+            }
+        } catch (Exception e) {
+            log.error("娓呯┖璐墿杞﹀け璐�", e);
+            return Result.error("娓呯┖璐墿杞﹀け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @GetMapping("/info")
+    @ApiOperation("鑾峰彇璐墿杞︿俊鎭�")
+    public Result<Object> getCart(@RequestParam @NotNull Long userId,
+                                 @RequestParam @NotNull Long unitId) {
+        try {
+            CartVO cart = cartService.getCart(userId, unitId);
+            return Result.success(cart);
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞︿俊鎭け璐�", e);
+            return Result.error("鑾峰彇璐墿杞︿俊鎭け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @GetMapping("/items")
+    @ApiOperation("鑾峰彇璐墿杞﹀晢鍝佸垪琛�")
+    public Result<Object> getCartItems(@RequestParam @NotNull Long userId,
+                                      @RequestParam @NotNull Long unitId) {
+        try {
+            List<CartItemVO> items = cartService.getCartItems(userId, unitId);
+            return Result.success(items);
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
+            return Result.error("鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @DeleteMapping("/batch-remove")
+    @ApiOperation("鎵归噺鍒犻櫎璐墿杞﹀晢鍝�")
+    public Result<Object> batchRemoveFromCart(@RequestParam @NotNull Long userId,
+                                             @RequestParam @NotNull Long unitId,
+                                             @RequestBody List<Long> pricingIds) {
+        try {
+            boolean result = cartService.batchRemoveFromCart(userId, unitId, pricingIds);
+            if (result) {
+                return Result.success("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佹垚鍔�");
+            } else {
+                return Result.error("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐�");
+            }
+        } catch (Exception e) {
+            log.error("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐�", e);
+            return Result.error("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @GetMapping("/count")
+    @ApiOperation("鑾峰彇璐墿杞﹀晢鍝佹暟閲�")
+    public Result<Object> getCartItemCount(@RequestParam @NotNull Long userId,
+                                          @RequestParam @NotNull Long unitId) {
+        try {
+            Integer count = cartService.getCartItemCount(userId, unitId);
+            return Result.success(count);
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
+            return Result.error("鑾峰彇璐墿杞﹀晢鍝佹暟閲忓け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @PostMapping("/sync-to-db")
+    @ApiOperation("鍚屾Redis璐墿杞︽暟鎹埌鏁版嵁搴�")
+    public Result<Object> syncCartToDatabase(@RequestParam @NotNull Long userId,
+                                            @RequestParam @NotNull Long unitId) {
+        try {
+            boolean result = cartService.syncCartToDatabase(userId, unitId);
+            if (result) {
+                return Result.success("鍚屾璐墿杞︽暟鎹埌鏁版嵁搴撴垚鍔�");
+            } else {
+                return Result.error("鍚屾璐墿杞︽暟鎹埌鏁版嵁搴撳け璐�");
+            }
+        } catch (Exception e) {
+            log.error("鍚屾璐墿杞︽暟鎹埌鏁版嵁搴撳け璐�", e);
+            return Result.error("鍚屾璐墿杞︽暟鎹埌鏁版嵁搴撳け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @PostMapping("/load-from-db")
+    @ApiOperation("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹埌Redis")
+    public Result<Object> loadCartFromDatabase(@RequestParam @NotNull Long userId,
+                                              @RequestParam @NotNull Long unitId) {
+        try {
+            boolean result = cartService.loadCartFromDatabase(userId, unitId);
+            if (result) {
+                return Result.success("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹垚鍔�");
+            } else {
+                return Result.error("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹け璐�");
+            }
+        } catch (Exception e) {
+            log.error("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹け璐�", e);
+            return Result.error("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @GetMapping("/consistency")
+    @ApiOperation("妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存��")
+    public Result<Object> checkCartConsistency(@RequestParam @NotNull Long userId,
+                                              @RequestParam @NotNull Long unitId) {
+        try {
+            boolean isConsistent = cartService.checkCartConsistency(userId, unitId);
+            if (isConsistent) {
+                return Result.success("璐墿杞︽暟鎹竴鑷�");
+            } else {
+                return Result.error("璐墿杞︽暟鎹笉涓�鑷�");
+            }
+        } catch (Exception e) {
+            log.error("妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存�уけ璐�", e);
+            return Result.error("妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存�уけ璐ワ細" + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/FileController.java b/src/main/java/com/webmanage/controller/FileController.java
new file mode 100644
index 0000000..c3d3292
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/FileController.java
@@ -0,0 +1,156 @@
+package com.webmanage.controller;
+
+import com.webmanage.common.Result;
+import com.webmanage.service.MinioService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鏂囦欢涓婁紶涓嬭浇鎺у埗鍣�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Slf4j
+@RestController
+@RequestMapping("/file")
+@Api(tags = "鏂囦欢绠$悊")
+public class FileController {
+
+    @Autowired
+    private MinioService minioService;
+
+    /**
+     * 涓婁紶鏂囦欢
+     */
+    @PostMapping("/upload")
+    @ApiOperation("涓婁紶鏂囦欢")
+    public Result<String> uploadFile(
+            @ApiParam("鏂囦欢") @RequestParam("file") MultipartFile file,
+            @ApiParam("鏂囦欢澶�") @RequestParam(defaultValue = "common") String folder) {
+        try {
+            if (file.isEmpty()) {
+                return Result.error("鏂囦欢涓嶈兘涓虹┖");
+            }
+            
+            // 妫�鏌ユ枃浠跺ぇ灏忥紙闄愬埗涓�100MB锛�
+            if (file.getSize() > 100 * 1024 * 1024) {
+                return Result.error("鏂囦欢澶у皬涓嶈兘瓒呰繃100MB");
+            }
+            
+            String fileName = minioService.uploadFile(file, folder);
+            return Result.success("鏂囦欢涓婁紶鎴愬姛", fileName);
+        } catch (Exception e) {
+            log.error("鏂囦欢涓婁紶澶辫触: ", e);
+            return Result.error("鏂囦欢涓婁紶澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 涓嬭浇鏂囦欢
+     */
+    @GetMapping("/download/{fileName}")
+    @ApiOperation("涓嬭浇鏂囦欢")
+    public ResponseEntity<InputStreamResource> downloadFile(
+            @ApiParam("鏂囦欢鍚�") @PathVariable String fileName,
+            @ApiParam("鍘熷鏂囦欢鍚�") @RequestParam(required = false) String originalName) {
+        try {
+            InputStream inputStream = minioService.downloadFile(fileName);
+            
+            // 濡傛灉娌℃湁鎻愪緵鍘熷鏂囦欢鍚嶏紝浠庤矾寰勪腑鎻愬彇
+            if (originalName == null || originalName.isEmpty()) {
+                String[] parts = fileName.split("/");
+                originalName = parts[parts.length - 1];
+            }
+            
+            // 璁剧疆鍝嶅簲澶�
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+            headers.setContentDispositionFormData("attachment", 
+                    URLEncoder.encode(originalName, StandardCharsets.UTF_8.toString()));
+            
+            InputStreamResource resource = new InputStreamResource(inputStream);
+            
+            return ResponseEntity.ok()
+                    .headers(headers)
+                    .body(resource);
+        } catch (Exception e) {
+            log.error("鏂囦欢涓嬭浇澶辫触: ", e);
+            return ResponseEntity.notFound().build();
+        }
+    }
+
+    /**
+     * 鑾峰彇鏂囦欢棰勮URL
+     */
+    @GetMapping("/preview/{fileName}")
+    @ApiOperation("鑾峰彇鏂囦欢棰勮URL")
+    public Result<String> getPreviewUrl(@ApiParam("鏂囦欢鍚�") @PathVariable String fileName) {
+        try {
+            String previewUrl = minioService.getPreviewUrl(fileName);
+            return Result.success("鑾峰彇棰勮URL鎴愬姛", previewUrl);
+        } catch (Exception e) {
+            log.error("鑾峰彇棰勮URL澶辫触: ", e);
+            return Result.error("鑾峰彇棰勮URL澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰彇鏂囦欢涓嬭浇URL
+     */
+    @GetMapping("/download-url/{fileName}")
+    @ApiOperation("鑾峰彇鏂囦欢涓嬭浇URL")
+    public Result<String> getDownloadUrl(@ApiParam("鏂囦欢鍚�") @PathVariable String fileName) {
+        try {
+            String downloadUrl = minioService.getDownloadUrl(fileName);
+            return Result.success("鑾峰彇涓嬭浇URL鎴愬姛", downloadUrl);
+        } catch (Exception e) {
+            log.error("鑾峰彇涓嬭浇URL澶辫触: ", e);
+            return Result.error("鑾峰彇涓嬭浇URL澶辫触: " + e.getMessage());
+        }
+    }
+ 
+    /**
+     * 鍒犻櫎鏂囦欢
+     */
+    @DeleteMapping("/delete/{fileName}")
+    @ApiOperation("鍒犻櫎鏂囦欢")
+    public Result<Boolean> deleteFile(@ApiParam("鏂囦欢鍚�") @PathVariable String fileName) {
+        try {
+            minioService.deleteFile(fileName);
+            return Result.success("鏂囦欢鍒犻櫎鎴愬姛", true);
+        } catch (Exception e) {
+            log.error("鏂囦欢鍒犻櫎澶辫触: ", e);
+            return Result.error("鏂囦欢鍒犻櫎澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+     */
+    @GetMapping("/exists/{fileName}")
+    @ApiOperation("妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�")
+    public Result<Boolean> fileExists(@ApiParam("鏂囦欢鍚�") @PathVariable String fileName) {
+        try {
+            boolean exists = minioService.fileExists(fileName);
+            return Result.success("妫�鏌ュ畬鎴�", exists);
+        } catch (Exception e) {
+            log.error("妫�鏌ユ枃浠舵槸鍚﹀瓨鍦ㄥけ璐�: ", e);
+            return Result.error("妫�鏌ユ枃浠舵槸鍚﹀瓨鍦ㄥけ璐�: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/OrderController.java b/src/main/java/com/webmanage/controller/OrderController.java
new file mode 100644
index 0000000..6680838
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/OrderController.java
@@ -0,0 +1,182 @@
+package com.webmanage.controller;
+
+import com.webmanage.common.Result;
+import com.webmanage.dto.CreateOrderDTO;
+import com.webmanage.dto.OrderQueryDTO;
+import com.webmanage.service.OrderInfoService;
+import com.webmanage.service.OrderNoService;
+import com.webmanage.vo.OrderDetailVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 璁㈠崟绠$悊Controller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/order")
+@Api(tags = "璁㈠崟绠$悊")
+@Validated
+public class OrderController {
+    @Resource private OrderInfoService orderInfoService;
+    @Resource private OrderNoService orderNoService;
+
+    @PostMapping("/buyer/page")
+    @ApiOperation("鍒嗛〉鏌ヨ涔板璁㈠崟鍒楄〃")
+    public Result<Object> getBuyerOrderPage(@Valid @RequestBody OrderQueryDTO queryDTO) {
+        try { return Result.success(orderInfoService.getBuyerOrderPage(queryDTO)); }
+        catch (Exception e) { log.error("鏌ヨ涔板璁㈠崟鍒楄〃澶辫触", e); return Result.error("鏌ヨ涔板璁㈠崟鍒楄〃澶辫触锛�" + e.getMessage()); }
+    }
+
+    @PostMapping("/create")
+    @ApiOperation("鍒涘缓璁㈠崟锛堝寘鍚鍗曡鎯咃級")
+    public Result<Object> createOrder(@Valid @RequestBody CreateOrderDTO createOrderDTO) {
+        try {
+            String orderId = orderInfoService.createOrder(createOrderDTO);
+            return Result.success(orderId);
+        } catch (Exception e) {
+            log.error("鍒涘缓璁㈠崟澶辫触", e);
+            return Result.error("鍒涘缓璁㈠崟澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/no/new")
+    @ApiOperation("鐢熸垚鍞竴璁㈠崟鍙�")
+    public Result<Object> generateOrderNo() {
+        try {
+            String orderNo = orderNoService.generateOrderNo();
+            return Result.success(orderNo);
+        } catch (Exception e) {
+            log.error("鐢熸垚璁㈠崟鍙峰け璐�", e);
+            return Result.error("鐢熸垚璁㈠崟鍙峰け璐ワ細" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/seller/page")
+    @ApiOperation("鍒嗛〉鏌ヨ鍗栧璁㈠崟鍒楄〃")
+    public Result<Object> getSellerOrderPage(@Valid @RequestBody OrderQueryDTO queryDTO) {
+        try {
+            if (queryDTO.getProviderId() == null) {
+                return Result.error("鎻愪緵鑰匢D涓嶈兘涓虹┖");
+            }
+            return Result.success(orderInfoService.getSellerOrderPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ鍗栧璁㈠崟鍒楄〃澶辫触", e);
+            return Result.error("鏌ヨ鍗栧璁㈠崟鍒楄〃澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/approval/page")
+    @ApiOperation("鍒嗛〉鏌ヨ寰呭鎵硅鍗曞垪琛�")
+    public Result<Object> getPendingApprovalOrderPage(@Valid @RequestBody OrderQueryDTO queryDTO) {
+        try {
+            return Result.success(orderInfoService.getPendingApprovalOrderPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ寰呭鎵硅鍗曞垪琛ㄥけ璐�", e);
+            return Result.error("鏌ヨ寰呭鎵硅鍗曞垪琛ㄥけ璐ワ細" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/detail/{orderId}")
+    @ApiOperation("鑾峰彇璁㈠崟璇︽儏")
+    public Result<OrderDetailVO> getOrderDetail(
+            @ApiParam("璁㈠崟ID") @PathVariable @NotBlank String orderId) {
+        try {
+            OrderDetailVO orderDetail = orderInfoService.getOrderDetail(orderId);
+            return Result.success(orderDetail);
+        } catch (Exception e) {
+            log.error("鑾峰彇璁㈠崟璇︽儏澶辫触锛岃鍗旾D: {}", orderId, e);
+            return Result.error("鑾峰彇璁㈠崟璇︽儏澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/attachment/upload")
+    @ApiOperation("涓婁紶璁㈠崟闄勪欢")
+    public Result<Boolean> uploadOrderAttachment(
+            @ApiParam("璁㈠崟ID") @RequestParam @NotBlank String orderId,
+            @ApiParam("鏂囦欢鍚�") @RequestParam @NotBlank String fileName,
+            @ApiParam("鍘熷鏂囦欢鍚�") @RequestParam String originalName,
+            @ApiParam("闄勪欢绫诲瀷") @RequestParam @NotBlank String fileType,
+            @ApiParam("闄勪欢澶у皬") @RequestParam @NotNull Long fileSize,
+            @ApiParam("闄勪欢鍦板潃") @RequestParam @NotBlank String fileUrl,
+            @ApiParam("瀛樺偍妗跺悕绉�") @RequestParam String bucketName,
+            @ApiParam("瀵硅薄鍚嶇О") @RequestParam String objectName,
+            @ApiParam("涓婁紶鐢ㄦ埛ID") @RequestParam @NotNull Long uploadUserId,
+            @ApiParam("涓婁紶鐢ㄦ埛鍚�") @RequestParam @NotBlank String uploadUserName,
+            @ApiParam("闄勪欢绫诲瀷") @RequestParam String attachmentType,
+            @ApiParam("闄勪欢鎻忚堪") @RequestParam String description) {
+        try {
+            boolean result = orderInfoService.uploadOrderAttachment(
+                orderId, fileName, originalName, fileType, fileSize, fileUrl,
+                bucketName, objectName, uploadUserId, uploadUserName, attachmentType, description
+            );
+            return result ? Result.success(true) : Result.error("涓婁紶璁㈠崟闄勪欢澶辫触");
+        } catch (Exception e) {
+            log.error("涓婁紶璁㈠崟闄勪欢澶辫触锛岃鍗旾D: {}", orderId, e);
+            return Result.error("涓婁紶璁㈠崟闄勪欢澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/evaluation/add")
+    @ApiOperation("娣诲姞璁㈠崟璇勪环")
+    public Result<Boolean> addOrderEvaluation(
+            @ApiParam("璁㈠崟ID") @RequestParam @NotBlank String orderId,
+            @ApiParam("璇勪环浜篒D") @RequestParam @NotNull Long evaluatorId,
+            @ApiParam("璇勪环浜哄鍚�") @RequestParam @NotBlank String evaluatorName,
+            @ApiParam("璇勪环浜虹被鍨�") @RequestParam @NotBlank String evaluatorType,
+            @ApiParam("璇勪环鍐呭") @RequestParam @NotBlank String content,
+            @ApiParam("璇勫垎") @RequestParam @NotNull Integer rating,
+            @ApiParam("鏈嶅姟璇勫垎") @RequestParam Integer serviceRating,
+            @ApiParam("璐ㄩ噺璇勫垎") @RequestParam Integer qualityRating,
+            @ApiParam("浜や粯璇勫垎") @RequestParam Integer deliveryRating,
+            @ApiParam("鏄惁鍖垮悕") @RequestParam Boolean isAnonymous) {
+        try {
+            boolean result = orderInfoService.addOrderEvaluation(
+                orderId, evaluatorId, evaluatorName, evaluatorType, content, rating,
+                serviceRating, qualityRating, deliveryRating, isAnonymous
+            );
+            return result ? Result.success(true) : Result.error("娣诲姞璁㈠崟璇勪环澶辫触");
+        } catch (Exception e) {
+            log.error("娣诲姞璁㈠崟璇勪环澶辫触锛岃鍗旾D: {}", orderId, e);
+            return Result.error("娣诲姞璁㈠崟璇勪环澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/transaction/confirm")
+    @ApiOperation("浜ゆ槗纭")
+    public Result<Boolean> confirmTransaction(
+            @ApiParam("璁㈠崟ID") @RequestParam @NotBlank String orderId,
+            @ApiParam("鐢ㄦ埛ID") @RequestParam @NotNull Long userId) {
+        try {
+            boolean result = orderInfoService.confirmTransaction(orderId, userId);
+            return result ? Result.success(true) : Result.error("浜ゆ槗纭澶辫触");
+        } catch (Exception e) {
+            log.error("浜ゆ槗纭澶辫触锛岃鍗旾D: {}", orderId, e);
+            return Result.error("浜ゆ槗纭澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/evaluation/reply")
+    @ApiOperation("鍥炲璇勪环")
+    public Result<Boolean> replyEvaluation(
+            @ApiParam("璇勪环ID") @RequestParam @NotNull Long evaluationId,
+            @ApiParam("鍥炲鍐呭") @RequestParam @NotBlank String replyContent,
+            @ApiParam("鍥炲鐢ㄦ埛ID") @RequestParam @NotNull Long replyUserId) {
+        try {
+            boolean result = orderInfoService.replyEvaluation(evaluationId, replyContent, replyUserId);
+            return result ? Result.success(true) : Result.error("鍥炲璇勪环澶辫触");
+        } catch (Exception e) {
+            log.error("鍥炲璇勪环澶辫触锛岃瘎浠稩D: {}", evaluationId, e);
+            return Result.error("鍥炲璇勪环澶辫触锛�" + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/PointsController.java b/src/main/java/com/webmanage/controller/PointsController.java
new file mode 100644
index 0000000..b4e0ba5
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/PointsController.java
@@ -0,0 +1,275 @@
+package com.webmanage.controller;
+
+import com.webmanage.common.Result;
+import com.webmanage.dto.AddPointsFlowDTO;
+import com.webmanage.dto.PointsFlowQueryDTO;
+import com.webmanage.dto.PointsMainQueryDTO;
+import com.webmanage.dto.PointsRuleDTO;
+import com.webmanage.entity.Points;
+import com.webmanage.entity.PointsRule;
+import com.webmanage.service.PointsFlowService;
+import com.webmanage.service.PointsRuleService;
+import com.webmanage.service.PointsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import com.webmanage.entity.PointsFlow;
+
+/**
+ * 绉垎绠$悊Controller
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/points")
+@Api(tags = "绉垎绠$悊")
+@Validated
+public class PointsController {
+
+    @Resource
+    private PointsRuleService pointsRuleService;
+
+    @Resource
+    private PointsFlowService pointsFlowService;
+
+    @Resource
+    private PointsService pointsService;
+
+    // ==================== 绉垎涓昏〃绠$悊 ====================
+
+    @PostMapping("/main/page")
+    @ApiOperation("鍒嗛〉鏌ヨ绉垎涓昏〃")
+    public Result<Object> getPointsMainPage(@Valid @RequestBody PointsMainQueryDTO queryDTO) {
+        try {
+            return Result.success(pointsService.getPointsMainPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ绉垎涓昏〃澶辫触", e);
+            return Result.error("鏌ヨ绉垎涓昏〃澶辫触锛�" + e.getMessage());
+        }
+    }
+
+
+    // ==================== 绉垎瑙勫垯绠$悊 ====================
+
+    @PostMapping("/rule/page")
+    @ApiOperation("鍒嗛〉鏌ヨ绉垎瑙勫垯")
+    public Result<Object> getPointsRulePage(@RequestParam(defaultValue = "1") Integer pageNum,
+                                          @RequestParam(defaultValue = "10") Integer pageSize,
+                                          @RequestParam(required = false) String ruleName,
+                                          @RequestParam(required = false) String ruleType) {
+        try {
+            return Result.success(pointsRuleService.getPointsRulePage(pageNum, pageSize, ruleName, ruleType));
+        } catch (Exception e) {
+            log.error("鏌ヨ绉垎瑙勫垯澶辫触", e);
+            return Result.error("鏌ヨ绉垎瑙勫垯澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/rule/add")
+    @ApiOperation("鏂板绉垎瑙勫垯")
+    public Result<Object> addPointsRule(@Valid @RequestBody PointsRuleDTO pointsRuleDTO) {
+        try {
+            boolean result = pointsRuleService.addPointsRule(pointsRuleDTO);
+            if (result) {
+                return Result.success("鏂板绉垎瑙勫垯鎴愬姛");
+            } else {
+                return Result.error("鏂板绉垎瑙勫垯澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鏂板绉垎瑙勫垯澶辫触", e);
+            return Result.error("鏂板绉垎瑙勫垯澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/rule/update")
+    @ApiOperation("淇敼绉垎瑙勫垯")
+    public Result<Object> updatePointsRule(@Valid @RequestBody PointsRuleDTO pointsRuleDTO) {
+        try {
+            boolean result = pointsRuleService.updatePointsRule(pointsRuleDTO);
+            if (result) {
+                return Result.success("淇敼绉垎瑙勫垯鎴愬姛");
+            } else {
+                return Result.error("淇敼绉垎瑙勫垯澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("淇敼绉垎瑙勫垯澶辫触", e);
+            return Result.error("淇敼绉垎瑙勫垯澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @DeleteMapping("/rule/{id}")
+    @ApiOperation("鍒犻櫎绉垎瑙勫垯")
+    public Result<Object> deletePointsRule(@ApiParam("瑙勫垯ID") @PathVariable Long id) {
+        try {
+            boolean result = pointsRuleService.deletePointsRule(id);
+            if (result) {
+                return Result.success("鍒犻櫎绉垎瑙勫垯鎴愬姛");
+            } else {
+                return Result.error("鍒犻櫎绉垎瑙勫垯澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鍒犻櫎绉垎瑙勫垯澶辫触", e);
+            return Result.error("鍒犻櫎绉垎瑙勫垯澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/rule/toggle/{id}")
+    @ApiOperation("鍚敤/绂佺敤绉垎瑙勫垯")
+    public Result<Object> togglePointsRuleStatus(@ApiParam("瑙勫垯ID") @PathVariable Long id,
+                                               @ApiParam("鏄惁鍚敤") @RequestParam @NotNull Boolean isEnabled) {
+        try {
+            boolean result = pointsRuleService.togglePointsRuleStatus(id, isEnabled);
+            if (result) {
+                return Result.success("鎿嶄綔鎴愬姛");
+            } else {
+                return Result.error("鎿嶄綔澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鎿嶄綔绉垎瑙勫垯鐘舵�佸け璐�", e);
+            return Result.error("鎿嶄綔绉垎瑙勫垯鐘舵�佸け璐ワ細" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/rule/type/{ruleType}")
+    @ApiOperation("鏍规嵁瑙勫垯绫诲瀷鏌ヨ鍚敤鐨勮鍒�")
+    public Result<Object> getEnabledRulesByType(@ApiParam("瑙勫垯绫诲瀷") @PathVariable String ruleType) {
+        try {
+            List<PointsRule> rules = pointsRuleService.getEnabledRulesByType(ruleType);
+            return Result.success(rules);
+        } catch (Exception e) {
+            log.error("鏌ヨ绉垎瑙勫垯澶辫触", e);
+            return Result.error("鏌ヨ绉垎瑙勫垯澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    // ==================== 绉垎娴佹按鏌ヨ ====================
+
+    @PostMapping("/flow/personal/page")
+    @ApiOperation("鍒嗛〉鏌ヨ涓汉绉垎娴佹按")
+    public Result<Object> getPersonalPointsFlowPage(@Valid @RequestBody PointsFlowQueryDTO queryDTO) {
+        try {
+            return Result.success(pointsFlowService.getPersonalPointsFlowPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ涓汉绉垎娴佹按澶辫触", e);
+            return Result.error("鏌ヨ涓汉绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/flow/unit/page")
+    @ApiOperation("鍒嗛〉鏌ヨ鍗曚綅绉垎娴佹按")
+    public Result<Object> getUnitPointsFlowPage(@Valid @RequestBody PointsFlowQueryDTO queryDTO) {
+        try {
+            return Result.success(pointsFlowService.getUnitPointsFlowPage(queryDTO));
+        } catch (Exception e) {
+            log.error("鏌ヨ鍗曚綅绉垎娴佹按澶辫触", e);
+            return Result.error("鏌ヨ鍗曚綅绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/flow/user/{userId}")
+    @ApiOperation("鏍规嵁鐢ㄦ埛ID鏌ヨ绉垎娴佹按")
+    public Result<Object> getPointsFlowByUserId(@ApiParam("鐢ㄦ埛ID") @PathVariable Long userId) {
+        try {
+            List<PointsFlow> flows = pointsFlowService.getPointsFlowByUserId(userId);
+            return Result.success(flows);
+        } catch (Exception e) {
+            log.error("鏌ヨ鐢ㄦ埛绉垎娴佹按澶辫触", e);
+            return Result.error("鏌ヨ鐢ㄦ埛绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/flow/unit/{unitId}")
+    @ApiOperation("鏍规嵁鍗曚綅ID鏌ヨ绉垎娴佹按")
+    public Result<Object> getPointsFlowByUnitId(@ApiParam("鍗曚綅ID") @PathVariable Long unitId) {
+        try {
+            List<PointsFlow> flows = pointsFlowService.getPointsFlowByUnitId(unitId);
+            return Result.success(flows);
+        } catch (Exception e) {
+            log.error("鏌ヨ鍗曚綅绉垎娴佹按澶辫触", e);
+            return Result.error("鏌ヨ鍗曚綅绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    // ==================== 鏂板绉垎娴佹按 ====================
+
+    @PostMapping("/flow/add")
+    @ApiOperation("鏂板绉垎娴佹按锛堟牴鎹鍒欒嚜鍔ㄨ绠楋級")
+    public Result<Object> addPointsFlow(@Valid @RequestBody AddPointsFlowDTO addPointsFlowDTO) {
+        try {
+            boolean result = pointsFlowService.addPointsFlowByRule(addPointsFlowDTO);
+            if (result) {
+                return Result.success("鏂板绉垎娴佹按鎴愬姛");
+            } else {
+                return Result.error("鏂板绉垎娴佹按澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鏂板绉垎娴佹按澶辫触", e);
+            return Result.error("鏂板绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/flow/add/personal")
+    @ApiOperation("鏂板涓汉绉垎娴佹按")
+    public Result<Object> addPersonalPointsFlow(@Valid @RequestBody AddPointsFlowDTO addPointsFlowDTO) {
+        try {
+            boolean result = pointsFlowService.addPointsFlowByRule(addPointsFlowDTO);
+            if (result) {
+                return Result.success("鏂板涓汉绉垎娴佹按鎴愬姛");
+            } else {
+                return Result.error("鏂板涓汉绉垎娴佹按澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鏂板涓汉绉垎娴佹按澶辫触", e);
+            return Result.error("鏂板涓汉绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/flow/add/unit")
+    @ApiOperation("鏂板鍗曚綅绉垎娴佹按")
+    public Result<Object> addUnitPointsFlow(@Valid @RequestBody AddPointsFlowDTO addPointsFlowDTO) {
+        try {
+            boolean result = pointsFlowService.addPointsFlowByRule(addPointsFlowDTO);
+            if (result) {
+                return Result.success("鏂板鍗曚綅绉垎娴佹按鎴愬姛");
+            } else {
+                return Result.error("鏂板鍗曚綅绉垎娴佹按澶辫触");
+            }
+        } catch (Exception e) {
+            log.error("鏂板鍗曚綅绉垎娴佹按澶辫触", e);
+            return Result.error("鏂板鍗曚綅绉垎娴佹按澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    // ==================== 绉垎缁熻 ====================
+
+    @GetMapping("/total/user/{userId}")
+    @ApiOperation("鑾峰彇鐢ㄦ埛绉垎缁熻")
+    public Result<Object> getUserPointsTotal(@ApiParam("鐢ㄦ埛ID") @PathVariable Long userId) {
+        try {
+            Integer total = pointsFlowService.getUserPointsTotal(userId);
+            return Result.success(total);
+        } catch (Exception e) {
+            log.error("鑾峰彇鐢ㄦ埛绉垎缁熻澶辫触", e);
+            return Result.error("鑾峰彇鐢ㄦ埛绉垎缁熻澶辫触锛�" + e.getMessage());
+        }
+    }
+
+    @GetMapping("/total/unit/{unitId}")
+    @ApiOperation("鑾峰彇鍗曚綅绉垎缁熻")
+    public Result<Object> getUnitPointsTotal(@ApiParam("鍗曚綅ID") @PathVariable Long unitId) {
+        try {
+            Integer total = pointsFlowService.getUnitPointsTotal(unitId);
+            return Result.success(total);
+        } catch (Exception e) {
+            log.error("鑾峰彇鍗曚綅绉垎缁熻澶辫触", e);
+            return Result.error("鑾峰彇鍗曚綅绉垎缁熻澶辫触锛�" + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/controller/ProductPricingController.java b/src/main/java/com/webmanage/controller/ProductPricingController.java
new file mode 100644
index 0000000..1ca6f19
--- /dev/null
+++ b/src/main/java/com/webmanage/controller/ProductPricingController.java
@@ -0,0 +1,164 @@
+package com.webmanage.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.common.Result;
+import com.webmanage.entity.ProductPricing;
+import com.webmanage.service.ProductPricingService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 浜у搧瀹氫环绠$悊鎺у埗鍣�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Slf4j
+@RestController
+@RequestMapping("/product-pricing")
+@Api(tags = "浜у搧瀹氫环绠$悊")
+@Validated
+public class ProductPricingController {
+
+    @Autowired
+    private ProductPricingService productPricingService;
+
+    /**
+     * 鏂板浜у搧瀹氫环
+     */
+    @PostMapping("/add")
+    @ApiOperation("鏂板浜у搧瀹氫环")
+    public Result<Boolean> addProductPricing(@Valid @RequestBody ProductPricing productPricing) {
+        try {
+            boolean result = productPricingService.addProductPricing(productPricing);
+            return result ? Result.success("鏂板浜у搧瀹氫环鎴愬姛", true) : Result.error("鏂板浜у搧瀹氫环澶辫触");
+        } catch (Exception e) {
+            log.error("鏂板浜у搧瀹氫环澶辫触: ", e);
+            return Result.error("鏂板浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 缂栬緫浜у搧瀹氫环
+     */
+    @PutMapping("/update")
+    @ApiOperation("缂栬緫浜у搧瀹氫环")
+    public Result<Boolean> updateProductPricing(@Valid @RequestBody ProductPricing productPricing) {
+        try {
+            if (productPricing.getId() == null) {
+                return Result.error("浜у搧瀹氫环ID涓嶈兘涓虹┖");
+            }
+            boolean result = productPricingService.updateProductPricing(productPricing);
+            return result ? Result.success("缂栬緫浜у搧瀹氫环鎴愬姛", true) : Result.error("缂栬緫浜у搧瀹氫环澶辫触");
+        } catch (Exception e) {
+            log.error("缂栬緫浜у搧瀹氫环澶辫触: ", e);
+            return Result.error("缂栬緫浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鍒犻櫎浜у搧瀹氫环锛堥�昏緫鍒犻櫎锛�
+     */
+    @DeleteMapping("/delete/{id}")
+    @ApiOperation("鍒犻櫎浜у搧瀹氫环")
+    public Result<Boolean> deleteProductPricing(@ApiParam("浜у搧瀹氫环ID") @PathVariable Long id) {
+        try {
+            if (id == null) {
+                return Result.error("浜у搧瀹氫环ID涓嶈兘涓虹┖");
+            }
+            boolean result = productPricingService.deleteProductPricing(id);
+            return result ? Result.success("鍒犻櫎浜у搧瀹氫环鎴愬姛", true) : Result.error("鍒犻櫎浜у搧瀹氫环澶辫触");
+        } catch (Exception e) {
+            log.error("鍒犻櫎浜у搧瀹氫环澶辫触: ", e);
+            return Result.error("鍒犻櫎浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鍒嗛〉鏌ヨ浜у搧瀹氫环鍒楄〃
+     */
+    @GetMapping("/page")
+    @ApiOperation("鍒嗛〉鏌ヨ浜у搧瀹氫环鍒楄〃")
+    public Result<IPage<ProductPricing>> getProductPricingPage(
+            @ApiParam("椤电爜") @RequestParam(defaultValue = "1") Long pageNum,
+            @ApiParam("姣忛〉澶у皬") @RequestParam(defaultValue = "10") Long pageSize,
+            @ApiParam("浜у搧ID") @RequestParam(required = false) Long productId) {
+        try {
+            Page<ProductPricing> page = new Page<>(pageNum, pageSize);
+            IPage<ProductPricing> result = productPricingService.getProductPricingPage(page, productId);
+            return Result.success("鏌ヨ鎴愬姛", result);
+        } catch (Exception e) {
+            log.error("鍒嗛〉鏌ヨ浜у搧瀹氫环澶辫触: ", e);
+            return Result.error("鍒嗛〉鏌ヨ浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鏍规嵁浜у搧ID鏌ヨ瀹氫环鍒楄〃
+     */
+    @GetMapping("/product/{productId}")
+    @ApiOperation("鏍规嵁浜у搧ID鏌ヨ瀹氫环鍒楄〃")
+    public Result<List<ProductPricing>> getPricingByProductId(@ApiParam("浜у搧ID") @PathVariable Long productId) {
+        try {
+            if (productId == null) {
+                return Result.error("浜у搧ID涓嶈兘涓虹┖");
+            }
+            List<ProductPricing> result = productPricingService.getPricingByProductId(productId);
+            return Result.success("鏌ヨ鎴愬姛", result);
+        } catch (Exception e) {
+            log.error("鏍规嵁浜у搧ID鏌ヨ瀹氫环澶辫触: ", e);
+            return Result.error("鏍规嵁浜у搧ID鏌ヨ瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环
+     */
+    @GetMapping("/condition")
+    @ApiOperation("鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环")
+    public Result<List<ProductPricing>> getPricingByCondition(
+            @ApiParam("濂椾欢鍚嶇О") @RequestParam(required = false) String suiteName,
+            @ApiParam("閿�鍞舰寮�") @RequestParam(required = false) String salesForm,
+            @ApiParam("瀹㈡埛瀵硅薄") @RequestParam(required = false) String customerType,
+            @ApiParam("浠锋牸绫诲瀷") @RequestParam(required = false) String priceType,
+            @ApiParam("鍚敤鐘舵��") @RequestParam(required = false) Boolean isActive) {
+        try {
+            List<ProductPricing> result = productPricingService.getPricingByCondition(
+                    suiteName, salesForm, customerType, priceType, isActive);
+            return Result.success("鏌ヨ鎴愬姛", result);
+        } catch (Exception e) {
+            log.error("鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环澶辫触: ", e);
+            return Result.error("鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰彇浜у搧瀹氫环璇︽儏
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation("鑾峰彇浜у搧瀹氫环璇︽儏")
+    public Result<ProductPricing> getProductPricingDetail(@ApiParam("浜у搧瀹氫环ID") @PathVariable Long id) {
+        try {
+            if (id == null) {
+                return Result.error("浜у搧瀹氫环ID涓嶈兘涓虹┖");
+            }
+            ProductPricing result = productPricingService.getById(id);
+            if (result == null) {
+                return Result.error("浜у搧瀹氫环涓嶅瓨鍦�");
+            }
+            return Result.success("鏌ヨ鎴愬姛", result);
+        } catch (Exception e) {
+            log.error("鑾峰彇浜у搧瀹氫环璇︽儏澶辫触: ", e);
+            return Result.error("鑾峰彇浜у搧瀹氫环璇︽儏澶辫触: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/dto/AddPointsFlowDTO.java b/src/main/java/com/webmanage/dto/AddPointsFlowDTO.java
new file mode 100644
index 0000000..5fbb5c0
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/AddPointsFlowDTO.java
@@ -0,0 +1,41 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 鏂板绉垎娴佹按DTO
+ */
+@Data
+@ApiModel(value = "AddPointsFlowDTO", description = "鏂板绉垎娴佹按")
+public class AddPointsFlowDTO {
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    @NotNull(message = "鐢ㄦ埛ID涓嶈兘涓虹┖")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    @NotNull(message = "鍗曚綅ID涓嶈兘涓虹┖")
+    private Long unitId;
+
+    @ApiModelProperty("瑙勫垯绫诲瀷(鑾峰緱/娑堣垂)")
+    @NotBlank(message = "瑙勫垯绫诲瀷涓嶈兘涓虹┖")
+    private String ruleType;
+
+    @ApiModelProperty("瑙勫垯鍚嶇О")
+    @NotBlank(message = "瑙勫垯鍚嶇О涓嶈兘涓虹┖")
+    private String ruleName;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    private String orderId;
+
+    @ApiModelProperty("绉垎娴佹按鎻忚堪")
+    private String description;
+
+    @ApiModelProperty("瑙﹀彂娆℃暟(榛樿涓�1)")
+    private Integer count = 1;
+}
diff --git a/src/main/java/com/webmanage/dto/ApprovalActionDTO.java b/src/main/java/com/webmanage/dto/ApprovalActionDTO.java
new file mode 100644
index 0000000..e622829
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/ApprovalActionDTO.java
@@ -0,0 +1,55 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 瀹℃壒鎿嶄綔DTO
+ */
+@Data
+@ApiModel(value = "ApprovalActionDTO", description = "瀹℃壒鎿嶄綔")
+public class ApprovalActionDTO {
+
+    @ApiModelProperty("璁㈠崟ID")
+    @NotBlank(message = "璁㈠崟ID涓嶈兘涓虹┖")
+    private String orderId;
+
+    @ApiModelProperty("瀹℃壒浜篒D")
+    @NotNull(message = "瀹℃壒浜篒D涓嶈兘涓虹┖")
+    private Long approverId;
+
+    @ApiModelProperty("瀹℃壒浜哄鍚�")
+    @NotBlank(message = "瀹℃壒浜哄鍚嶄笉鑳戒负绌�")
+    private String approverName;
+
+    @ApiModelProperty("瀹℃壒浜鸿鑹�")
+    @NotBlank(message = "瀹℃壒浜鸿鑹蹭笉鑳戒负绌�")
+    private String approverRole;
+
+    @ApiModelProperty("瀹℃壒姝ラ")
+    @NotBlank(message = "瀹℃壒姝ラ涓嶈兘涓虹┖")
+    private String approvalStep;
+
+    @ApiModelProperty("瀹℃壒缁撴灉(閫氳繃/椹冲洖)")
+    @NotBlank(message = "瀹℃壒缁撴灉涓嶈兘涓虹┖")
+    private String approvalResult;
+
+    @ApiModelProperty("瀹℃壒鎰忚")
+    private String approvalOpinion;
+
+    @ApiModelProperty("鏄惁闇�瑕佹巿鏉�")
+    private Boolean needAuthorization = false;
+
+    @ApiModelProperty("鎺堟潈浜篒D")
+    private Long authorizerId;
+
+    @ApiModelProperty("鎺堟潈浜哄鍚�")
+    private String authorizerName;
+
+    @ApiModelProperty("鎺堟潈鎰忚")
+    private String authorizationOpinion;
+}
diff --git a/src/main/java/com/webmanage/dto/ApprovalQueryDTO.java b/src/main/java/com/webmanage/dto/ApprovalQueryDTO.java
new file mode 100644
index 0000000..a35ab24
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/ApprovalQueryDTO.java
@@ -0,0 +1,60 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 瀹℃壒鏌ヨ鏉′欢DTO
+ */
+@Data
+@ApiModel(value = "ApprovalQueryDTO", description = "瀹℃壒鏌ヨ鏉′欢")
+public class ApprovalQueryDTO {
+
+    @ApiModelProperty("褰撳墠椤电爜")
+    private Integer pageNum = 1;
+
+    @ApiModelProperty("姣忛〉澶у皬")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty("璁㈠崟ID")
+    private String orderId;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("瀹℃壒浜篒D")
+    private Long approverId;
+
+    @ApiModelProperty("瀹℃壒缁撴灉")
+    private String approvalResult;
+
+    @ApiModelProperty("瀹℃壒姝ラ")
+    private String approvalStep;
+
+    @ApiModelProperty("鏄惁闇�瑕佹巿鏉�")
+    private Boolean needAuthorization;
+
+    @ApiModelProperty("鐢宠寮�濮嬫椂闂�")
+    private LocalDateTime applyTimeStart;
+
+    @ApiModelProperty("鐢宠缁撴潫鏃堕棿")
+    private LocalDateTime applyTimeEnd;
+
+    @ApiModelProperty("瀹℃壒寮�濮嬫椂闂�")
+    private LocalDateTime approvalTimeStart;
+
+    @ApiModelProperty("瀹℃壒缁撴潫鏃堕棿")
+    private LocalDateTime approvalTimeEnd;
+
+    @ApiModelProperty("鎺掑簭瀛楁")
+    private String orderBy = "created_at";
+
+    @ApiModelProperty("鎺掑簭鏂瑰悜(asc/desc)")
+    private String orderDirection = "desc";
+}
diff --git a/src/main/java/com/webmanage/dto/CartItemDTO.java b/src/main/java/com/webmanage/dto/CartItemDTO.java
new file mode 100644
index 0000000..8514c92
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/CartItemDTO.java
@@ -0,0 +1,73 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * 璐墿杞﹀晢鍝侀」DTO
+ */
+@Data
+@ApiModel(value = "CartItemDTO", description = "璐墿杞﹀晢鍝侀」")
+public class CartItemDTO {
+
+    @ApiModelProperty("鍟嗗搧瀹氫环ID")
+    @NotNull(message = "鍟嗗搧瀹氫环ID涓嶈兘涓虹┖")
+    private Long pricingId;
+
+    @ApiModelProperty("鍟嗗搧ID")
+    @NotNull(message = "鍟嗗搧ID涓嶈兘涓虹┖")
+    private Long productId;
+
+    @ApiModelProperty("鍟嗗搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("鍟嗗搧濂椾欢鍚嶇О")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    @NotNull(message = "鍗曚环涓嶈兘涓虹┖")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    @NotNull(message = "鏁伴噺涓嶈兘涓虹┖")
+    @Min(value = 1, message = "鏁伴噺蹇呴』澶т簬0")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    private String remarks;
+}
diff --git a/src/main/java/com/webmanage/dto/CartQueryDTO.java b/src/main/java/com/webmanage/dto/CartQueryDTO.java
new file mode 100644
index 0000000..4bca7f3
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/CartQueryDTO.java
@@ -0,0 +1,29 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 璐墿杞︽煡璇TO
+ */
+@Data
+@ApiModel(value = "CartQueryDTO", description = "璐墿杞︽煡璇㈡潯浠�")
+public class CartQueryDTO {
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    @NotNull(message = "鐢ㄦ埛ID涓嶈兘涓虹┖")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    @NotNull(message = "鍗曚綅ID涓嶈兘涓虹┖")
+    private Long unitId;
+
+    @ApiModelProperty("鍟嗗搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+}
diff --git a/src/main/java/com/webmanage/dto/CreateOrderDTO.java b/src/main/java/com/webmanage/dto/CreateOrderDTO.java
new file mode 100644
index 0000000..8d940ae
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/CreateOrderDTO.java
@@ -0,0 +1,50 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@ApiModel(value = "CreateOrderDTO", description = "鍒涘缓璁㈠崟璇锋眰")
+public class CreateOrderDTO {
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    @NotNull(message = "鐢ㄦ埛ID涓嶈兘涓虹┖")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    @NotNull(message = "鍗曚綅ID涓嶈兘涓虹┖")
+    private Long unitId;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    @NotBlank(message = "浜у搧鍚嶇О涓嶈兘涓虹┖")
+    private String productName;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("鏀粯鏂瑰紡锛堝锛氱Н鍒�/鐜伴噾/娣峰悎锛�")
+    @NotBlank(message = "鏀粯鏂瑰紡涓嶈兘涓虹┖")
+    private String paymentType;
+
+    @ApiModelProperty("涔板澶囨敞")
+    private String buyerRemarks;
+
+    @ApiModelProperty("璁㈠崟鎬婚噾棰濓紙鍙笉浼狅紝鍚庣鎸夋槑缁嗗悎璁¤绠楋級")
+    private BigDecimal totalAmount;
+
+    @ApiModelProperty("璁㈠崟鏄庣粏鍒楄〃")
+    @Valid
+    @NotEmpty(message = "璁㈠崟鏄庣粏涓嶈兘涓虹┖")
+    private List<CreateOrderItemDTO> items;
+}
diff --git a/src/main/java/com/webmanage/dto/CreateOrderItemDTO.java b/src/main/java/com/webmanage/dto/CreateOrderItemDTO.java
new file mode 100644
index 0000000..e34bc55
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/CreateOrderItemDTO.java
@@ -0,0 +1,65 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "CreateOrderItemDTO", description = "鍒涘缓璁㈠崟-鏄庣粏椤�")
+public class CreateOrderItemDTO {
+    @ApiModelProperty("鍏宠仈浜у搧瀹氫环ID")
+    private Long pricingId;
+
+    @ApiModelProperty("浜у搧ID")
+    @NotNull(message = "浜у搧ID涓嶈兘涓虹┖")
+    private Long productId;
+
+    @ApiModelProperty("浜у搧濂椾欢鍚嶇О")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    @NotNull(message = "鍗曚环涓嶈兘涓虹┖")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    @NotNull(message = "鏁伴噺涓嶈兘涓虹┖")
+    @Min(value = 1, message = "鏁伴噺蹇呴』澶т簬0")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦(鍙笉浼狅紝鍚庣鎸夊崟浠�*鏁伴噺璁$畻)")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    private String remarks;
+}
diff --git a/src/main/java/com/webmanage/dto/OrderQueryDTO.java b/src/main/java/com/webmanage/dto/OrderQueryDTO.java
new file mode 100644
index 0000000..9f96807
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/OrderQueryDTO.java
@@ -0,0 +1,66 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟鏌ヨ鏉′欢DTO
+ */
+@Data
+@ApiModel(value = "OrderQueryDTO", description = "璁㈠崟鏌ヨ鏉′欢")
+public class OrderQueryDTO {
+
+    @ApiModelProperty("褰撳墠椤电爜")
+    private Integer pageNum = 1;
+
+    @ApiModelProperty("姣忛〉澶у皬")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    private Long unitId;
+
+    @ApiModelProperty("鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("璁㈠崟鐘舵��")
+    private String orderStatus;
+
+    @ApiModelProperty("鏀粯鐘舵��")
+    private String paymentStatus;
+
+    @ApiModelProperty("鏀粯鏂瑰紡")
+    private String paymentType;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("璁㈠崟缂栧彿")
+    private String orderId;
+
+    @ApiModelProperty("鐢宠寮�濮嬫椂闂�")
+    private LocalDateTime applyTimeStart;
+
+    @ApiModelProperty("鐢宠缁撴潫鏃堕棿")
+    private LocalDateTime applyTimeEnd;
+
+    @ApiModelProperty("鍒涘缓寮�濮嬫椂闂�")
+    private LocalDateTime createTimeStart;
+
+    @ApiModelProperty("鍒涘缓缁撴潫鏃堕棿")
+    private LocalDateTime createTimeEnd;
+
+    @ApiModelProperty("鎺掑簭瀛楁")
+    private String orderBy = "created_at";
+
+    @ApiModelProperty("鎺掑簭鏂瑰悜(asc/desc)")
+    private String orderDirection = "desc";
+}
diff --git a/src/main/java/com/webmanage/dto/PointsDTO.java b/src/main/java/com/webmanage/dto/PointsDTO.java
new file mode 100644
index 0000000..92c0b08
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsDTO.java
@@ -0,0 +1,41 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎涓昏〃DTO
+ */
+@Data
+@ApiModel(value = "PointsDTO", description = "绉垎涓昏〃")
+public class PointsDTO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("绉垎鍚嶇О")
+    @NotBlank(message = "绉垎鍚嶇О涓嶈兘涓虹┖")
+    private String pointsName;
+
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�")
+    private LocalDateTime effectiveStart;
+
+    @ApiModelProperty("鐢熸晥缁撴潫鏃堕棿")
+    private LocalDateTime effectiveEnd;
+
+
+    @ApiModelProperty("淇敼浜哄鍚�")
+    private String modifierName;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private String version;
+
+
+    @ApiModelProperty("鐘舵��")
+    private String status;
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/dto/PointsFlowQueryDTO.java b/src/main/java/com/webmanage/dto/PointsFlowQueryDTO.java
new file mode 100644
index 0000000..3234cf0
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsFlowQueryDTO.java
@@ -0,0 +1,48 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎娴佹按鏌ヨ鏉′欢DTO
+ */
+@Data
+@ApiModel(value = "PointsFlowQueryDTO", description = "绉垎娴佹按鏌ヨ鏉′欢")
+public class PointsFlowQueryDTO {
+
+    @ApiModelProperty("褰撳墠椤电爜")
+    private Integer pageNum = 1;
+
+    @ApiModelProperty("姣忛〉澶у皬")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    private Long unitId;
+
+    @ApiModelProperty("娴佹按绫诲瀷(鑾峰緱/娑堣垂)")
+    private String flowType;
+
+    @ApiModelProperty("绉垎鏉ユ簮")
+    private String pointsSource;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    private String orderId;
+
+    @ApiModelProperty("寮�濮嬫椂闂�")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty("缁撴潫鏃堕棿")
+    private LocalDateTime endTime;
+
+    @ApiModelProperty("鎺掑簭瀛楁")
+    private String orderBy = "created_at";
+
+    @ApiModelProperty("鎺掑簭鏂瑰悜(asc/desc)")
+    private String orderDirection = "desc";
+}
diff --git a/src/main/java/com/webmanage/dto/PointsMainQueryDTO.java b/src/main/java/com/webmanage/dto/PointsMainQueryDTO.java
new file mode 100644
index 0000000..dbe278d
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsMainQueryDTO.java
@@ -0,0 +1,51 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎涓昏〃鏌ヨDTO
+ */
+@Data
+@ApiModel(value = "PointsMainQueryDTO", description = "绉垎涓昏〃鏌ヨ鏉′欢")
+public class PointsMainQueryDTO {
+
+    @ApiModelProperty("褰撳墠椤电爜")
+    private Integer pageNum = 1;
+
+    @ApiModelProperty("姣忛〉澶у皬")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty("绉垎鍚嶇О")
+    private String pointsName;
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�-寮�濮�")
+    private LocalDateTime effectiveStartTime;
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�-缁撴潫")
+    private LocalDateTime effectiveEndTime;
+
+    @ApiModelProperty("淇敼浜哄鍚�")
+    private String modifierName;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    private String version;
+
+    @ApiModelProperty("鐘舵��")
+    private String status;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿-寮�濮�")
+    private LocalDateTime createdAtBegin;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿-缁撴潫")
+    private LocalDateTime createdAtEnd;
+
+    @ApiModelProperty("鎺掑簭瀛楁")
+    private String orderBy = "created_at";
+
+    @ApiModelProperty("鎺掑簭鏂瑰悜(asc/desc)")
+    private String orderDirection = "desc";
+} 
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/dto/PointsOperateDTO.java b/src/main/java/com/webmanage/dto/PointsOperateDTO.java
new file mode 100644
index 0000000..3e03be4
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsOperateDTO.java
@@ -0,0 +1,18 @@
+package com.webmanage.dto;
+
+import lombok.Data;
+
+/**
+ * 璁拌处鎿嶄綔DTO锛氭寜瑙勫垯鍚嶆柊澧炴祦姘�
+ */
+@Data
+public class PointsOperateDTO {
+    /** 瀵瑰簲 points_rule.rule_name */
+    private String ruleName;
+    /** 娆℃暟/鏁伴噺锛屽彲绌洪粯璁�1 */
+    private Integer count;
+    /** 娴佹按鍚嶇О/鎻忚堪锛堝彲閫夛紝涓嶅~鐢ㄨ鍒欐弿杩帮級 */
+    private String name;
+}
+
+
diff --git a/src/main/java/com/webmanage/dto/PointsQueryDTO.java b/src/main/java/com/webmanage/dto/PointsQueryDTO.java
new file mode 100644
index 0000000..27b0219
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsQueryDTO.java
@@ -0,0 +1,50 @@
+package com.webmanage.dto;
+
+import lombok.Data;
+
+/**
+ * 绉垎鏌ヨDTO
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+public class PointsQueryDTO {
+
+    /**
+     * 鐢ㄦ埛ID锛堝彲閫夛紝鐢ㄤ簬闄愬畾涓汉娴佹按锛�
+     */
+    private Long userId;
+
+    /**
+     * 鍗曚綅ID锛堝彲閫夛紝鐢ㄤ簬闄愬畾鍗曚綅娴佹按锛�
+     */
+    private Long unitId;
+
+    /** 鏁版嵁绫荤洰 */
+    private String dataCategory;
+
+    /** 鏁版嵁绫诲瀷 */
+    private String dataType;
+
+    /** 寮�濮嬫椂闂� */
+    private String startTime;
+
+    /** 缁撴潫鏃堕棿 */
+    private String endTime;
+
+    /** 骞翠唤 */
+    private String year;
+
+    /** 鏈堜唤 */
+    private String month;
+
+    /** 鏃ユ湡 */
+    private String day;
+
+    /** 椤电爜 */
+    private Integer pageNum = 1;
+
+    /** 姣忛〉澶у皬 */
+    private Integer pageSize = 10;
+}
diff --git a/src/main/java/com/webmanage/dto/PointsRuleDTO.java b/src/main/java/com/webmanage/dto/PointsRuleDTO.java
new file mode 100644
index 0000000..e816a14
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsRuleDTO.java
@@ -0,0 +1,54 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * 绉垎瑙勫垯DTO
+ */
+@Data
+@ApiModel(value = "PointsRuleDTO", description = "绉垎瑙勫垯")
+public class PointsRuleDTO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("瑙勫垯鍚嶇О")
+    @NotBlank(message = "瑙勫垯鍚嶇О涓嶈兘涓虹┖")
+    private String ruleName;
+
+    @ApiModelProperty("瑙勫垯绫诲瀷(鑾峰緱/娑堣垂)")
+    @NotBlank(message = "瑙勫垯绫诲瀷涓嶈兘涓虹┖")
+    private String ruleType;
+
+    @ApiModelProperty("绉垎鍊�")
+    @NotNull(message = "绉垎鍊间笉鑳戒负绌�")
+    private Integer pointsValue;
+
+    @ApiModelProperty("瑙﹀彂鏉′欢")
+    @NotBlank(message = "瑙﹀彂鏉′欢涓嶈兘涓虹┖")
+    private String triggerCondition;
+
+    @ApiModelProperty("瑙﹀彂閲戦")
+    private BigDecimal triggerAmount;
+
+    @ApiModelProperty("瑙勫垯鎻忚堪")
+    private String description;
+
+    @ApiModelProperty("鏄惁鍚敤")
+    private Boolean isEnabled = true;
+
+    @ApiModelProperty("浼樺厛绾�")
+    private Integer priority = 1;
+
+    @ApiModelProperty("鏈夋晥鏈熷紑濮嬫椂闂�")
+    private String validStartTime;
+
+    @ApiModelProperty("鏈夋晥鏈熺粨鏉熸椂闂�")
+    private String validEndTime;
+}
diff --git a/src/main/java/com/webmanage/dto/PointsRuleDetailDTO.java b/src/main/java/com/webmanage/dto/PointsRuleDetailDTO.java
new file mode 100644
index 0000000..3ba8ca5
--- /dev/null
+++ b/src/main/java/com/webmanage/dto/PointsRuleDetailDTO.java
@@ -0,0 +1,56 @@
+package com.webmanage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎瑙勫垯璇︽儏DTO
+ */
+@Data
+@ApiModel(value = "PointsRuleDetailDTO", description = "绉垎瑙勫垯璇︽儏")
+public class PointsRuleDetailDTO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈绉垎瑙勫垯ID")
+    @NotNull(message = "鍏宠仈绉垎瑙勫垯ID涓嶈兘涓虹┖")
+    private Long ruleId;
+
+    @ApiModelProperty("鍏宠仈绉垎ID")
+    @NotNull(message = "鍏宠仈绉垎ID涓嶈兘涓虹┖")
+    private Long pointsId;
+
+    @ApiModelProperty("绉垎鍊�")
+    @NotNull(message = "绉垎鍊间笉鑳戒负绌�")
+    private Integer pointsValue;
+
+    @ApiModelProperty("姣忔棩绉垎涓婇檺鍊�")
+    private Integer dailyLimit;
+
+    @ApiModelProperty("姣忔湀绉垎涓婇檺鍊�")
+    private Integer monthlyLimit;
+
+    @ApiModelProperty("姣忓勾绉垎涓婇檺鍊�")
+    private Integer yearlyLimit;
+
+    @ApiModelProperty("鏈�灏忓��")
+    private Integer minValue;
+
+    @ApiModelProperty("鏈�澶у��")
+    private Integer maxValue;
+
+    @ApiModelProperty("杞崲姣旂巼")
+    private BigDecimal conversionRate;
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�")
+    private LocalDateTime effectiveStart;
+
+    @ApiModelProperty("鐢熸晥缁撴潫鏃堕棿")
+    private LocalDateTime effectiveEnd;
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/entity/ApprovalRecord.java b/src/main/java/com/webmanage/entity/ApprovalRecord.java
new file mode 100644
index 0000000..0315756
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/ApprovalRecord.java
@@ -0,0 +1,88 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 瀹℃壒璁板綍瀹炰綋绫�
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("approval_record")
+@ApiModel(value = "ApprovalRecord", description = "瀹℃壒璁板綍")
+public class ApprovalRecord {
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    @TableField("order_id")
+    private String orderId;
+
+    @ApiModelProperty("瀹℃壒浜篒D")
+    @TableField("approver_id")
+    private Long approverId;
+
+    @ApiModelProperty("瀹℃壒浜哄鍚�")
+    @TableField("approver_name")
+    private String approverName;
+
+    @ApiModelProperty("瀹℃壒浜鸿鑹�")
+    @TableField("approver_role")
+    private String approverRole;
+
+    @ApiModelProperty("瀹℃壒姝ラ")
+    @TableField("approval_step")
+    private String approvalStep;
+
+    @ApiModelProperty("瀹℃壒缁撴灉(閫氳繃/椹冲洖)")
+    @TableField("approval_result")
+    private String approvalResult;
+
+    @ApiModelProperty("瀹℃壒鎰忚")
+    @TableField("approval_opinion")
+    private String approvalOpinion;
+
+    @ApiModelProperty("瀹℃壒鏃堕棿")
+    @TableField("approval_time")
+    private LocalDateTime approvalTime;
+
+    @ApiModelProperty("鏄惁闇�瑕佹巿鏉�")
+    @TableField("need_authorization")
+    private Boolean needAuthorization;
+
+    @ApiModelProperty("鎺堟潈浜篒D")
+    @TableField("authorizer_id")
+    private Long authorizerId;
+
+    @ApiModelProperty("鎺堟潈浜哄鍚�")
+    @TableField("authorizer_name")
+    private String authorizerName;
+
+    @ApiModelProperty("鎺堟潈鏃堕棿")
+    @TableField("authorization_time")
+    private LocalDateTime authorizationTime;
+
+    @ApiModelProperty("鎺堟潈鎰忚")
+    @TableField("authorization_opinion")
+    private String authorizationOpinion;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/Cart.java b/src/main/java/com/webmanage/entity/Cart.java
new file mode 100644
index 0000000..2504dd7
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/Cart.java
@@ -0,0 +1,112 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 璐墿杞﹀疄浣撶被
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("cart")
+@ApiModel(value = "Cart", description = "璐墿杞�")
+public class Cart {
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    @TableField("user_id")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    @TableField("unit_id")
+    private Long unitId;
+
+    @ApiModelProperty("鍟嗗搧瀹氫环ID")
+    @TableField("pricing_id")
+    private Long pricingId;
+
+    @ApiModelProperty("鍟嗗搧ID")
+    @TableField("product_id")
+    private Long productId;
+
+    @ApiModelProperty("鍟嗗搧鍚嶇О")
+    @TableField("product_name")
+    private String productName;
+
+    @ApiModelProperty("鍟嗗搧濂椾欢鍚嶇О")
+    @TableField("suite_name")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    @TableField("sales_form")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    @TableField("customer_type")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    @TableField("account_limit")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    @TableField("concurrent_nodes")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    @TableField("price_type")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    @TableField("price_unit")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    @TableField("unit_price")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    @TableField("quantity")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    @TableField("duration")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦")
+    @TableField("total_price")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    @TableField("provider_id")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    @TableField("provider_name")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    @TableField("remarks")
+    private String remarks;
+
+    @ApiModelProperty("娣诲姞鏃堕棿")
+    @TableField("add_time")
+    private LocalDateTime addTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField("update_time")
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/OrderAttachment.java b/src/main/java/com/webmanage/entity/OrderAttachment.java
new file mode 100644
index 0000000..97b406c
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/OrderAttachment.java
@@ -0,0 +1,88 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟闄勪欢瀹炰綋绫�
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("order_attachment")
+@ApiModel(value = "OrderAttachment", description = "璁㈠崟闄勪欢")
+public class OrderAttachment {
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    @TableField("order_id")
+    private String orderId;
+
+    @ApiModelProperty("闄勪欢鍚嶇О")
+    @TableField("file_name")
+    private String fileName;
+
+    @ApiModelProperty("鍘熷鏂囦欢鍚�")
+    @TableField("original_name")
+    private String originalName;
+
+    @ApiModelProperty("闄勪欢绫诲瀷")
+    @TableField("file_type")
+    private String fileType;
+
+    @ApiModelProperty("闄勪欢澶у皬(瀛楄妭)")
+    @TableField("file_size")
+    private Long fileSize;
+
+    @ApiModelProperty("闄勪欢鍦板潃")
+    @TableField("file_url")
+    private String fileUrl;
+
+    @ApiModelProperty("鏂囦欢瀛樺偍璺緞")
+    @TableField("file_path")
+    private String filePath;
+
+    @ApiModelProperty("MinIO瀛樺偍妗跺悕绉�")
+    @TableField("bucket_name")
+    private String bucketName;
+
+    @ApiModelProperty("MinIO瀵硅薄鍚嶇О")
+    @TableField("object_name")
+    private String objectName;
+
+    @ApiModelProperty("涓婁紶鐢ㄦ埛ID")
+    @TableField("upload_user_id")
+    private Long uploadUserId;
+
+    @ApiModelProperty("涓婁紶鐢ㄦ埛鍚�")
+    @TableField("upload_user_name")
+    private String uploadUserName;
+
+    @ApiModelProperty("闄勪欢绫诲瀷(鍚堝悓/鍙戠エ/鍏朵粬)")
+    @TableField("attachment_type")
+    private String attachmentType;
+
+    @ApiModelProperty("闄勪欢鎻忚堪")
+    @TableField("description")
+    private String description;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/OrderDetail.java b/src/main/java/com/webmanage/entity/OrderDetail.java
new file mode 100644
index 0000000..f2bb3e4
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/OrderDetail.java
@@ -0,0 +1,105 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟璇︽儏瀹炰綋绫�
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("order_detail")
+@ApiModel(value = "OrderDetail", description = "璁㈠崟璇︽儏")
+public class OrderDetail {
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    @TableField("order_id")
+    private String orderId;
+
+    @ApiModelProperty("鍏宠仈浜у搧瀹氫环ID")
+    @TableField("pricing_id")
+    private Long pricingId;
+
+    @ApiModelProperty("浜у搧ID")
+    @TableField("product_id")
+    private Long productId;
+
+    @ApiModelProperty("浜у搧濂椾欢鍚嶇О")
+    @TableField("suite_name")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    @TableField("sales_form")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    @TableField("customer_type")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    @TableField("account_limit")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    @TableField("concurrent_nodes")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    @TableField("price_type")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    @TableField("price_unit")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    @TableField("unit_price")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    @TableField("quantity")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    @TableField("duration")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦")
+    @TableField("total_price")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    @TableField("provider_id")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    @TableField("provider_name")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    @TableField("remarks")
+    private String remarks;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/OrderEvaluation.java b/src/main/java/com/webmanage/entity/OrderEvaluation.java
new file mode 100644
index 0000000..9ae5922
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/OrderEvaluation.java
@@ -0,0 +1,88 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟璇勪环瀹炰綋绫�
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("order_evaluation")
+@ApiModel(value = "OrderEvaluation", description = "璁㈠崟璇勪环")
+public class OrderEvaluation {
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    @TableField("order_id")
+    private String orderId;
+
+    @ApiModelProperty("璇勪环浜篒D")
+    @TableField("evaluator_id")
+    private Long evaluatorId;
+
+    @ApiModelProperty("璇勪环浜哄鍚�")
+    @TableField("evaluator_name")
+    private String evaluatorName;
+
+    @ApiModelProperty("璇勪环浜虹被鍨�")
+    @TableField("evaluator_type")
+    private String evaluatorType;
+
+    @ApiModelProperty("璇勪环鍐呭")
+    @TableField("content")
+    private String content;
+
+    @ApiModelProperty("璇勫垎(1-5)")
+    @TableField("rating")
+    private Integer rating;
+
+    @ApiModelProperty("鏈嶅姟璇勫垎")
+    @TableField("service_rating")
+    private Integer serviceRating;
+
+    @ApiModelProperty("璐ㄩ噺璇勫垎")
+    @TableField("quality_rating")
+    private Integer qualityRating;
+
+    @ApiModelProperty("浜や粯璇勫垎")
+    @TableField("delivery_rating")
+    private Integer deliveryRating;
+
+    @ApiModelProperty("鏄惁鍖垮悕璇勪环")
+    @TableField("is_anonymous")
+    private Boolean isAnonymous;
+
+    @ApiModelProperty("鍥炲鍐呭")
+    @TableField("reply_content")
+    private String replyContent;
+
+    @ApiModelProperty("鍥炲鐢ㄦ埛ID")
+    @TableField("reply_user_id")
+    private Long replyUserId;
+
+    @ApiModelProperty("鍥炲鏃堕棿")
+    @TableField("reply_time")
+    private LocalDateTime replyTime;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/OrderInfo.java b/src/main/java/com/webmanage/entity/OrderInfo.java
new file mode 100644
index 0000000..6ab5947
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/OrderInfo.java
@@ -0,0 +1,144 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟淇℃伅瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("order_info")
+public class OrderInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 璁㈠崟缂栧彿
+     */
+    @TableId(value = "order_id", type = IdType.INPUT)
+    private String orderId;
+
+    /**
+     * 浜у搧ID
+     */
+    @TableField("product_id")
+    private Long productId;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 鍗曚綅ID
+     */
+    @TableField("unit_id")
+    private Long unitId;
+
+    /**
+     * 浜у搧鍚嶇О
+     */
+    @TableField("product_name")
+    private String productName;
+
+    /**
+     * 浜у搧鎻愪緵鑰呭悕绉�
+     */
+    @TableField("provider_name")
+    private String providerName;
+
+    /**
+     * 鎻愪緵鑰匢D
+     */
+    @TableField("provider_id")
+    private Long providerId;
+
+    /**
+     * 鐢宠鏃堕棿
+     */
+    @TableField("apply_time")
+    private LocalDateTime applyTime;
+
+    /**
+     * 璁㈠崟鐘舵��
+     */
+    @TableField("order_status")
+    private String orderStatus;
+
+    /**
+     * 璁㈠崟鎬婚噾棰�
+     */
+    @TableField("total_amount")
+    private BigDecimal totalAmount;
+
+    /**
+     * 鏀粯鏂瑰紡
+     */
+    @TableField("payment_type")
+    private String paymentType;
+
+    /**
+     * 鏀粯鐘舵��
+     */
+    @TableField("payment_status")
+    private String paymentStatus;
+
+    /**
+     * 宸ヤ綔娴両D
+     */
+    @TableField("workflow_id")
+    private String workflowId;
+
+    /**
+     * 褰撳墠瀹℃壒姝ラ
+     */
+    @TableField("current_step")
+    private String currentStep;
+
+    /**
+     * 瀹℃壒娴佺▼閰嶇疆
+     */
+    @TableField("approval_flow")
+    private String approvalFlow;
+
+    /**
+     * 涔板澶囨敞
+     */
+    @TableField("buyer_remarks")
+    private String buyerRemarks;
+
+    /**
+     * 鍗栧澶囨敞
+     */
+    @TableField("seller_remarks")
+    private String sellerRemarks;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    /**
+     * 閫昏緫鍒犻櫎
+     */
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/Points.java b/src/main/java/com/webmanage/entity/Points.java
new file mode 100644
index 0000000..40a6f3f
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/Points.java
@@ -0,0 +1,73 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎涓昏〃瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("points")
+@ApiModel(value = "Points", description = "绉垎涓昏〃")
+public class Points implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("绉垎瑙勫垯鍚嶇О")
+    @TableField("points_name")
+    private String pointsName;
+
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�")
+    @TableField("effective_start")
+//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime effectiveStart;
+
+
+    @ApiModelProperty("淇敼浜篒D")
+    @TableField("modifier_id")
+    private Long modifierId;
+
+    @ApiModelProperty("淇敼浜哄鍚�")
+    @TableField("modifier_name")
+    private String modifierName;
+
+    @ApiModelProperty("鐗堟湰鍙�")
+    @TableField("version")
+    @JsonFormat(shape= JsonFormat.Shape.STRING)
+    private float version;
+
+  
+
+    @ApiModelProperty("鐘舵��")
+    @TableField("status")
+    private int status;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/entity/PointsFlow.java b/src/main/java/com/webmanage/entity/PointsFlow.java
new file mode 100644
index 0000000..0066883
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/PointsFlow.java
@@ -0,0 +1,89 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎娴佹按瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("points_flow")
+public class PointsFlow implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 鍗曚綅ID
+     */
+    @TableField("unit_id")
+    private Long unitId;
+
+    /**
+     * 鏁版嵁绫荤洰
+     */
+    @TableField("data_category")
+    private String dataCategory;
+
+    /**
+     * 鏁版嵁绫诲瀷
+     */
+    @TableField("data_type")
+    private String dataType;
+
+    /**
+     * 鍚嶇О/鎻忚堪
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 绉垎鍊�
+     */
+    @TableField("points")
+    private Integer points;
+
+    /**
+     * 娴佹按鏃堕棿
+     */
+    @TableField("flow_time")
+    private LocalDateTime flowTime;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(value = "create_time", fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    /**
+     * 閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�
+     */
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/PointsRule.java b/src/main/java/com/webmanage/entity/PointsRule.java
new file mode 100644
index 0000000..0a9a8a1
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/PointsRule.java
@@ -0,0 +1,83 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎瑙勫垯瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("points_rule")
+@ApiModel(value = "PointsRule", description = "绉垎瑙勫垯")
+public class PointsRule implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("瑙勫垯鍚嶇О")
+    @TableField("rule_name")
+    private String ruleName;
+
+    @ApiModelProperty("瑙勫垯绫诲瀷(鑾峰緱/娑堣垂)")
+    @TableField("rule_type")
+    private String ruleType;
+
+    @ApiModelProperty("绉垎鍊�")
+    @TableField("points_value")
+    private Integer pointsValue;
+
+    @ApiModelProperty("瑙﹀彂鏉′欢")
+    @TableField("trigger_condition")
+    private String triggerCondition;
+
+    @ApiModelProperty("瑙﹀彂閲戦")
+    @TableField("trigger_amount")
+    private BigDecimal triggerAmount;
+
+    @ApiModelProperty("瑙勫垯鎻忚堪")
+    @TableField("rule_description")
+    private String ruleDescription;
+
+    @ApiModelProperty("鏄惁鍚敤")
+    @TableField("is_enabled")
+    private Boolean isEnabled;
+
+    @ApiModelProperty("浼樺厛绾�")
+    @TableField("priority")
+    private Integer priority;
+
+    @ApiModelProperty("鏈夋晥鏈熷紑濮嬫椂闂�")
+    @TableField("valid_start_time")
+    private LocalDateTime validStartTime;
+
+    @ApiModelProperty("鏈夋晥鏈熺粨鏉熸椂闂�")
+    @TableField("valid_end_time")
+    private LocalDateTime validEndTime;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/PointsRuleDetail.java b/src/main/java/com/webmanage/entity/PointsRuleDetail.java
new file mode 100644
index 0000000..15025d9
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/PointsRuleDetail.java
@@ -0,0 +1,87 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎瑙勫垯璇︽儏瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("points_rule_detail")
+@ApiModel(value = "PointsRuleDetail", description = "绉垎瑙勫垯璇︽儏")
+public class PointsRuleDetail implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈绉垎瑙勫垯ID")
+    @TableField("rule_id")
+    private Long ruleId;
+
+    @ApiModelProperty("鍏宠仈绉垎ID")
+    @TableField("points_id")
+    private Long pointsId;
+
+    @ApiModelProperty("绉垎鍊�")
+    @TableField("points_value")
+    private Integer pointsValue;
+
+    @ApiModelProperty("姣忔棩绉垎涓婇檺鍊�")
+    @TableField("daily_limit")
+    private Integer dailyLimit;
+
+    @ApiModelProperty("姣忔湀绉垎涓婇檺鍊�")
+    @TableField("monthly_limit")
+    private Integer monthlyLimit;
+
+    @ApiModelProperty("姣忓勾绉垎涓婇檺鍊�")
+    @TableField("yearly_limit")
+    private Integer yearlyLimit;
+
+    @ApiModelProperty("鏈�灏忓��")
+    @TableField("min_value")
+    private Integer minValue;
+
+    @ApiModelProperty("鏈�澶у��")
+    @TableField("max_value")
+    private Integer maxValue;
+
+    @ApiModelProperty("杞崲姣旂巼")
+    @TableField("conversion_rate")
+    private BigDecimal conversionRate;
+
+    @ApiModelProperty("鐢熸晥寮�濮嬫椂闂�")
+    @TableField("effective_start")
+    private LocalDateTime effectiveStart;
+
+    @ApiModelProperty("鐢熸晥缁撴潫鏃堕棿")
+    @TableField("effective_end")
+    private LocalDateTime effectiveEnd;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/entity/PointsRuleEntity.java b/src/main/java/com/webmanage/entity/PointsRuleEntity.java
new file mode 100644
index 0000000..6245c1d
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/PointsRuleEntity.java
@@ -0,0 +1,66 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 绉垎瑙勫垯琛ㄥ疄浣�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("points_rule")
+@ApiModel(value = "PointsRuleEntity", description = "绉垎瑙勫垯")
+public class PointsRuleEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈绉垎ID")
+    @TableField("points_id")
+    private Long pointsId;
+
+    @ApiModelProperty("绉垎瑙勫垯绫诲瀷")
+    @TableField("rule_type")
+    private String ruleType;
+
+    @ApiModelProperty("绉垎绫诲埆")
+    @TableField("category")
+    private String category;
+
+    @ApiModelProperty("瑙勫垯鍚嶇О")
+    @TableField("rule_name")
+    private String ruleName;
+
+    @ApiModelProperty("瑙勫垯鎻忚堪")
+    @TableField("rule_description")
+    private String ruleDescription;
+
+    @ApiModelProperty("瑙勫垯鐘舵��")
+    @TableField("status")
+    private String status;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("閫昏緫鍒犻櫎")
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/entity/ProductPricing.java b/src/main/java/com/webmanage/entity/ProductPricing.java
new file mode 100644
index 0000000..7c61271
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/ProductPricing.java
@@ -0,0 +1,144 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 浜у搧瀹氫环瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("product_pricing")
+public class ProductPricing implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 浜у搧濂椾欢鍚嶇О
+     */
+    @TableField("suite_name")
+    private String suiteName;
+
+    /**
+     * 閿�鍞舰寮�
+     */
+    @TableField("sales_form")
+    private String salesForm;
+
+    /**
+     * 瀹㈡埛瀵硅薄
+     */
+    @TableField("customer_type")
+    private String customerType;
+
+    /**
+     * 璐︽埛鏁伴噺
+     */
+    @TableField("account_limit")
+    private String accountLimit;
+
+    /**
+     * 骞跺彂鑺傜偣鏁�
+     */
+    @TableField("concurrent_nodes")
+    private String concurrentNodes;
+
+    /**
+     * 浠锋牸璁剧疆
+     */
+    @TableField("price_type")
+    private String priceType;
+
+    /**
+     * 浠锋牸鍗曚綅
+     */
+    @TableField("price_unit")
+    private String priceUnit;
+
+    /**
+     * 浠锋牸鍊�
+     */
+    @TableField("price")
+    private BigDecimal price;
+
+    /**
+     * 鍚敤鐘舵��
+     */
+    @TableField("is_active")
+    private Boolean isActive;
+
+    /**
+     * 鍏宠仈浜у搧ID
+     */
+    @TableField("product_id")
+    private Long productId;
+
+    /**
+     * 浜у搧鍚嶇О
+     */
+    @TableField("product_name")
+    private String productName;
+
+    /**
+     * 浜у搧鎻愪緵鑰匢D
+     */
+    @TableField("provider_id")
+    private Long providerId;
+
+    /**
+     * 浜у搧鎻愪緵鑰呭悕绉�
+     */
+    @TableField("provider_name")
+    private String providerName;
+
+    /**
+     * 浜у搧鎻忚堪
+     */
+    @TableField("description")
+    private String description;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(value = "created_at", fill = FieldFill.INSERT)
+    private LocalDateTime createdAt;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updatedAt;
+
+    /**
+     * 鍒涘缓浜篒D
+     */
+    @TableField("created_by")
+    private Long createdBy;
+
+    /**
+     * 鏇存柊浜篒D
+     */
+    @TableField("updated_by")
+    private Long updatedBy;
+
+    /**
+     * 閫昏緫鍒犻櫎
+     */
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/entity/UserPoints.java b/src/main/java/com/webmanage/entity/UserPoints.java
new file mode 100644
index 0000000..5448b71
--- /dev/null
+++ b/src/main/java/com/webmanage/entity/UserPoints.java
@@ -0,0 +1,83 @@
+package com.webmanage.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 鐢ㄦ埛绉垎瀹炰綋
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("user_points")
+public class UserPoints implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓婚敭ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 鍗曚綅ID
+     */
+    @TableField("unit_id")
+    private Long unitId;
+
+    /**
+     * 绉垎浣欓
+     */
+    @TableField("balance")
+    private Integer balance;
+
+    /**
+     * 绱鑾峰彇绉垎
+     */
+    @TableField("total_earned")
+    private Integer totalEarned;
+
+    /**
+     * 绱娑堣�楃Н鍒�
+     */
+    @TableField("total_consumed")
+    private Integer totalConsumed;
+
+    /**
+     * 绱杞崲绉垎
+     */
+    @TableField("total_converted")
+    private Integer totalConverted;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @TableField(value = "create_time", fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    /**
+     * 閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�
+     */
+    @TableLogic
+    @TableField("deleted")
+    private Integer deleted;
+}
diff --git a/src/main/java/com/webmanage/mapper/ApprovalRecordMapper.java b/src/main/java/com/webmanage/mapper/ApprovalRecordMapper.java
new file mode 100644
index 0000000..35dea0d
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/ApprovalRecordMapper.java
@@ -0,0 +1,51 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.entity.ApprovalRecord;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 瀹℃壒璁板綍Mapper鎺ュ彛
+ */
+@Mapper
+public interface ApprovalRecordMapper extends BaseMapper<ApprovalRecord> {
+
+    /**
+     * 鍒嗛〉鏌ヨ瀹℃壒璁板綍
+     */
+    IPage<ApprovalRecord> selectApprovalRecordPage(Page<ApprovalRecord> page,
+                                                   @Param("orderId") String orderId,
+                                                   @Param("productName") String productName,
+                                                   @Param("providerName") String providerName,
+                                                   @Param("approverId") Long approverId,
+                                                   @Param("approvalResult") String approvalResult,
+                                                   @Param("approvalStep") String approvalStep,
+                                                   @Param("needAuthorization") Boolean needAuthorization,
+                                                   @Param("applyTimeStart") String applyTimeStart,
+                                                   @Param("applyTimeEnd") String applyTimeEnd,
+                                                   @Param("approvalTimeStart") String approvalTimeStart,
+                                                   @Param("approvalTimeEnd") String approvalTimeEnd,
+                                                   @Param("orderBy") String orderBy,
+                                                   @Param("orderDirection") String orderDirection);
+
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ瀹℃壒璁板綍
+     */
+    List<ApprovalRecord> selectByOrderId(@Param("orderId") String orderId);
+
+    /**
+     * 鏌ヨ寰呭鎵圭殑璁㈠崟
+     */
+    IPage<ApprovalRecord> selectPendingApprovalPage(Page<ApprovalRecord> page,
+                                                    @Param("orderId") String orderId,
+                                                    @Param("productName") String productName,
+                                                    @Param("providerName") String providerName,
+                                                    @Param("approvalStep") String approvalStep,
+                                                    @Param("orderBy") String orderBy,
+                                                    @Param("orderDirection") String orderDirection);
+}
diff --git a/src/main/java/com/webmanage/mapper/CartMapper.java b/src/main/java/com/webmanage/mapper/CartMapper.java
new file mode 100644
index 0000000..76abe93
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/CartMapper.java
@@ -0,0 +1,35 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.Cart;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 璐墿杞apper鎺ュ彛
+ */
+@Mapper
+public interface CartMapper extends BaseMapper<Cart> {
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鍜屽崟浣岻D鏌ヨ璐墿杞﹀晢鍝佸垪琛�
+     */
+    List<Cart> selectByUserIdAndUnitId(@Param("userId") Long userId, @Param("unitId") Long unitId);
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛ID銆佸崟浣岻D鍜屽畾浠稩D鏌ヨ璐墿杞﹀晢鍝�
+     */
+    Cart selectByUserIdUnitIdAndPricingId(@Param("userId") Long userId, @Param("unitId") Long unitId, @Param("pricingId") Long pricingId);
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鍜屽崟浣岻D缁熻璐墿杞﹀晢鍝佹暟閲�
+     */
+    Integer countByUserIdAndUnitId(@Param("userId") Long userId, @Param("unitId") Long unitId);
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鍜屽崟浣岻D璁$畻璐墿杞︽�婚噾棰�
+     */
+    java.math.BigDecimal sumTotalAmountByUserIdAndUnitId(@Param("userId") Long userId, @Param("unitId") Long unitId);
+}
diff --git a/src/main/java/com/webmanage/mapper/OrderAttachmentMapper.java b/src/main/java/com/webmanage/mapper/OrderAttachmentMapper.java
new file mode 100644
index 0000000..e10675b
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/OrderAttachmentMapper.java
@@ -0,0 +1,20 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.OrderAttachment;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 璁㈠崟闄勪欢Mapper鎺ュ彛
+ */
+@Mapper
+public interface OrderAttachmentMapper extends BaseMapper<OrderAttachment> {
+
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟闄勪欢鍒楄〃
+     */
+    List<OrderAttachment> selectByOrderId(@Param("orderId") String orderId);
+}
diff --git a/src/main/java/com/webmanage/mapper/OrderDetailMapper.java b/src/main/java/com/webmanage/mapper/OrderDetailMapper.java
new file mode 100644
index 0000000..02df4af
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/OrderDetailMapper.java
@@ -0,0 +1,20 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.OrderDetail;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 璁㈠崟璇︽儏Mapper鎺ュ彛
+ */
+@Mapper
+public interface OrderDetailMapper extends BaseMapper<OrderDetail> {
+
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟璇︽儏鍒楄〃
+     */
+    List<OrderDetail> selectByOrderId(@Param("orderId") String orderId);
+}
diff --git a/src/main/java/com/webmanage/mapper/OrderEvaluationMapper.java b/src/main/java/com/webmanage/mapper/OrderEvaluationMapper.java
new file mode 100644
index 0000000..217f070
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/OrderEvaluationMapper.java
@@ -0,0 +1,18 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.OrderEvaluation;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 璁㈠崟璇勪环Mapper鎺ュ彛
+ */
+@Mapper
+public interface OrderEvaluationMapper extends BaseMapper<OrderEvaluation> {
+
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟璇勪环
+     */
+    OrderEvaluation selectByOrderId(@Param("orderId") String orderId);
+}
diff --git a/src/main/java/com/webmanage/mapper/OrderInfoMapper.java b/src/main/java/com/webmanage/mapper/OrderInfoMapper.java
new file mode 100644
index 0000000..e019bcb
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/OrderInfoMapper.java
@@ -0,0 +1,46 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.entity.OrderInfo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 璁㈠崟淇℃伅Mapper鎺ュ彛
+ */
+@Mapper
+public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
+
+    /**
+     * 鍒嗛〉鏌ヨ涔板璁㈠崟鍒楄〃
+     */
+    IPage<OrderInfo> selectBuyerOrderPage(Page<OrderInfo> page, @Param("userId") Long userId, 
+                                        @Param("unitId") Long unitId, @Param("orderStatus") String orderStatus,
+                                        @Param("paymentStatus") String paymentStatus, @Param("paymentType") String paymentType,
+                                        @Param("productName") String productName, @Param("providerName") String providerName,
+                                        @Param("orderId") String orderId, @Param("applyTimeStart") String applyTimeStart,
+                                        @Param("applyTimeEnd") String applyTimeEnd, @Param("createTimeStart") String createTimeStart,
+                                        @Param("createTimeEnd") String createTimeEnd, @Param("orderBy") String orderBy,
+                                        @Param("orderDirection") String orderDirection);
+
+    /**
+     * 鍒嗛〉鏌ヨ鍗栧璁㈠崟鍒楄〃
+     */
+    IPage<OrderInfo> selectSellerOrderPage(Page<OrderInfo> page, @Param("providerId") Long providerId,
+                                         @Param("orderStatus") String orderStatus, @Param("paymentStatus") String paymentStatus,
+                                         @Param("productName") String productName, @Param("orderId") String orderId,
+                                         @Param("applyTimeStart") String applyTimeStart, @Param("applyTimeEnd") String applyTimeEnd,
+                                         @Param("createTimeStart") String createTimeStart, @Param("createTimeEnd") String createTimeEnd,
+                                         @Param("orderBy") String orderBy, @Param("orderDirection") String orderDirection);
+
+    /**
+     * 鍒嗛〉鏌ヨ寰呭鎵硅鍗曞垪琛�
+     */
+    IPage<OrderInfo> selectPendingApprovalOrderPage(Page<OrderInfo> page, @Param("orderStatus") String orderStatus,
+                                                   @Param("productName") String productName, @Param("providerName") String providerName,
+                                                   @Param("orderId") String orderId, @Param("applyTimeStart") String applyTimeStart,
+                                                   @Param("applyTimeEnd") String applyTimeEnd, @Param("orderBy") String orderBy,
+                                                   @Param("orderDirection") String orderDirection);
+}
diff --git a/src/main/java/com/webmanage/mapper/PointsFlowMapper.java b/src/main/java/com/webmanage/mapper/PointsFlowMapper.java
new file mode 100644
index 0000000..71d0e43
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/PointsFlowMapper.java
@@ -0,0 +1,32 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.entity.PointsFlow;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 绉垎娴佹按Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface PointsFlowMapper extends BaseMapper<PointsFlow> {
+    
+    /**
+     * 鍒嗛〉鏌ヨ绉垎娴佹按
+     */
+    IPage<PointsFlow> selectPage(Page<PointsFlow> page,
+                                @Param("userId") Long userId,
+                                @Param("unitId") Long unitId,
+                                @Param("dataCategory") String dataCategory,
+                                @Param("dataType") String dataType,
+                                @Param("startTime") String startTime,
+                                @Param("endTime") String endTime,
+                                @Param("year") String year,
+                                @Param("month") String month,
+                                @Param("day") String day);
+}
diff --git a/src/main/java/com/webmanage/mapper/PointsMapper.java b/src/main/java/com/webmanage/mapper/PointsMapper.java
new file mode 100644
index 0000000..34473bf
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/PointsMapper.java
@@ -0,0 +1,24 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.dto.PointsMainQueryDTO;
+import com.webmanage.entity.Points;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 绉垎涓昏〃Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface PointsMapper extends BaseMapper<Points> {
+    
+    /**
+     * 鍒嗛〉鏌ヨ绉垎涓昏〃
+     */
+    IPage<Points> selectPointsMainPage(Page<Points> page, @Param("queryDTO") PointsMainQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/mapper/PointsRuleDetailMapper.java b/src/main/java/com/webmanage/mapper/PointsRuleDetailMapper.java
new file mode 100644
index 0000000..0830499
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/PointsRuleDetailMapper.java
@@ -0,0 +1,15 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.PointsRuleDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 绉垎瑙勫垯璇︽儏Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface PointsRuleDetailMapper extends BaseMapper<PointsRuleDetail> {
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/mapper/PointsRuleMapper.java b/src/main/java/com/webmanage/mapper/PointsRuleMapper.java
new file mode 100644
index 0000000..22a5edf
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/PointsRuleMapper.java
@@ -0,0 +1,15 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.PointsRule;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 绉垎瑙勫垯Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface PointsRuleMapper extends BaseMapper<PointsRule> {
+}
diff --git a/src/main/java/com/webmanage/mapper/ProductPricingMapper.java b/src/main/java/com/webmanage/mapper/ProductPricingMapper.java
new file mode 100644
index 0000000..19e467b
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/ProductPricingMapper.java
@@ -0,0 +1,39 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.webmanage.entity.ProductPricing;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 浜у搧瀹氫环Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface ProductPricingMapper extends BaseMapper<ProductPricing> {
+
+    /**
+     * 鍒嗛〉鏌ヨ浜у搧瀹氫环鍒楄〃
+     */
+    IPage<ProductPricing> selectProductPricingPage(Page<ProductPricing> page, @Param("productId") Long productId);
+
+    /**
+     * 鏍规嵁浜у搧ID鏌ヨ瀹氫环鍒楄〃
+     */
+    List<ProductPricing> selectByProductId(@Param("productId") Long productId);
+
+    /**
+     * 鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环
+     */
+    List<ProductPricing> selectByCondition(@Param("suiteName") String suiteName, 
+                                         @Param("salesForm") String salesForm,
+                                         @Param("customerType") String customerType,
+                                         @Param("priceType") String priceType,
+                                         @Param("isActive") Boolean isActive);
+}
diff --git a/src/main/java/com/webmanage/mapper/UserPointsMapper.java b/src/main/java/com/webmanage/mapper/UserPointsMapper.java
new file mode 100644
index 0000000..183ad79
--- /dev/null
+++ b/src/main/java/com/webmanage/mapper/UserPointsMapper.java
@@ -0,0 +1,26 @@
+package com.webmanage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.webmanage.entity.UserPoints;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 鐢ㄦ埛绉垎Mapper鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Mapper
+public interface UserPointsMapper extends BaseMapper<UserPoints> {
+    
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ绉垎淇℃伅
+     */
+    UserPoints selectByUserId(@Param("userId") Long userId);
+    
+    /**
+     * 鏍规嵁鍗曚綅ID鏌ヨ绉垎淇℃伅
+     */
+    UserPoints selectByUnitId(@Param("unitId") Long unitId);
+}
diff --git a/src/main/java/com/webmanage/service/ApprovalRecordService.java b/src/main/java/com/webmanage/service/ApprovalRecordService.java
new file mode 100644
index 0000000..0f4f11c
--- /dev/null
+++ b/src/main/java/com/webmanage/service/ApprovalRecordService.java
@@ -0,0 +1,45 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.ApprovalActionDTO;
+import com.webmanage.dto.ApprovalQueryDTO;
+import com.webmanage.entity.ApprovalRecord;
+
+import java.util.List;
+
+/**
+ * 瀹℃壒璁板綍Service鎺ュ彛
+ */
+public interface ApprovalRecordService extends IService<ApprovalRecord> {
+
+    /**
+     * 鍒嗛〉鏌ヨ瀹℃壒璁板綍
+     */
+    PageResult<ApprovalRecord> getApprovalRecordPage(ApprovalQueryDTO queryDTO);
+
+    /**
+     * 鍒嗛〉鏌ヨ寰呭鎵硅鍗�
+     */
+    PageResult<ApprovalRecord> getPendingApprovalPage(ApprovalQueryDTO queryDTO);
+
+    /**
+     * 鏍规嵁璁㈠崟ID鏌ヨ瀹℃壒璁板綍
+     */
+    List<ApprovalRecord> getApprovalRecordsByOrderId(String orderId);
+
+    /**
+     * 瀹℃壒璁㈠崟
+     */
+    boolean approveOrder(ApprovalActionDTO actionDTO);
+
+    /**
+     * 鎺堟潈瀹℃壒
+     */
+    boolean authorizeApproval(Long approvalId, Long authorizerId, String authorizerName, String authorizationOpinion);
+
+    /**
+     * 鑾峰彇璁㈠崟褰撳墠瀹℃壒鐘舵��
+     */
+    String getOrderCurrentApprovalStatus(String orderId);
+}
diff --git a/src/main/java/com/webmanage/service/CartService.java b/src/main/java/com/webmanage/service/CartService.java
new file mode 100644
index 0000000..58a08bb
--- /dev/null
+++ b/src/main/java/com/webmanage/service/CartService.java
@@ -0,0 +1,73 @@
+package com.webmanage.service;
+
+import com.webmanage.dto.CartItemDTO;
+import com.webmanage.dto.CartQueryDTO;
+import com.webmanage.vo.CartVO;
+import com.webmanage.vo.CartItemVO;
+
+import java.util.List;
+
+/**
+ * 璐墿杞︽湇鍔℃帴鍙�
+ */
+public interface CartService {
+    /**
+     * 娣诲姞鍟嗗搧鍒拌喘鐗╄溅锛圧edis + 鏁版嵁搴擄級
+     */
+    boolean addToCart(Long userId, Long unitId, CartItemDTO cartItemDTO);
+    
+    /**
+     * 浠庤喘鐗╄溅绉婚櫎鍟嗗搧锛圧edis + 鏁版嵁搴擄級
+     */
+    boolean removeFromCart(Long userId, Long unitId, Long pricingId);
+    
+    /**
+     * 鏇存柊璐墿杞﹀晢鍝佹暟閲忥紙Redis + 鏁版嵁搴擄級
+     */
+    boolean updateCartItemQuantity(Long userId, Long unitId, Long pricingId, Integer quantity);
+    
+    /**
+     * 娓呯┖璐墿杞︼紙Redis + 鏁版嵁搴擄級
+     */
+    boolean clearCart(Long userId, Long unitId);
+    
+    /**
+     * 鑾峰彇璐墿杞︿俊鎭紙浼樺厛Redis锛屽け璐ュ垯浠庢暟鎹簱鍔犺浇锛�
+     */
+    CartVO getCart(Long userId, Long unitId);
+    
+    /**
+     * 鑾峰彇璐墿杞﹀晢鍝佸垪琛紙浼樺厛Redis锛屽け璐ュ垯浠庢暟鎹簱鍔犺浇锛�
+     */
+    List<CartItemVO> getCartItems(Long userId, Long unitId);
+    
+    /**
+     * 妫�鏌ヨ喘鐗╄溅鍟嗗搧搴撳瓨
+     */
+    boolean checkCartItemStock(Long userId, Long unitId, Long pricingId);
+    
+    /**
+     * 鎵归噺鍒犻櫎璐墿杞﹀晢鍝侊紙Redis + 鏁版嵁搴擄級
+     */
+    boolean batchRemoveFromCart(Long userId, Long unitId, List<Long> pricingIds);
+    
+    /**
+     * 鑾峰彇璐墿杞﹀晢鍝佹暟閲忥紙浼樺厛Redis锛屽け璐ュ垯浠庢暟鎹簱鍔犺浇锛�
+     */
+    Integer getCartItemCount(Long userId, Long unitId);
+    
+    /**
+     * 浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹埌Redis
+     */
+    boolean loadCartFromDatabase(Long userId, Long unitId);
+    
+    /**
+     * 鍚屾Redis鏁版嵁鍒版暟鎹簱
+     */
+    boolean syncCartToDatabase(Long userId, Long unitId);
+    
+    /**
+     * 妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存��
+     */
+    boolean checkCartConsistency(Long userId, Long unitId);
+}
diff --git a/src/main/java/com/webmanage/service/MinioService.java b/src/main/java/com/webmanage/service/MinioService.java
new file mode 100644
index 0000000..62099c9
--- /dev/null
+++ b/src/main/java/com/webmanage/service/MinioService.java
@@ -0,0 +1,151 @@
+package com.webmanage.service;
+
+import com.webmanage.common.FileUploadException;
+import com.webmanage.config.MinioConfig;
+import io.minio.*;
+import io.minio.http.Method;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.InputStream;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * MinIO鏈嶅姟绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Slf4j
+@Service
+public class MinioService {
+
+    @Autowired
+    private MinioClient minioClient;
+
+    @Autowired
+    private MinioConfig minioConfig;
+
+    /**
+     * 涓婁紶鏂囦欢
+     */
+    public String uploadFile(MultipartFile file, String folder) {
+        try {
+            // 妫�鏌ュ瓨鍌ㄦ《鏄惁瀛樺湪锛屼笉瀛樺湪鍒欏垱寤�
+            boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder()
+                    .bucket(minioConfig.getBucketName())
+                    .build());
+            
+            if (!bucketExists) {
+                minioClient.makeBucket(MakeBucketArgs.builder()
+                        .bucket(minioConfig.getBucketName())
+                        .build());
+            }
+
+            // 鐢熸垚鏂囦欢鍚�
+            String originalFilename = file.getOriginalFilename();
+            String fileExtension = "";
+            if (originalFilename != null && originalFilename.contains(".")) {
+                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
+            }
+            String fileName = folder + "/" + UUID.randomUUID().toString() + fileExtension;
+
+            // 涓婁紶鏂囦欢
+            minioClient.putObject(PutObjectArgs.builder()
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .stream(file.getInputStream(), file.getSize(), -1)
+                    .contentType(file.getContentType())
+                    .build());
+
+            log.info("鏂囦欢涓婁紶鎴愬姛: {}", fileName);
+            return fileName;
+        } catch (Exception e) {
+            log.error("鏂囦欢涓婁紶澶辫触: ", e);
+            throw new FileUploadException("鏂囦欢涓婁紶澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 涓嬭浇鏂囦欢
+     */
+    public InputStream downloadFile(String fileName) {
+        try {
+            return minioClient.getObject(GetObjectArgs.builder()
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .build());
+        } catch (Exception e) {
+            log.error("鏂囦欢涓嬭浇澶辫触: ", e);
+            throw new FileUploadException("鏂囦欢涓嬭浇澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鍒犻櫎鏂囦欢
+     */
+    public void deleteFile(String fileName) {
+        try {
+            minioClient.removeObject(RemoveObjectArgs.builder()
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .build());
+            log.info("鏂囦欢鍒犻櫎鎴愬姛: {}", fileName);
+        } catch (Exception e) {
+            log.error("鏂囦欢鍒犻櫎澶辫触: ", e);
+            throw new FileUploadException("鏂囦欢鍒犻櫎澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鐢熸垚鏂囦欢棰勮URL
+     */
+    public String getPreviewUrl(String fileName) {
+        try {
+            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
+                    .method(Method.GET)
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .expiry(1, TimeUnit.HOURS)
+                    .build());
+        } catch (Exception e) {
+            log.error("鐢熸垚棰勮URL澶辫触: ", e);
+            throw new FileUploadException("鐢熸垚棰勮URL澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 鐢熸垚鏂囦欢涓嬭浇URL
+     */
+    public String getDownloadUrl(String fileName) {
+        try {
+            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
+                    .method(Method.GET)
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .expiry(24, TimeUnit.HOURS)
+                    .build());
+        } catch (Exception e) {
+            log.error("鐢熸垚涓嬭浇URL澶辫触: ", e);
+            throw new FileUploadException("鐢熸垚涓嬭浇URL澶辫触: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+     */
+    public boolean fileExists(String fileName) {
+        try {
+            minioClient.statObject(StatObjectArgs.builder()
+                    .bucket(minioConfig.getBucketName())
+                    .object(fileName)
+                    .build());
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/service/OrderInfoService.java b/src/main/java/com/webmanage/service/OrderInfoService.java
new file mode 100644
index 0000000..8e85fc7
--- /dev/null
+++ b/src/main/java/com/webmanage/service/OrderInfoService.java
@@ -0,0 +1,65 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.CreateOrderDTO;
+import com.webmanage.dto.OrderQueryDTO;
+import com.webmanage.entity.OrderInfo;
+import com.webmanage.vo.OrderDetailVO;
+
+/**
+ * 璁㈠崟淇℃伅Service鎺ュ彛
+ */
+public interface OrderInfoService extends IService<OrderInfo> {
+
+    /**
+     * 鍒嗛〉鏌ヨ涔板璁㈠崟鍒楄〃
+     */
+    PageResult<OrderInfo> getBuyerOrderPage(OrderQueryDTO queryDTO);
+
+    /**
+     * 鍒嗛〉鏌ヨ鍗栧璁㈠崟鍒楄〃
+     */
+    PageResult<OrderInfo> getSellerOrderPage(OrderQueryDTO queryDTO);
+
+    /**
+     * 鍒嗛〉鏌ヨ寰呭鎵硅鍗曞垪琛�
+     */
+    PageResult<OrderInfo> getPendingApprovalOrderPage(OrderQueryDTO queryDTO);
+
+    /**
+     * 鑾峰彇璁㈠崟璇︽儏
+     */
+    OrderDetailVO getOrderDetail(String orderId);
+
+    /**
+     * 鍒涘缓璁㈠崟锛堝寘鍚鍗曞ご涓庢槑缁嗘彃鍏ワ級锛岃繑鍥炶鍗曠紪鍙�
+     */
+    String createOrder(CreateOrderDTO createOrderDTO);
+
+    /**
+     * 涓婁紶璁㈠崟闄勪欢
+     */
+    boolean uploadOrderAttachment(String orderId, String fileName, String originalName, 
+                                String fileType, Long fileSize, String fileUrl, 
+                                String bucketName, String objectName, Long uploadUserId, 
+                                String uploadUserName, String attachmentType, String description);
+
+    /**
+     * 娣诲姞璁㈠崟璇勪环
+     */
+    boolean addOrderEvaluation(String orderId, Long evaluatorId, String evaluatorName, 
+                             String evaluatorType, String content, Integer rating, 
+                             Integer serviceRating, Integer qualityRating, Integer deliveryRating, 
+                             Boolean isAnonymous);
+
+    /**
+     * 浜ゆ槗纭
+     */
+    boolean confirmTransaction(String orderId, Long userId);
+
+    /**
+     * 鍥炲璇勪环
+     */
+    boolean replyEvaluation(Long evaluationId, String replyContent, Long replyUserId);
+}
diff --git a/src/main/java/com/webmanage/service/OrderNoService.java b/src/main/java/com/webmanage/service/OrderNoService.java
new file mode 100644
index 0000000..5a8b248
--- /dev/null
+++ b/src/main/java/com/webmanage/service/OrderNoService.java
@@ -0,0 +1,16 @@
+package com.webmanage.service;
+
+/**
+ * 璁㈠崟缂栧彿鏈嶅姟
+ */
+public interface OrderNoService {
+    /**
+     * 鐢熸垚鍞竴璁㈠崟鍙凤紙瀛楃涓插舰寮忥紝渚夸簬浣滀负涓氬姟涓婚敭浣跨敤锛�
+     */
+    String generateOrderNo();
+
+    /**
+     * 鐢熸垚鍘熷闆姳ID锛堥暱鏁村瀷锛�
+     */
+    long generateSnowflakeId();
+}
diff --git a/src/main/java/com/webmanage/service/PointsFlowService.java b/src/main/java/com/webmanage/service/PointsFlowService.java
new file mode 100644
index 0000000..7ff3d0d
--- /dev/null
+++ b/src/main/java/com/webmanage/service/PointsFlowService.java
@@ -0,0 +1,56 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.AddPointsFlowDTO;
+import com.webmanage.dto.PointsFlowQueryDTO;
+import com.webmanage.entity.PointsFlow;
+
+import java.util.List;
+
+/**
+ * 绉垎娴佹按Service鎺ュ彛
+ */
+public interface PointsFlowService extends IService<PointsFlow> {
+
+    /**
+     * 鍒嗛〉鏌ヨ涓汉绉垎娴佹按
+     */
+    PageResult<PointsFlow> getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO);
+
+    /**
+     * 鍒嗛〉鏌ヨ鍗曚綅绉垎娴佹按
+     */
+    PageResult<PointsFlow> getUnitPointsFlowPage(PointsFlowQueryDTO queryDTO);
+
+    /**
+     * 鏍规嵁鐢ㄦ埛ID鏌ヨ绉垎娴佹按
+     */
+    List<PointsFlow> getPointsFlowByUserId(Long userId);
+
+    /**
+     * 鏍规嵁鍗曚綅ID鏌ヨ绉垎娴佹按
+     */
+    List<PointsFlow> getPointsFlowByUnitId(Long unitId);
+
+    /**
+     * 璁板綍绉垎娴佹按
+     */
+    boolean recordPointsFlow(Long userId, Long unitId, String flowType, String pointsSource, 
+                           Integer pointsValue, String orderId, String description);
+
+    /**
+     * 鏂板绉垎娴佹按锛堟牴鎹鍒欒嚜鍔ㄨ绠楋級
+     */
+    boolean addPointsFlowByRule(AddPointsFlowDTO addPointsFlowDTO);
+
+    /**
+     * 鑾峰彇鐢ㄦ埛绉垎缁熻
+     */
+    Integer getUserPointsTotal(Long userId);
+
+    /**
+     * 鑾峰彇鍗曚綅绉垎缁熻
+     */
+    Integer getUnitPointsTotal(Long unitId);
+}
diff --git a/src/main/java/com/webmanage/service/PointsRuleDetailService.java b/src/main/java/com/webmanage/service/PointsRuleDetailService.java
new file mode 100644
index 0000000..2777f6d
--- /dev/null
+++ b/src/main/java/com/webmanage/service/PointsRuleDetailService.java
@@ -0,0 +1,11 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.entity.PointsRuleDetail;
+
+/**
+ * 绉垎瑙勫垯璇︽儏Service鎺ュ彛
+ */
+public interface PointsRuleDetailService extends IService<PointsRuleDetail> {
+    // 绉垎瑙勫垯璇︽儏鐩稿叧涓氬姟閫昏緫鏂规硶鍙湪姝ゆ坊鍔�
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/service/PointsRuleService.java b/src/main/java/com/webmanage/service/PointsRuleService.java
new file mode 100644
index 0000000..da6de60
--- /dev/null
+++ b/src/main/java/com/webmanage/service/PointsRuleService.java
@@ -0,0 +1,49 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.PointsRuleDTO;
+import com.webmanage.entity.PointsRule;
+
+import java.util.List;
+
+/**
+ * 绉垎瑙勫垯Service鎺ュ彛
+ */
+public interface PointsRuleService extends IService<PointsRule> {
+
+    /**
+     * 鍒嗛〉鏌ヨ绉垎瑙勫垯
+     */
+    PageResult<PointsRule> getPointsRulePage(Integer pageNum, Integer pageSize, String ruleName, String ruleType);
+
+    /**
+     * 鏂板绉垎瑙勫垯
+     */
+    boolean addPointsRule(PointsRuleDTO pointsRuleDTO);
+
+    /**
+     * 淇敼绉垎瑙勫垯
+     */
+    boolean updatePointsRule(PointsRuleDTO pointsRuleDTO);
+
+    /**
+     * 鍒犻櫎绉垎瑙勫垯
+     */
+    boolean deletePointsRule(Long id);
+
+    /**
+     * 鍚敤/绂佺敤绉垎瑙勫垯
+     */
+    boolean togglePointsRuleStatus(Long id, Boolean isEnabled);
+
+    /**
+     * 鏍规嵁瑙勫垯绫诲瀷鏌ヨ鍚敤鐨勮鍒�
+     */
+    List<PointsRule> getEnabledRulesByType(String ruleType);
+
+    /**
+     * 鏍规嵁瑙﹀彂鏉′欢鏌ヨ閫傜敤鐨勮鍒�
+     */
+    PointsRule getRuleByTriggerCondition(String triggerCondition);
+}
diff --git a/src/main/java/com/webmanage/service/PointsService.java b/src/main/java/com/webmanage/service/PointsService.java
new file mode 100644
index 0000000..d64242a
--- /dev/null
+++ b/src/main/java/com/webmanage/service/PointsService.java
@@ -0,0 +1,17 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.PointsMainQueryDTO;
+import com.webmanage.entity.Points;
+
+/**
+ * 绉垎涓昏〃Service鎺ュ彛
+ */
+public interface PointsService extends IService<Points> {
+    
+    /**
+     * 鍒嗛〉鏌ヨ绉垎涓昏〃
+     */
+    PageResult<Points> getPointsMainPage(PointsMainQueryDTO queryDTO);
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/service/ProductPricingService.java b/src/main/java/com/webmanage/service/ProductPricingService.java
new file mode 100644
index 0000000..1f0b329
--- /dev/null
+++ b/src/main/java/com/webmanage/service/ProductPricingService.java
@@ -0,0 +1,48 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.entity.ProductPricing;
+
+import java.util.List;
+
+/**
+ * 浜у搧瀹氫环鏈嶅姟鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+public interface ProductPricingService extends IService<ProductPricing> {
+
+    /**
+     * 鏂板浜у搧瀹氫环
+     */
+    boolean addProductPricing(ProductPricing productPricing);
+
+    /**
+     * 缂栬緫浜у搧瀹氫环
+     */
+    boolean updateProductPricing(ProductPricing productPricing);
+
+    /**
+     * 鍒犻櫎浜у搧瀹氫环锛堥�昏緫鍒犻櫎锛�
+     */
+    boolean deleteProductPricing(Long id);
+
+    /**
+     * 鍒嗛〉鏌ヨ浜у搧瀹氫环鍒楄〃
+     */
+    IPage<ProductPricing> getProductPricingPage(Page<ProductPricing> page, Long productId);
+
+    /**
+     * 鏍规嵁浜у搧ID鏌ヨ瀹氫环鍒楄〃
+     */
+    List<ProductPricing> getPricingByProductId(Long productId);
+
+    /**
+     * 鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环
+     */
+    List<ProductPricing> getPricingByCondition(String suiteName, String salesForm, 
+                                             String customerType, String priceType, Boolean isActive);
+}
diff --git a/src/main/java/com/webmanage/service/UserPointsService.java b/src/main/java/com/webmanage/service/UserPointsService.java
new file mode 100644
index 0000000..390481f
--- /dev/null
+++ b/src/main/java/com/webmanage/service/UserPointsService.java
@@ -0,0 +1,28 @@
+package com.webmanage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.webmanage.vo.PointsStatsVO;
+
+/**
+ * 鐢ㄦ埛绉垎Service鎺ュ彛
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+public interface UserPointsService extends IService<com.webmanage.entity.UserPoints> {
+    
+    /**
+     * 鑾峰彇涓汉绉垎缁熻
+     */
+    PointsStatsVO getPersonalPointsStats(Long userId);
+    
+    /**
+     * 鑾峰彇鍗曚綅绉垎缁熻
+     */
+    PointsStatsVO getUnitPointsStats(Long unitId);
+    
+    /**
+     * 鏇存柊鐢ㄦ埛绉垎
+     */
+    void updateUserPoints(Long userId, Long unitId, Integer points);
+}
diff --git a/src/main/java/com/webmanage/service/impl/ApprovalRecordServiceImpl.java b/src/main/java/com/webmanage/service/impl/ApprovalRecordServiceImpl.java
new file mode 100644
index 0000000..a7aac05
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/ApprovalRecordServiceImpl.java
@@ -0,0 +1,170 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.BusinessException;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.ApprovalActionDTO;
+import com.webmanage.dto.ApprovalQueryDTO;
+import com.webmanage.entity.ApprovalRecord;
+import com.webmanage.entity.OrderInfo;
+import com.webmanage.mapper.ApprovalRecordMapper;
+import com.webmanage.mapper.OrderInfoMapper;
+import com.webmanage.service.ApprovalRecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 瀹℃壒璁板綍Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class ApprovalRecordServiceImpl extends ServiceImpl<ApprovalRecordMapper, ApprovalRecord> implements ApprovalRecordService {
+
+    @Resource
+    private OrderInfoMapper orderInfoMapper;
+
+    @Override
+    public PageResult<ApprovalRecord> getApprovalRecordPage(ApprovalQueryDTO queryDTO) {
+        Page<ApprovalRecord> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+        IPage<ApprovalRecord> result = baseMapper.selectApprovalRecordPage(
+            page, queryDTO.getOrderId(), queryDTO.getProductName(), queryDTO.getProviderName(),
+            queryDTO.getApproverId(), queryDTO.getApprovalResult(), queryDTO.getApprovalStep(),
+            queryDTO.getNeedAuthorization(),
+            queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null,
+            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
+            queryDTO.getApprovalTimeStart() != null ? queryDTO.getApprovalTimeStart().toString() : null,
+            queryDTO.getApprovalTimeEnd() != null ? queryDTO.getApprovalTimeEnd().toString() : null,
+            queryDTO.getOrderBy(), queryDTO.getOrderDirection()
+        );
+        return new PageResult<ApprovalRecord>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public PageResult<ApprovalRecord> getPendingApprovalPage(ApprovalQueryDTO queryDTO) {
+        Page<ApprovalRecord> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+        IPage<ApprovalRecord> result = baseMapper.selectPendingApprovalPage(
+            page, queryDTO.getOrderId(), queryDTO.getProductName(), queryDTO.getProviderName(),
+            queryDTO.getApprovalStep(), queryDTO.getOrderBy(), queryDTO.getOrderDirection()
+        );
+        return new PageResult<ApprovalRecord>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public List<ApprovalRecord> getApprovalRecordsByOrderId(String orderId) {
+        if (!StringUtils.hasText(orderId)) {
+            throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖");
+        }
+        return baseMapper.selectByOrderId(orderId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean approveOrder(ApprovalActionDTO actionDTO) {
+        // 楠岃瘉璁㈠崟鏄惁瀛樺湪
+        OrderInfo orderInfo = orderInfoMapper.selectById(actionDTO.getOrderId());
+        if (orderInfo == null) {
+            throw new BusinessException("璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 鍒涘缓瀹℃壒璁板綍
+        ApprovalRecord approvalRecord = new ApprovalRecord();
+        approvalRecord.setOrderId(actionDTO.getOrderId());
+        approvalRecord.setApproverId(actionDTO.getApproverId());
+        approvalRecord.setApproverName(actionDTO.getApproverName());
+        approvalRecord.setApproverRole(actionDTO.getApproverRole());
+        approvalRecord.setApprovalStep(actionDTO.getApprovalStep());
+        approvalRecord.setApprovalResult(actionDTO.getApprovalResult());
+        approvalRecord.setApprovalOpinion(actionDTO.getApprovalOpinion());
+        approvalRecord.setApprovalTime(LocalDateTime.now());
+        approvalRecord.setNeedAuthorization(actionDTO.getNeedAuthorization());
+
+        // 濡傛灉闇�瑕佹巿鏉冿紝璁剧疆鎺堟潈浜轰俊鎭�
+        if (Boolean.TRUE.equals(actionDTO.getNeedAuthorization()) && actionDTO.getAuthorizerId() != null) {
+            approvalRecord.setAuthorizerId(actionDTO.getAuthorizerId());
+            approvalRecord.setAuthorizerName(actionDTO.getAuthorizerName());
+            approvalRecord.setAuthorizationOpinion(actionDTO.getAuthorizationOpinion());
+            approvalRecord.setAuthorizationTime(LocalDateTime.now());
+        }
+
+        // 淇濆瓨瀹℃壒璁板綍
+        boolean saved = save(approvalRecord);
+        if (!saved) {
+            throw new BusinessException("淇濆瓨瀹℃壒璁板綍澶辫触");
+        }
+
+        // 鏇存柊璁㈠崟鐘舵��
+        if ("閫氳繃".equals(actionDTO.getApprovalResult())) {
+            orderInfo.setOrderStatus("宸插鎵�");
+            orderInfo.setCurrentStep(actionDTO.getApprovalStep());
+        } else if ("椹冲洖".equals(actionDTO.getApprovalResult())) {
+            orderInfo.setOrderStatus("宸查┏鍥�");
+        }
+
+        int updated = orderInfoMapper.updateById(orderInfo);
+        if (updated <= 0) {
+            throw new BusinessException("鏇存柊璁㈠崟鐘舵�佸け璐�");
+        }
+
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean authorizeApproval(Long approvalId, Long authorizerId, String authorizerName, String authorizationOpinion) {
+        ApprovalRecord approvalRecord = getById(approvalId);
+        if (approvalRecord == null) {
+            throw new BusinessException("瀹℃壒璁板綍涓嶅瓨鍦�");
+        }
+
+        if (!Boolean.TRUE.equals(approvalRecord.getNeedAuthorization())) {
+            throw new BusinessException("璇ュ鎵硅褰曚笉闇�瑕佹巿鏉�");
+        }
+
+        approvalRecord.setAuthorizerId(authorizerId);
+        approvalRecord.setAuthorizerName(authorizerName);
+        approvalRecord.setAuthorizationOpinion(authorizationOpinion);
+        approvalRecord.setAuthorizationTime(LocalDateTime.now());
+
+        return updateById(approvalRecord);
+    }
+
+    @Override
+    public String getOrderCurrentApprovalStatus(String orderId) {
+        if (!StringUtils.hasText(orderId)) {
+            return "鏈煡";
+        }
+
+        QueryWrapper<ApprovalRecord> wrapper = new QueryWrapper<>();
+        wrapper.eq("order_id", orderId)
+               .orderByDesc("created_at")
+               .last("LIMIT 1");
+
+        ApprovalRecord latestRecord = getOne(wrapper);
+        if (latestRecord == null) {
+            return "寰呭鎵�";
+        }
+
+        return latestRecord.getApprovalResult();
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/CartServiceImpl.java b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
new file mode 100644
index 0000000..304a9fe
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
@@ -0,0 +1,488 @@
+package com.webmanage.service.impl;
+
+import com.webmanage.common.BusinessException;
+import com.webmanage.dto.CartItemDTO;
+import com.webmanage.entity.Cart;
+import com.webmanage.entity.ProductPricing;
+import com.webmanage.mapper.CartMapper;
+import com.webmanage.mapper.ProductPricingMapper;
+import com.webmanage.service.CartService;
+import com.webmanage.vo.CartItemVO;
+import com.webmanage.vo.CartVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 璐墿杞︽湇鍔″疄鐜扮被
+ */
+@Slf4j
+@Service
+public class CartServiceImpl implements CartService {
+    
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+    
+    @Resource
+    private CartMapper cartMapper;
+    
+    @Resource
+    private ProductPricingMapper productPricingMapper;
+    
+    // Redis key鍓嶇紑
+    private static final String CART_KEY_PREFIX = "cart:";
+    private static final String CART_ITEM_KEY_PREFIX = "cart_item:";
+    private static final int CART_EXPIRE_DAYS = 30; // 璐墿杞﹁繃鏈熸椂闂�30澶�
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addToCart(Long userId, Long unitId, CartItemDTO cartItemDTO) {
+        try {
+            // 楠岃瘉鍟嗗搧瀹氫环鏄惁瀛樺湪
+            ProductPricing pricing = productPricingMapper.selectById(cartItemDTO.getPricingId());
+            if (pricing == null) {
+                throw new BusinessException("鍟嗗搧瀹氫环涓嶅瓨鍦�");
+            }
+            
+            // 鏋勫缓璐墿杞ey
+            String cartKey = buildCartKey(userId, unitId);
+            String cartItemKey = buildCartItemKey(userId, unitId, cartItemDTO.getPricingId());
+            
+            // 妫�鏌ュ晢鍝佹槸鍚﹀凡鍦ㄨ喘鐗╄溅涓�
+            CartItemVO existingItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
+            if (existingItem != null) {
+                // 濡傛灉宸插瓨鍦紝鏇存柊鏁伴噺
+                existingItem.setQuantity(existingItem.getQuantity() + cartItemDTO.getQuantity());
+                existingItem.setTotalPrice(existingItem.getUnitPrice().multiply(BigDecimal.valueOf(existingItem.getQuantity())));
+                existingItem.setUpdateTime(LocalDateTime.now());
+            } else {
+                // 濡傛灉涓嶅瓨鍦紝鍒涘缓鏂扮殑璐墿杞﹂」
+                existingItem = new CartItemVO();
+                BeanUtils.copyProperties(cartItemDTO, existingItem);
+                existingItem.setAddTime(LocalDateTime.now());
+                existingItem.setUpdateTime(LocalDateTime.now());
+                // 璁$畻灏忚閲戦
+                if (existingItem.getTotalPrice() == null) {
+                    existingItem.setTotalPrice(existingItem.getUnitPrice().multiply(BigDecimal.valueOf(existingItem.getQuantity())));
+                }
+            }
+            
+            // 淇濆瓨鍒癛edis
+            redisTemplate.opsForValue().set(cartItemKey, existingItem, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+            
+            // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
+            updateCartItemList(userId, unitId, cartItemDTO.getPricingId(), true);
+            
+            // 璁剧疆璐墿杞﹁繃鏈熸椂闂�
+            redisTemplate.expire(cartKey, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+            
+            // 鍚屾鍒版暟鎹簱
+            syncCartItemToDatabase(userId, unitId, existingItem);
+            
+            log.info("鐢ㄦ埛{}鎴愬姛娣诲姞鍟嗗搧{}鍒拌喘鐗╄溅", userId, cartItemDTO.getProductName());
+            return true;
+        } catch (Exception e) {
+            log.error("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触", e);
+            throw new BusinessException("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触锛�" + e.getMessage());
+        }
+    }
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean removeFromCart(Long userId, Long unitId, Long pricingId) {
+        try {
+            String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+            
+            // 浠嶳edis涓垹闄ゅ晢鍝侀」
+            Boolean removed = redisTemplate.delete(cartItemKey);
+            if (Boolean.TRUE.equals(removed)) {
+                // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
+                updateCartItemList(userId, unitId, pricingId, false);
+                
+                // 浠庢暟鎹簱涓垹闄�
+                removeCartItemFromDatabase(userId, unitId, pricingId);
+                
+                log.info("鐢ㄦ埛{}鎴愬姛浠庤喘鐗╄溅绉婚櫎鍟嗗搧{}", userId, pricingId);
+                return true;
+            }
+            return false;
+        } catch (Exception e) {
+            log.error("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触", e);
+            throw new BusinessException("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触锛�" + e.getMessage());
+        }
+    }
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateCartItemQuantity(Long userId, Long unitId, Long pricingId, Integer quantity) {
+        try {
+            if (quantity <= 0) {
+                return removeFromCart(userId, unitId, pricingId);
+            }
+            
+            String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+            CartItemVO cartItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
+            if (cartItem == null) {
+                throw new BusinessException("璐墿杞﹀晢鍝佷笉瀛樺湪");
+            }
+            
+            cartItem.setQuantity(quantity);
+            cartItem.setTotalPrice(cartItem.getUnitPrice().multiply(BigDecimal.valueOf(quantity)));
+            cartItem.setUpdateTime(LocalDateTime.now());
+            
+            // 鏇存柊鍒癛edis
+            redisTemplate.opsForValue().set(cartItemKey, cartItem, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+            
+            // 鍚屾鍒版暟鎹簱
+            syncCartItemToDatabase(userId, unitId, cartItem);
+            
+            log.info("鐢ㄦ埛{}鎴愬姛鏇存柊璐墿杞﹀晢鍝亄}鏁伴噺涓簕}", userId, pricingId, quantity);
+            return true;
+        } catch (Exception e) {
+            log.error("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
+            throw new BusinessException("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean clearCart(Long userId, Long unitId) {
+        try {
+            String cartKey = buildCartKey(userId, unitId);
+            List<Long> pricingIds = getCartItemPricingIds(userId, unitId);
+            
+            // 鍒犻櫎鎵�鏈夊晢鍝侀」
+            for (Long pricingId : pricingIds) {
+                String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+                redisTemplate.delete(cartItemKey);
+            }
+            
+            // 鍒犻櫎璐墿杞﹀垪琛�
+            redisTemplate.delete(cartKey);
+            
+            // 娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁
+            clearCartFromDatabase(userId, unitId);
+            
+            log.info("鐢ㄦ埛{}鎴愬姛娓呯┖璐墿杞�", userId);
+            return true;
+        } catch (Exception e) {
+            log.error("娓呯┖璐墿杞﹀け璐�", e);
+            throw new BusinessException("娓呯┖璐墿杞﹀け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @Override
+    public CartVO getCart(Long userId, Long unitId) {
+        try {
+            CartVO cartVO = new CartVO();
+            cartVO.setUserId(userId);
+            cartVO.setUnitId(unitId);
+            
+            List<CartItemVO> items = getCartItems(userId, unitId);
+            cartVO.setItems(items);
+            
+            // 璁$畻鎬绘暟閲忓拰鎬婚噾棰�
+            int totalQuantity = items.stream().mapToInt(item -> item.getQuantity()).sum();
+            BigDecimal totalAmount = items.stream()
+                    .map(item -> item.getTotalPrice())
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            
+            cartVO.setTotalQuantity(totalQuantity);
+            cartVO.setTotalAmount(totalAmount);
+            cartVO.setLastUpdateTime(LocalDateTime.now());
+            
+            return cartVO;
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞︿俊鎭け璐�", e);
+            throw new BusinessException("鑾峰彇璐墿杞︿俊鎭け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @Override
+    public List<CartItemVO> getCartItems(Long userId, Long unitId) {
+        try {
+            // 浼樺厛浠嶳edis鑾峰彇
+            List<CartItemVO> items = getCartItemsFromRedis(userId, unitId);
+            if (items != null && !items.isEmpty()) {
+                return items;
+            }
+            
+            // Redis涓病鏈夋暟鎹紝浠庢暟鎹簱鍔犺浇
+            log.info("Redis涓棤璐墿杞︽暟鎹紝浠庢暟鎹簱鍔犺浇鐢ㄦ埛{}鐨勮喘鐗╄溅", userId);
+            return loadCartFromDatabase(userId, unitId) ? getCartItemsFromRedis(userId, unitId) : new ArrayList<>();
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
+            // 闄嶇骇鍒版暟鎹簱鏌ヨ
+            return getCartItemsFromDatabase(userId, unitId);
+        }
+    }
+    
+    @Override
+    public boolean checkCartItemStock(Long userId, Long unitId, Long pricingId) {
+        // TODO: 瀹炵幇搴撳瓨妫�鏌ラ�昏緫
+        return true;
+    }
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean batchRemoveFromCart(Long userId, Long unitId, List<Long> pricingIds) {
+        try {
+            if (CollectionUtils.isEmpty(pricingIds)) {
+                return true;
+            }
+            
+            for (Long pricingId : pricingIds) {
+                removeFromCart(userId, unitId, pricingId);
+            }
+            
+            return true;
+        } catch (Exception e) {
+            log.error("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐�", e);
+            throw new BusinessException("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐ワ細" + e.getMessage());
+        }
+    }
+    
+    @Override
+    public Integer getCartItemCount(Long userId, Long unitId) {
+        try {
+            // 浼樺厛浠嶳edis鑾峰彇
+            String cartKey = buildCartKey(userId, unitId);
+            List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
+            if (pricingIds != null) {
+                return pricingIds.size();
+            }
+            
+            // 浠庢暟鎹簱鑾峰彇
+            return cartMapper.countByUserIdAndUnitId(userId, unitId);
+        } catch (Exception e) {
+            log.error("鑾峰彇璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
+            return 0;
+        }
+    }
+    
+    @Override
+    public boolean loadCartFromDatabase(Long userId, Long unitId) {
+        try {
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            if (CollectionUtils.isEmpty(cartItems)) {
+                return false;
+            }
+            
+            String cartKey = buildCartKey(userId, unitId);
+            List<Long> pricingIds = new ArrayList<>();
+            
+            for (Cart cartItem : cartItems) {
+                CartItemVO itemVO = convertCartToCartItemVO(cartItem);
+                String cartItemKey = buildCartItemKey(userId, unitId, cartItem.getPricingId());
+                
+                // 淇濆瓨鍒癛edis
+                redisTemplate.opsForValue().set(cartItemKey, itemVO, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+                pricingIds.add(cartItem.getPricingId());
+            }
+            
+            // 淇濆瓨璐墿杞﹀垪琛ㄥ埌Redis
+            redisTemplate.opsForValue().set(cartKey, pricingIds, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+            
+            log.info("鎴愬姛浠庢暟鎹簱鍔犺浇鐢ㄦ埛{}鐨勮喘鐗╄溅鏁版嵁鍒癛edis", userId);
+            return true;
+        } catch (Exception e) {
+            log.error("浠庢暟鎹簱鍔犺浇璐墿杞︽暟鎹け璐�", e);
+            return false;
+        }
+    }
+    
+    @Override
+    public boolean syncCartToDatabase(Long userId, Long unitId) {
+        try {
+            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId);
+            if (CollectionUtils.isEmpty(redisItems)) {
+                return true;
+            }
+            
+            // 娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁
+            clearCartFromDatabase(userId, unitId);
+            
+            // 鍚屾Redis鏁版嵁鍒版暟鎹簱
+            for (CartItemVO item : redisItems) {
+                syncCartItemToDatabase(userId, unitId, item);
+            }
+            
+            log.info("鎴愬姛鍚屾Redis璐墿杞︽暟鎹埌鏁版嵁搴擄紝鐢ㄦ埛{}", userId);
+            return true;
+        } catch (Exception e) {
+            log.error("鍚屾璐墿杞︽暟鎹埌鏁版嵁搴撳け璐�", e);
+            return false;
+        }
+    }
+    
+    @Override
+    public boolean checkCartConsistency(Long userId, Long unitId) {
+        try {
+            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId);
+            List<Cart> dbItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            
+            if (redisItems.size() != dbItems.size()) {
+                log.warn("璐墿杞︽暟鎹笉涓�鑷达細Redis鏁伴噺{}锛屾暟鎹簱鏁伴噺{}", redisItems.size(), dbItems.size());
+                return false;
+            }
+            
+            // 妫�鏌ユ瘡涓晢鍝侀」鏄惁涓�鑷�
+            for (CartItemVO redisItem : redisItems) {
+                boolean found = false;
+                for (Cart dbItem : dbItems) {
+                    if (redisItem.getPricingId().equals(dbItem.getPricingId()) &&
+                        redisItem.getQuantity().equals(dbItem.getQuantity())) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    log.warn("璐墿杞﹀晢鍝侀」涓嶄竴鑷达細pricingId={}", redisItem.getPricingId());
+                    return false;
+                }
+            }
+            
+            return true;
+        } catch (Exception e) {
+            log.error("妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存�уけ璐�", e);
+            return false;
+        }
+    }
+    
+    // ==================== 绉佹湁鏂规硶 ====================
+    
+    private String buildCartKey(Long userId, Long unitId) {
+        return CART_KEY_PREFIX + userId + ":" + unitId;
+    }
+    
+    private String buildCartItemKey(Long userId, Long unitId, Long pricingId) {
+        return CART_ITEM_KEY_PREFIX + userId + ":" + unitId + ":" + pricingId;
+    }
+    
+    private void updateCartItemList(Long userId, Long unitId, Long pricingId, boolean add) {
+        String cartKey = buildCartKey(userId, unitId);
+        List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
+        
+        if (pricingIds == null) {
+            pricingIds = new ArrayList<>();
+        }
+        
+        if (add && !pricingIds.contains(pricingId)) {
+            pricingIds.add(pricingId);
+        } else if (!add) {
+            pricingIds.remove(pricingId);
+        }
+        
+        redisTemplate.opsForValue().set(cartKey, pricingIds, CART_EXPIRE_DAYS, TimeUnit.DAYS);
+    }
+    
+    private List<Long> getCartItemPricingIds(Long userId, Long unitId) {
+        String cartKey = buildCartKey(userId, unitId);
+        List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
+        return pricingIds != null ? pricingIds : new ArrayList<>();
+    }
+    
+    private List<CartItemVO> getCartItemsFromRedis(Long userId, Long unitId) {
+        try {
+            String cartKey = buildCartKey(userId, unitId);
+            List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
+            
+            if (CollectionUtils.isEmpty(pricingIds)) {
+                return new ArrayList<>();
+            }
+            
+            List<CartItemVO> items = new ArrayList<>();
+            for (Long pricingId : pricingIds) {
+                String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+                CartItemVO item = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
+                if (item != null) {
+                    items.add(item);
+                }
+            }
+            
+            return items;
+        } catch (Exception e) {
+            log.error("浠嶳edis鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
+            return new ArrayList<>();
+        }
+    }
+    
+    private List<CartItemVO> getCartItemsFromDatabase(Long userId, Long unitId) {
+        try {
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            List<CartItemVO> items = new ArrayList<>();
+            
+            for (Cart cartItem : cartItems) {
+                items.add(convertCartToCartItemVO(cartItem));
+            }
+            
+            return items;
+        } catch (Exception e) {
+            log.error("浠庢暟鎹簱鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
+            return new ArrayList<>();
+        }
+    }
+    
+    private CartItemVO convertCartToCartItemVO(Cart cart) {
+        CartItemVO itemVO = new CartItemVO();
+        BeanUtils.copyProperties(cart, itemVO);
+        return itemVO;
+    }
+    
+    private void syncCartItemToDatabase(Long userId, Long unitId, CartItemVO item) {
+        try {
+            Cart cart = new Cart();
+            BeanUtils.copyProperties(item, cart);
+            cart.setUserId(userId);
+            cart.setUnitId(unitId);
+            cart.setUpdateTime(LocalDateTime.now());
+            
+            // 妫�鏌ユ槸鍚﹀凡瀛樺湪
+            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, item.getPricingId());
+            if (existingCart != null) {
+                // 鏇存柊
+                cart.setId(existingCart.getId());
+                cartMapper.updateById(cart);
+            } else {
+                // 鏂板
+                cart.setAddTime(LocalDateTime.now());
+                cartMapper.insert(cart);
+            }
+        } catch (Exception e) {
+            log.error("鍚屾璐墿杞﹀晢鍝佸埌鏁版嵁搴撳け璐�", e);
+        }
+    }
+    
+    private void removeCartItemFromDatabase(Long userId, Long unitId, Long pricingId) {
+        try {
+            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, pricingId);
+            if (existingCart != null) {
+                cartMapper.deleteById(existingCart.getId());
+            }
+        } catch (Exception e) {
+            log.error("浠庢暟鎹簱鍒犻櫎璐墿杞﹀晢鍝佸け璐�", e);
+        }
+    }
+    
+    private void clearCartFromDatabase(Long userId, Long unitId) {
+        try {
+            // 浣跨敤閫昏緫鍒犻櫎
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            for (Cart item : cartItems) {
+                cartMapper.deleteById(item.getId());
+            }
+        } catch (Exception e) {
+            log.error("娓呯┖鏁版嵁搴撹喘鐗╄溅澶辫触", e);
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java b/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java
new file mode 100644
index 0000000..92a9b54
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java
@@ -0,0 +1,422 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.BusinessException;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.CreateOrderDTO;
+import com.webmanage.dto.CreateOrderItemDTO;
+import com.webmanage.dto.OrderQueryDTO;
+import com.webmanage.entity.OrderAttachment;
+import com.webmanage.entity.OrderDetail;
+import com.webmanage.entity.OrderEvaluation;
+import com.webmanage.entity.OrderInfo;
+import com.webmanage.mapper.OrderAttachmentMapper;
+import com.webmanage.mapper.OrderDetailMapper;
+import com.webmanage.mapper.OrderEvaluationMapper;
+import com.webmanage.mapper.OrderInfoMapper;
+import com.webmanage.service.OrderInfoService;
+import com.webmanage.service.OrderNoService;
+import com.webmanage.vo.OrderAttachmentVO;
+import com.webmanage.vo.OrderDetailItemVO;
+import com.webmanage.vo.OrderDetailVO;
+import com.webmanage.vo.OrderEvaluationVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 璁㈠崟淇℃伅Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
+
+    @Resource
+    private OrderDetailMapper orderDetailMapper;
+
+    @Resource
+    private OrderAttachmentMapper orderAttachmentMapper;
+
+    @Resource
+    private OrderEvaluationMapper orderEvaluationMapper;
+
+    @Resource
+    private OrderNoService orderNoService;
+
+    @Override
+    public PageResult<OrderInfo> getBuyerOrderPage(OrderQueryDTO queryDTO) {
+        // 鍙傛暟鏍¢獙
+        if (queryDTO.getUserId() == null) {
+            throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+
+        // 鍒涘缓鍒嗛〉瀵硅薄
+        Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+
+        // 鎵ц鍒嗛〉鏌ヨ
+        IPage<OrderInfo> result = baseMapper.selectBuyerOrderPage(
+            page, queryDTO.getUserId(), queryDTO.getUnitId(), queryDTO.getOrderStatus(),
+            queryDTO.getPaymentStatus(), queryDTO.getPaymentType(), queryDTO.getProductName(),
+            queryDTO.getProviderName(), queryDTO.getOrderId(), 
+            queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null,
+            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
+            queryDTO.getCreateTimeStart() != null ? queryDTO.getCreateTimeStart().toString() : null,
+            queryDTO.getCreateTimeEnd() != null ? queryDTO.getCreateTimeEnd().toString() : null,
+            queryDTO.getOrderBy(), queryDTO.getOrderDirection()
+        );
+
+        // 鏋勫缓杩斿洖缁撴灉
+        return new PageResult<OrderInfo>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public PageResult<OrderInfo> getSellerOrderPage(OrderQueryDTO queryDTO) {
+        // 鍙傛暟鏍¢獙
+        if (queryDTO.getUserId() == null) {
+            throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+
+        // 鍒涘缓鍒嗛〉瀵硅薄
+        Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+
+        // 鎵ц鍒嗛〉鏌ヨ
+        IPage<OrderInfo> result = baseMapper.selectSellerOrderPage(
+            page, queryDTO.getUserId(), queryDTO.getOrderStatus(), queryDTO.getPaymentStatus(),
+            queryDTO.getProductName(), queryDTO.getOrderId(),
+            queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null,
+            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
+            queryDTO.getCreateTimeStart() != null ? queryDTO.getCreateTimeStart().toString() : null,
+            queryDTO.getCreateTimeEnd() != null ? queryDTO.getCreateTimeEnd().toString() : null,
+            queryDTO.getOrderBy(), queryDTO.getOrderDirection()
+        );
+
+        // 鏋勫缓杩斿洖缁撴灉
+        return new PageResult<OrderInfo>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public PageResult<OrderInfo> getPendingApprovalOrderPage(OrderQueryDTO queryDTO) {
+        // 鍒涘缓鍒嗛〉瀵硅薄
+        Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+
+        // 鎵ц鍒嗛〉鏌ヨ
+        IPage<OrderInfo> result = baseMapper.selectPendingApprovalOrderPage(
+            page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(),
+            queryDTO.getOrderId(),
+            queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null,
+            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
+            queryDTO.getOrderBy(), queryDTO.getOrderDirection()
+        );
+
+        // 鏋勫缓杩斿洖缁撴灉
+        return new PageResult<OrderInfo>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public OrderDetailVO getOrderDetail(String orderId) {
+        // 鍙傛暟鏍¢獙
+        if (!StringUtils.hasText(orderId)) {
+            throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖");
+        }
+
+        // 鏌ヨ璁㈠崟鍩烘湰淇℃伅
+        OrderInfo orderInfo = this.getById(orderId);
+        if (orderInfo == null) {
+            throw new BusinessException("璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 鏋勫缓璁㈠崟璇︽儏VO
+        OrderDetailVO orderDetailVO = new OrderDetailVO();
+        BeanUtils.copyProperties(orderInfo, orderDetailVO);
+
+        // 鏌ヨ璁㈠崟璇︽儏鍒楄〃
+        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(orderId);
+        List<OrderDetailItemVO> orderDetailItemVOs = orderDetails.stream().map(detail -> {
+            OrderDetailItemVO itemVO = new OrderDetailItemVO();
+            BeanUtils.copyProperties(detail, itemVO);
+            return itemVO;
+        }).collect(Collectors.toList());
+        orderDetailVO.setOrderDetails(orderDetailItemVOs);
+
+        // 鏌ヨ璁㈠崟闄勪欢鍒楄〃
+        List<OrderAttachment> attachments = orderAttachmentMapper.selectByOrderId(orderId);
+        List<OrderAttachmentVO> attachmentVOs = attachments.stream().map(attachment -> {
+            OrderAttachmentVO attachmentVO = new OrderAttachmentVO();
+            BeanUtils.copyProperties(attachment, attachmentVO);
+            return attachmentVO;
+        }).collect(Collectors.toList());
+        orderDetailVO.setAttachments(attachmentVOs);
+
+        // 鏌ヨ璁㈠崟璇勪环
+        OrderEvaluation evaluation = orderEvaluationMapper.selectByOrderId(orderId);
+        if (evaluation != null) {
+            OrderEvaluationVO evaluationVO = new OrderEvaluationVO();
+            BeanUtils.copyProperties(evaluation, evaluationVO);
+            orderDetailVO.setEvaluation(evaluationVO);
+        }
+
+        return orderDetailVO;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public String createOrder(CreateOrderDTO createOrderDTO) {
+        if (createOrderDTO == null || CollectionUtils.isEmpty(createOrderDTO.getItems())) {
+            throw new BusinessException("璁㈠崟淇℃伅涓嶅畬鏁�");
+        }
+        // 鐢熸垚璁㈠崟缂栧彿
+        String orderId = orderNoService.generateOrderNo();
+
+        // 璁$畻鎬婚噾棰�
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        for (CreateOrderItemDTO item : createOrderDTO.getItems()) {
+            BigDecimal unitPrice = item.getUnitPrice();
+            Integer quantity = item.getQuantity();
+            if (unitPrice == null || quantity == null || quantity <= 0) {
+                throw new BusinessException("鏄庣粏椤瑰崟浠锋垨鏁伴噺涓嶅悎娉�");
+            }
+            BigDecimal lineAmount = unitPrice.multiply(BigDecimal.valueOf(quantity));
+            totalAmount = totalAmount.add(lineAmount);
+        }
+
+        // 淇濆瓨璁㈠崟澶�
+        OrderInfo orderInfo = new OrderInfo();
+        orderInfo.setOrderId(orderId);
+        orderInfo.setProductId(createOrderDTO.getItems().get(0).getProductId());
+        orderInfo.setProductName(createOrderDTO.getProductName());
+        orderInfo.setProviderId(createOrderDTO.getProviderId());
+        orderInfo.setProviderName(createOrderDTO.getProviderName());
+        orderInfo.setUserId(createOrderDTO.getUserId());
+        orderInfo.setUnitId(createOrderDTO.getUnitId());
+        orderInfo.setApplyTime(LocalDateTime.now());
+        orderInfo.setOrderStatus("寰呭鎵�");
+        orderInfo.setTotalAmount(createOrderDTO.getTotalAmount() != null ? createOrderDTO.getTotalAmount() : totalAmount);
+        orderInfo.setPaymentType(createOrderDTO.getPaymentType());
+        orderInfo.setPaymentStatus("鏈敮浠�");
+        orderInfo.setBuyerRemarks(createOrderDTO.getBuyerRemarks());
+        orderInfo.setCreatedAt(LocalDateTime.now());
+        orderInfo.setUpdatedAt(LocalDateTime.now());
+
+        int inserted = this.baseMapper.insert(orderInfo);
+        if (inserted <= 0) {
+            throw new BusinessException("淇濆瓨璁㈠崟澶辫触");
+        }
+
+        // 淇濆瓨璁㈠崟鏄庣粏
+        for (CreateOrderItemDTO item : createOrderDTO.getItems()) {
+            OrderDetail detail = new OrderDetail();
+            detail.setOrderId(orderId);
+            detail.setPricingId(item.getPricingId());
+            detail.setProductId(item.getProductId());
+            detail.setSuiteName(item.getSuiteName());
+            detail.setSalesForm(item.getSalesForm());
+            detail.setCustomerType(item.getCustomerType());
+            detail.setAccountLimit(item.getAccountLimit());
+            detail.setConcurrentNodes(item.getConcurrentNodes());
+            detail.setPriceType(item.getPriceType());
+            detail.setPriceUnit(item.getPriceUnit());
+            detail.setUnitPrice(item.getUnitPrice());
+            detail.setQuantity(item.getQuantity());
+            detail.setDuration(item.getDuration());
+            BigDecimal lineAmount = item.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
+            detail.setTotalPrice(item.getTotalPrice() != null ? item.getTotalPrice() : lineAmount);
+            detail.setProviderId(item.getProviderId());
+            detail.setProviderName(item.getProviderName());
+            detail.setRemarks(item.getRemarks());
+            detail.setCreatedAt(LocalDateTime.now());
+            detail.setUpdatedAt(LocalDateTime.now());
+            orderDetailMapper.insert(detail);
+        }
+
+        return orderId;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean uploadOrderAttachment(String orderId, String fileName, String originalName, 
+                                      String fileType, Long fileSize, String fileUrl, 
+                                      String bucketName, String objectName, Long uploadUserId, 
+                                      String uploadUserName, String attachmentType, String description) {
+        // 鍙傛暟鏍¢獙
+        if (!StringUtils.hasText(orderId)) {
+            throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(fileName)) {
+            throw new BusinessException("鏂囦欢鍚嶄笉鑳戒负绌�");
+        }
+
+        // 妫�鏌ヨ鍗曟槸鍚﹀瓨鍦�
+        OrderInfo orderInfo = this.getById(orderId);
+        if (orderInfo == null) {
+            throw new BusinessException("璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 鍒涘缓璁㈠崟闄勪欢
+        OrderAttachment attachment = new OrderAttachment();
+        attachment.setOrderId(orderId);
+        attachment.setFileName(fileName);
+        attachment.setOriginalName(originalName);
+        attachment.setFileType(fileType);
+        attachment.setFileSize(fileSize);
+        attachment.setFileUrl(fileUrl);
+        attachment.setBucketName(bucketName);
+        attachment.setObjectName(objectName);
+        attachment.setUploadUserId(uploadUserId);
+        attachment.setUploadUserName(uploadUserName);
+        attachment.setAttachmentType(attachmentType);
+        attachment.setDescription(description);
+
+        // 淇濆瓨闄勪欢
+        return orderAttachmentMapper.insert(attachment) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addOrderEvaluation(String orderId, Long evaluatorId, String evaluatorName, 
+                                   String evaluatorType, String content, Integer rating, 
+                                   Integer serviceRating, Integer qualityRating, Integer deliveryRating, 
+                                   Boolean isAnonymous) {
+        // 鍙傛暟鏍¢獙
+        if (!StringUtils.hasText(orderId)) {
+            throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖");
+        }
+        if (evaluatorId == null) {
+            throw new BusinessException("璇勪环浜篒D涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(content)) {
+            throw new BusinessException("璇勪环鍐呭涓嶈兘涓虹┖");
+        }
+        if (rating == null || rating < 1 || rating > 5) {
+            throw new BusinessException("璇勫垎蹇呴』鍦�1-5涔嬮棿");
+        }
+
+        // 妫�鏌ヨ鍗曟槸鍚﹀瓨鍦�
+        OrderInfo orderInfo = this.getById(orderId);
+        if (orderInfo == null) {
+            throw new BusinessException("璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 妫�鏌ユ槸鍚﹀凡缁忚瘎浠疯繃
+        OrderEvaluation existingEvaluation = orderEvaluationMapper.selectByOrderId(orderId);
+        if (existingEvaluation != null) {
+            throw new BusinessException("璇ヨ鍗曞凡缁忚瘎浠疯繃浜�");
+        }
+
+        // 鍒涘缓璁㈠崟璇勪环
+        OrderEvaluation evaluation = new OrderEvaluation();
+        evaluation.setOrderId(orderId);
+        evaluation.setEvaluatorId(evaluatorId);
+        evaluation.setEvaluatorName(evaluatorName);
+        evaluation.setEvaluatorType(evaluatorType);
+        evaluation.setContent(content);
+        evaluation.setRating(rating);
+        evaluation.setServiceRating(serviceRating);
+        evaluation.setQualityRating(qualityRating);
+        evaluation.setDeliveryRating(deliveryRating);
+        evaluation.setIsAnonymous(isAnonymous != null ? isAnonymous : false);
+
+        // 淇濆瓨璇勪环
+        return orderEvaluationMapper.insert(evaluation) > 0;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean confirmTransaction(String orderId, Long userId) {
+        // 鍙傛暟鏍¢獙
+        if (!StringUtils.hasText(orderId)) {
+            throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖");
+        }
+        if (userId == null) {
+            throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+
+        // 鏌ヨ璁㈠崟淇℃伅
+        OrderInfo orderInfo = this.getById(orderId);
+        if (orderInfo == null) {
+            throw new BusinessException("璁㈠崟涓嶅瓨鍦�");
+        }
+
+        // 妫�鏌ヨ鍗曠姸鎬�
+        if (!"寰呬氦鏄撶‘璁�".equals(orderInfo.getOrderStatus())) {
+            throw new BusinessException("璁㈠崟鐘舵�佷笉姝g‘锛屾棤娉曠‘璁や氦鏄�");
+        }
+
+        // 妫�鏌ョ敤鎴锋潈闄�
+        if (!userId.equals(orderInfo.getUserId())) {
+            throw new BusinessException("鏃犳潈闄愭搷浣滄璁㈠崟");
+        }
+
+        // 鏇存柊璁㈠崟鐘舵��
+        orderInfo.setOrderStatus("宸插畬鎴�");
+        orderInfo.setUpdatedAt(LocalDateTime.now());
+
+        // 濡傛灉鏄Н鍒嗕氦鏄擄紝闇�瑕佹墸闄ょН鍒�
+        if ("绉垎".equals(orderInfo.getPaymentType())) {
+            // TODO: 瀹炵幇绉垎鎵i櫎閫昏緫
+            log.info("绉垎浜ゆ槗纭锛岃鍗旾D: {}, 闇�瑕佹墸闄ょН鍒�", orderId);
+        }
+
+        // 淇濆瓨璁㈠崟
+        return this.updateById(orderInfo);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean replyEvaluation(Long evaluationId, String replyContent, Long replyUserId) {
+        // 鍙傛暟鏍¢獙
+        if (evaluationId == null) {
+            throw new BusinessException("璇勪环ID涓嶈兘涓虹┖");
+        }
+        if (!StringUtils.hasText(replyContent)) {
+            throw new BusinessException("鍥炲鍐呭涓嶈兘涓虹┖");
+        }
+        if (replyUserId == null) {
+            throw new BusinessException("鍥炲鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+
+        // 鏌ヨ璇勪环淇℃伅
+        OrderEvaluation evaluation = orderEvaluationMapper.selectById(evaluationId);
+        if (evaluation == null) {
+            throw new BusinessException("璇勪环涓嶅瓨鍦�");
+        }
+
+        // 鏇存柊鍥炲淇℃伅
+        evaluation.setReplyContent(replyContent);
+        evaluation.setReplyUserId(replyUserId);
+        evaluation.setReplyTime(LocalDateTime.now());
+        evaluation.setUpdatedAt(LocalDateTime.now());
+
+        // 淇濆瓨璇勪环
+        return orderEvaluationMapper.updateById(evaluation) > 0;
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/OrderNoServiceImpl.java b/src/main/java/com/webmanage/service/impl/OrderNoServiceImpl.java
new file mode 100644
index 0000000..4aec738
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/OrderNoServiceImpl.java
@@ -0,0 +1,50 @@
+package com.webmanage.service.impl;
+
+import com.webmanage.service.OrderNoService;
+import com.webmanage.util.SnowflakeIdWorker;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 璁㈠崟缂栧彿鏈嶅姟瀹炵幇
+ */
+@Service
+public class OrderNoServiceImpl implements OrderNoService {
+
+    @Value("${snowflake.worker-id:1}")
+    private long workerId;
+
+    @Value("${snowflake.datacenter-id:1}")
+    private long datacenterId;
+
+    @Value("${snowflake.twepoch-ms:1577808000000}") // 2020-01-01 00:00:00
+    private long twepochMs;
+
+    private SnowflakeIdWorker idWorker;
+
+    private static final DateTimeFormatter ORDER_PREFIX_FMT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+
+    @PostConstruct
+    public void init() {
+        this.idWorker = new SnowflakeIdWorker(workerId, datacenterId, twepochMs);
+    }
+
+    @Override
+    public String generateOrderNo() {
+        long id = generateSnowflakeId();
+        String timePrefix = LocalDateTime.now().format(ORDER_PREFIX_FMT);
+        // 璁㈠崟鍙锋牸寮忥細鏃堕棿鍓嶇紑 + 闆姳ID鍚�10浣嶏紝淇濊瘉闀垮害涓庢帓搴忓彲璇绘��
+        String idStr = String.valueOf(id);
+        String tail = idStr.length() > 10 ? idStr.substring(idStr.length() - 10) : String.format("%010d", id);
+        return timePrefix + tail;
+    }
+
+    @Override
+    public long generateSnowflakeId() {
+        return idWorker.nextId();
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java b/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java
new file mode 100644
index 0000000..ac0d99d
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java
@@ -0,0 +1,401 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.BusinessException;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.AddPointsFlowDTO;
+import com.webmanage.dto.PointsFlowQueryDTO;
+import com.webmanage.entity.PointsFlow;
+import com.webmanage.entity.PointsRule;
+import com.webmanage.entity.UserPoints;
+import com.webmanage.mapper.PointsFlowMapper;
+import com.webmanage.mapper.UserPointsMapper;
+import com.webmanage.service.PointsFlowService;
+import com.webmanage.service.PointsRuleService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 绉垎娴佹按Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class PointsFlowServiceImpl extends ServiceImpl<PointsFlowMapper, PointsFlow> implements PointsFlowService {
+
+    @Resource
+    private UserPointsMapper userPointsMapper;
+
+    @Resource
+    private PointsRuleService pointsRuleService;
+
+    @Override
+    public PageResult<PointsFlow> getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO) {
+        if (queryDTO.getUserId() == null) {
+            throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+
+        Page<PointsFlow> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+        
+        QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("user_id", queryDTO.getUserId());
+        
+        buildQueryWrapper(wrapper, queryDTO);
+        
+        IPage<PointsFlow> result = page(page, wrapper);
+        
+        return new PageResult<PointsFlow>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public PageResult<PointsFlow> getUnitPointsFlowPage(PointsFlowQueryDTO queryDTO) {
+        if (queryDTO.getUnitId() == null) {
+            throw new BusinessException("鍗曚綅ID涓嶈兘涓虹┖");
+        }
+
+        Page<PointsFlow> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+        
+        QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("unit_id", queryDTO.getUnitId());
+        
+        buildQueryWrapper(wrapper, queryDTO);
+        
+        IPage<PointsFlow> result = page(page, wrapper);
+        
+        return new PageResult<PointsFlow>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public List<PointsFlow> getPointsFlowByUserId(Long userId) {
+        if (userId == null) {
+            throw new BusinessException("鐢ㄦ埛ID涓嶈兘涓虹┖");
+        }
+        
+        QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("user_id", userId)
+               .orderByDesc("created_at");
+        
+        return list(wrapper);
+    }
+
+    @Override
+    public List<PointsFlow> getPointsFlowByUnitId(Long unitId) {
+        if (unitId == null) {
+            throw new BusinessException("鍗曚綅ID涓嶈兘涓虹┖");
+        }
+        
+        QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("unit_id", unitId)
+               .orderByDesc("created_at");
+        
+        return list(wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean recordPointsFlow(Long userId, Long unitId, String flowType, String pointsSource, 
+                                  Integer pointsValue, String orderId, String description) {
+        if (userId == null || unitId == null || !StringUtils.hasText(flowType) || 
+            !StringUtils.hasText(pointsSource) || pointsValue == null) {
+            throw new BusinessException("鍙傛暟涓嶅畬鏁�");
+        }
+
+        // 鍒涘缓绉垎娴佹按璁板綍
+        PointsFlow pointsFlow = new PointsFlow();
+        pointsFlow.setUserId(userId);
+        pointsFlow.setUnitId(unitId);
+        pointsFlow.setDataType(flowType);
+        pointsFlow.setDataCategory(pointsSource);
+        pointsFlow.setPoints(pointsValue);
+        pointsFlow.setName(description);
+        pointsFlow.setFlowTime(LocalDateTime.now());
+
+        boolean saved = save(pointsFlow);
+        if (!saved) {
+            throw new BusinessException("淇濆瓨绉垎娴佹按澶辫触");
+        }
+
+        // 鏇存柊鐢ㄦ埛绉垎
+        updateUserPoints(userId, unitId, pointsValue);
+
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addPointsFlowByRule(AddPointsFlowDTO addPointsFlowDTO) {
+        if (addPointsFlowDTO == null) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        Long userId = addPointsFlowDTO.getUserId();
+        Long unitId = addPointsFlowDTO.getUnitId();
+        String ruleType = addPointsFlowDTO.getRuleType();
+        String ruleName = addPointsFlowDTO.getRuleName();
+        Integer count = addPointsFlowDTO.getCount() != null ? addPointsFlowDTO.getCount() : 1;
+
+        // 鏌ヨ绉垎瑙勫垯
+        PointsRule pointsRule = pointsRuleService.getRuleByTriggerCondition(ruleName);
+        if (pointsRule == null) {
+            throw new BusinessException("绉垎瑙勫垯涓嶅瓨鍦ㄦ垨鏈惎鐢�: " + ruleName);
+        }
+
+        // 楠岃瘉瑙勫垯绫诲瀷鏄惁鍖归厤
+        if (!ruleType.equals(pointsRule.getRuleType())) {
+            throw new BusinessException("瑙勫垯绫诲瀷涓嶅尮閰嶏紝鏈熸湜: " + pointsRule.getRuleType() + "锛屽疄闄�: " + ruleType);
+        }
+
+        // 璁$畻绉垎鍊�
+        Integer basePoints = pointsRule.getPointsValue() != null ? pointsRule.getPointsValue() : 0;
+        Integer totalPoints = basePoints * count;
+
+        // 濡傛灉鏄秷璐圭被鍨嬶紝绉垎涓鸿礋鏁�
+        if ("娑堣垂".equals(ruleType)) {
+            totalPoints = -totalPoints;
+        }
+
+        // 妫�鏌ユ瘡鏃ョН鍒嗕笂闄�
+        if (basePoints > 0 && pointsRule.getPriority() != null && pointsRule.getPriority() > 0) {
+            checkDailyLimit(userId, unitId, ruleName, totalPoints, pointsRule.getPriority());
+        }
+
+        // 鍒涘缓绉垎娴佹按璁板綍
+        PointsFlow pointsFlow = new PointsFlow();
+        pointsFlow.setUserId(userId);
+        pointsFlow.setUnitId(unitId);
+        pointsFlow.setDataType(ruleType);
+        pointsFlow.setDataCategory(ruleName);
+        pointsFlow.setPoints(totalPoints);
+        pointsFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : pointsRule.getRuleDescription());
+        pointsFlow.setFlowTime(LocalDateTime.now());
+
+        boolean saved = save(pointsFlow);
+        if (!saved) {
+            throw new BusinessException("淇濆瓨绉垎娴佹按澶辫触");
+        }
+
+        // 鏇存柊鐢ㄦ埛绉垎璐︽埛
+        updateUserPointsByRule(userId, unitId, totalPoints, ruleType);
+
+        return true;
+    }
+
+    @Override
+    public Integer getUserPointsTotal(Long userId) {
+        if (userId == null) {
+            return 0;
+        }
+        
+        QueryWrapper<UserPoints> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("user_id", userId);
+        
+        UserPoints userPoints = userPointsMapper.selectOne(wrapper);
+        return userPoints != null ? userPoints.getBalance() : 0;
+    }
+
+    @Override
+    public Integer getUnitPointsTotal(Long unitId) {
+        if (unitId == null) {
+            return 0;
+        }
+        
+        QueryWrapper<UserPoints> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("unit_id", unitId);
+        
+        UserPoints userPoints = userPointsMapper.selectOne(wrapper);
+        return userPoints != null ? userPoints.getBalance() : 0;
+    }
+
+    /**
+     * 鏋勫缓鏌ヨ鏉′欢
+     */
+    private void buildQueryWrapper(QueryWrapper<PointsFlow> wrapper, PointsFlowQueryDTO queryDTO) {
+        if (StringUtils.hasText(queryDTO.getFlowType())) {
+            wrapper.eq("flow_type", queryDTO.getFlowType());
+        }
+        if (StringUtils.hasText(queryDTO.getPointsSource())) {
+            wrapper.eq("points_source", queryDTO.getPointsSource());
+        }
+        if (StringUtils.hasText(queryDTO.getOrderId())) {
+            wrapper.eq("order_id", queryDTO.getOrderId());
+        }
+        if (queryDTO.getStartTime() != null) {
+            wrapper.ge("flow_time", queryDTO.getStartTime());
+        }
+        if (queryDTO.getEndTime() != null) {
+            wrapper.le("flow_time", queryDTO.getEndTime());
+        }
+        
+        wrapper.orderByDesc("flow_time");
+    }
+
+    /**
+     * 妫�鏌ユ瘡鏃ョН鍒嗕笂闄�
+     */
+    private void checkDailyLimit(Long userId, Long unitId, String ruleName, Integer currentPoints, Integer priority) {
+        // 鑾峰彇浠婃棩寮�濮嬪拰缁撴潫鏃堕棿
+        LocalDate today = LocalDate.now();
+        LocalDateTime startOfDay = today.atStartOfDay();
+        LocalDateTime endOfDay = today.atTime(23, 59, 59);
+
+        // 鏌ヨ浠婃棩璇ヨ鍒欑殑绉垎娴佹按
+        QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("user_id", userId)
+               .eq("unit_id", unitId)
+               .eq("data_category", ruleName)
+               .ge("flow_time", startOfDay)
+               .le("flow_time", endOfDay);
+
+        List<PointsFlow> todayFlows = list(wrapper);
+        
+        // 璁$畻浠婃棩绱绉垎
+        int todayTotal = todayFlows.stream()
+                .mapToInt(flow -> flow.getPoints() != null ? flow.getPoints() : 0)
+                .sum();
+
+        // 濡傛灉浠婃棩绱绉垎瓒呰繃浼樺厛绾ч檺鍒讹紝鍒欐姏鍑哄紓甯�
+        if (Math.abs(todayTotal) >= priority) {
+            throw new BusinessException("浠婃棩璇ヨ鍒欑Н鍒嗗凡杈句笂闄�: " + priority);
+        }
+    }
+
+    /**
+     * 鏇存柊鐢ㄦ埛绉垎
+     */
+    private void updateUserPoints(Long userId, Long unitId, Integer pointsValue) {
+        // 鏇存柊涓汉绉垎
+        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
+        userWrapper.eq("deleted", 0)
+                  .eq("user_id", userId);
+        
+        UserPoints userPoints = userPointsMapper.selectOne(userWrapper);
+        if (userPoints == null) {
+            userPoints = new UserPoints();
+            userPoints.setUserId(userId);
+            userPoints.setUnitId(unitId);
+            userPoints.setBalance(pointsValue);
+            userPointsMapper.insert(userPoints);
+        } else {
+            userPoints.setBalance(userPoints.getBalance() + pointsValue);
+            userPoints.setUpdateTime(LocalDateTime.now());
+            userPointsMapper.updateById(userPoints);
+        }
+
+        // 鏇存柊鍗曚綅绉垎
+        QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>();
+        unitWrapper.eq("deleted", 0)
+                  .eq("unit_id", unitId);
+        
+        UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper);
+        if (unitPoints == null) {
+            unitPoints = new UserPoints();
+            unitPoints.setUserId(userId);
+            unitPoints.setUnitId(unitId);
+            unitPoints.setBalance(pointsValue);
+            userPointsMapper.insert(unitPoints);
+        } else {
+            unitPoints.setBalance(unitPoints.getBalance() + pointsValue);
+            unitPoints.setUpdateTime(LocalDateTime.now());
+            userPointsMapper.updateById(unitPoints);
+        }
+    }
+
+    /**
+     * 鏍规嵁瑙勫垯鏇存柊鐢ㄦ埛绉垎璐︽埛
+     */
+    private void updateUserPointsByRule(Long userId, Long unitId, Integer pointsValue, String ruleType) {
+        // 鏇存柊涓汉绉垎璐︽埛
+        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
+        userWrapper.eq("deleted", 0)
+                  .eq("user_id", userId);
+        
+        UserPoints userPoints = userPointsMapper.selectOne(userWrapper);
+        if (userPoints == null) {
+            userPoints = new UserPoints();
+            userPoints.setUserId(userId);
+            userPoints.setUnitId(unitId);
+            userPoints.setBalance(pointsValue);
+            userPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0);
+            userPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0);
+            userPointsMapper.insert(userPoints);
+        } else {
+            userPoints.setBalance(userPoints.getBalance() + pointsValue);
+            
+            // 鏇存柊绱鑾峰彇绉垎
+            if (pointsValue > 0) {
+                userPoints.setTotalEarned(userPoints.getTotalEarned() != null ? 
+                    userPoints.getTotalEarned() + pointsValue : pointsValue);
+            }
+            
+            // 鏇存柊绱娑堣�楃Н鍒�
+            if (pointsValue < 0) {
+                userPoints.setTotalConsumed(userPoints.getTotalConsumed() != null ? 
+                    userPoints.getTotalConsumed() + Math.abs(pointsValue) : Math.abs(pointsValue));
+            }
+            
+            userPoints.setUpdateTime(LocalDateTime.now());
+            userPointsMapper.updateById(userPoints);
+        }
+
+        // 鏇存柊鍗曚綅绉垎璐︽埛
+        QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>();
+        unitWrapper.eq("deleted", 0)
+                  .eq("unit_id", unitId);
+        
+        UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper);
+        if (unitPoints == null) {
+            unitPoints = new UserPoints();
+            unitPoints.setUserId(userId);
+            unitPoints.setUnitId(unitId);
+            unitPoints.setBalance(pointsValue);
+            unitPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0);
+            unitPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0);
+            userPointsMapper.insert(unitPoints);
+        } else {
+            unitPoints.setBalance(unitPoints.getBalance() + pointsValue);
+            
+            // 鏇存柊绱鑾峰彇绉垎
+            if (pointsValue > 0) {
+                unitPoints.setTotalEarned(unitPoints.getTotalEarned() != null ? 
+                    unitPoints.getTotalEarned() + pointsValue : pointsValue);
+            }
+            
+            // 鏇存柊绱娑堣�楃Н鍒�
+            if (pointsValue < 0) {
+                unitPoints.setTotalConsumed(unitPoints.getTotalConsumed() != null ? 
+                    unitPoints.getTotalConsumed() + Math.abs(pointsValue) : Math.abs(pointsValue));
+            }
+            
+            unitPoints.setUpdateTime(LocalDateTime.now());
+            userPointsMapper.updateById(unitPoints);
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/PointsRuleDetailServiceImpl.java b/src/main/java/com/webmanage/service/impl/PointsRuleDetailServiceImpl.java
new file mode 100644
index 0000000..657f145
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/PointsRuleDetailServiceImpl.java
@@ -0,0 +1,17 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.entity.PointsRuleDetail;
+import com.webmanage.mapper.PointsRuleDetailMapper;
+import com.webmanage.service.PointsRuleDetailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 绉垎瑙勫垯璇︽儏Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class PointsRuleDetailServiceImpl extends ServiceImpl<PointsRuleDetailMapper, PointsRuleDetail> implements PointsRuleDetailService {
+    // 绉垎瑙勫垯璇︽儏鐩稿叧涓氬姟閫昏緫瀹炵幇鍙湪姝ゆ坊鍔�
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/service/impl/PointsRuleServiceImpl.java b/src/main/java/com/webmanage/service/impl/PointsRuleServiceImpl.java
new file mode 100644
index 0000000..f61054e
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/PointsRuleServiceImpl.java
@@ -0,0 +1,185 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.BusinessException;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.PointsRuleDTO;
+import com.webmanage.entity.Points;
+import com.webmanage.entity.PointsRule;
+import com.webmanage.entity.PointsRuleDetail;
+import com.webmanage.mapper.PointsRuleMapper;
+import com.webmanage.service.PointsRuleService;
+import com.webmanage.service.PointsService;
+import com.webmanage.service.PointsRuleDetailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 绉垎瑙勫垯Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class PointsRuleServiceImpl extends ServiceImpl<PointsRuleMapper, PointsRule> implements PointsRuleService {
+    
+    @Autowired
+    private PointsService pointsService;
+    
+    @Autowired
+    private PointsRuleDetailService pointsRuleDetailService;
+
+    @Override
+    public PageResult<PointsRule> getPointsRulePage(Integer pageNum, Integer pageSize, String ruleName, String ruleType) {
+        Page<PointsRule> page = new Page<>(pageNum, pageSize);
+        
+        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0);
+        
+        if (StringUtils.hasText(ruleName)) {
+            wrapper.like("rule_name", ruleName);
+        }
+        if (StringUtils.hasText(ruleType)) {
+            wrapper.eq("rule_type", ruleType);
+        }
+        
+        wrapper.orderByDesc("priority", "created_at");
+        
+        IPage<PointsRule> result = page(page, wrapper);
+        
+        return new PageResult<PointsRule>(
+            result.getRecords(),
+            result.getTotal(),
+            pageNum.longValue(),
+            pageSize.longValue(),
+            result.getPages()
+        );
+    }
+
+    @Override
+    public boolean addPointsRule(PointsRuleDTO pointsRuleDTO) {
+        // 楠岃瘉瑙勫垯鍚嶇О鏄惁閲嶅
+        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
+        wrapper.eq("rule_name", pointsRuleDTO.getRuleName())
+               .eq("deleted", 0);
+        
+        if (count(wrapper) > 0) {
+            throw new BusinessException("瑙勫垯鍚嶇О宸插瓨鍦�");
+        }
+        
+        PointsRule pointsRule = new PointsRule();
+        BeanUtils.copyProperties(pointsRuleDTO, pointsRule);
+        
+        return save(pointsRule);
+    }
+
+    @Override
+    public boolean updatePointsRule(PointsRuleDTO pointsRuleDTO) {
+        if (pointsRuleDTO.getId() == null) {
+            throw new BusinessException("瑙勫垯ID涓嶈兘涓虹┖");
+        }
+        
+        PointsRule existingRule = getById(pointsRuleDTO.getId());
+        if (existingRule == null) {
+            throw new BusinessException("绉垎瑙勫垯涓嶅瓨鍦�");
+        }
+        
+        // 楠岃瘉瑙勫垯鍚嶇О鏄惁閲嶅锛堟帓闄よ嚜韬級
+        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
+        wrapper.eq("rule_name", pointsRuleDTO.getRuleName())
+               .eq("deleted", 0)
+               .ne("id", pointsRuleDTO.getId());
+        
+        if (count(wrapper) > 0) {
+            throw new BusinessException("瑙勫垯鍚嶇О宸插瓨鍦�");
+        }
+        
+        // 鍒涘缓鏂扮殑绉垎涓昏〃璁板綍
+        Points points = new Points();
+        points.setPointsName(pointsRuleDTO.getRuleName() + "_" + System.currentTimeMillis());
+        points.setEffectiveStart(LocalDateTime.now());
+        points.setModifierId(1L); // 杩欓噷搴旇浠庝笂涓嬫枃涓幏鍙栧綋鍓嶇敤鎴稩D
+        points.setModifierName("admin"); // 杩欓噷搴旇浠庝笂涓嬫枃涓幏鍙栧綋鍓嶇敤鎴峰悕
+        points.setVersion(1.0f);
+        points.setStatus(0);
+        pointsService.save(points);
+        
+        // 鍒涘缓绉垎瑙勫垯璇︽儏璁板綍
+        PointsRuleDetail pointsRuleDetail = new PointsRuleDetail();
+        pointsRuleDetail.setRuleId(pointsRuleDTO.getId());
+        pointsRuleDetail.setPointsId(points.getId());
+        pointsRuleDetail.setPointsValue(pointsRuleDTO.getPointsValue());
+        pointsRuleDetail.setEffectiveStart(LocalDateTime.now());
+        pointsRuleDetailService.save(pointsRuleDetail);
+        
+        BeanUtils.copyProperties(pointsRuleDTO, existingRule);
+        existingRule.setUpdatedAt(LocalDateTime.now());
+        
+        return updateById(existingRule);
+    }
+
+    @Override
+    public boolean deletePointsRule(Long id) {
+        if (id == null) {
+            throw new BusinessException("瑙勫垯ID涓嶈兘涓虹┖");
+        }
+        
+        PointsRule pointsRule = getById(id);
+        if (pointsRule == null) {
+            throw new BusinessException("绉垎瑙勫垯涓嶅瓨鍦�");
+        }
+        
+        return removeById(id);
+    }
+
+    @Override
+    public boolean togglePointsRuleStatus(Long id, Boolean isEnabled) {
+        if (id == null) {
+            throw new BusinessException("瑙勫垯ID涓嶈兘涓虹┖");
+        }
+        
+        PointsRule pointsRule = getById(id);
+        if (pointsRule == null) {
+            throw new BusinessException("绉垎瑙勫垯涓嶅瓨鍦�");
+        }
+        
+        pointsRule.setIsEnabled(isEnabled);
+        pointsRule.setUpdatedAt(LocalDateTime.now());
+        
+        return updateById(pointsRule);
+    }
+
+    @Override
+    public List<PointsRule> getEnabledRulesByType(String ruleType) {
+        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("is_enabled", true)
+               .eq("rule_type", ruleType)
+               .orderByAsc("priority", "created_at");
+        
+        return list(wrapper);
+    }
+
+    @Override
+    public PointsRule getRuleByTriggerCondition(String triggerCondition) {
+        if (!StringUtils.hasText(triggerCondition)) {
+            return null;
+        }
+        
+        QueryWrapper<PointsRule> wrapper = new QueryWrapper<>();
+        wrapper.eq("deleted", 0)
+               .eq("is_enabled", true)
+               .eq("trigger_condition", triggerCondition)
+               .orderByAsc("priority")
+               .last("LIMIT 1");
+        
+        return getOne(wrapper);
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/PointsServiceImpl.java b/src/main/java/com/webmanage/service/impl/PointsServiceImpl.java
new file mode 100644
index 0000000..40a4644
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/PointsServiceImpl.java
@@ -0,0 +1,38 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.PageResult;
+import com.webmanage.dto.PointsMainQueryDTO;
+import com.webmanage.entity.Points;
+import com.webmanage.mapper.PointsMapper;
+import com.webmanage.service.PointsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 绉垎涓昏〃Service瀹炵幇绫�
+ */
+@Slf4j
+@Service
+public class PointsServiceImpl extends ServiceImpl<PointsMapper, Points> implements PointsService {
+    
+    @Override
+    public PageResult<Points> getPointsMainPage(PointsMainQueryDTO queryDTO) {
+        // 鍒涘缓鍒嗛〉瀵硅薄
+        Page<Points> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
+        
+        // 鎵ц鍒嗛〉鏌ヨ
+        IPage<Points> result = baseMapper.selectPointsMainPage(page, queryDTO);
+        
+        // 鏋勫缓杩斿洖缁撴灉
+        return new PageResult<Points>(
+            result.getRecords(),
+            result.getTotal(),
+            queryDTO.getPageNum().longValue(),
+            queryDTO.getPageSize().longValue(),
+            result.getPages()
+        );
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/webmanage/service/impl/ProductPricingServiceImpl.java b/src/main/java/com/webmanage/service/impl/ProductPricingServiceImpl.java
new file mode 100644
index 0000000..f14987b
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/ProductPricingServiceImpl.java
@@ -0,0 +1,188 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.common.BusinessException;
+import com.webmanage.entity.ProductPricing;
+import com.webmanage.mapper.ProductPricingMapper;
+import com.webmanage.service.ProductPricingService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 浜у搧瀹氫环鏈嶅姟瀹炵幇绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Slf4j
+@Service
+public class ProductPricingServiceImpl extends ServiceImpl<ProductPricingMapper, ProductPricing> implements ProductPricingService {
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addProductPricing(ProductPricing productPricing) {
+        try {
+            // 璁剧疆鍒涘缓鏃堕棿
+            productPricing.setCreatedAt(LocalDateTime.now());
+            productPricing.setUpdatedAt(LocalDateTime.now());
+            
+            // 楠岃瘉蹇呭~瀛楁
+            if (!StringUtils.hasText(productPricing.getSuiteName())) {
+                throw new BusinessException("浜у搧濂椾欢鍚嶇О涓嶈兘涓虹┖");
+            }
+            if (!StringUtils.hasText(productPricing.getSalesForm())) {
+                throw new BusinessException("閿�鍞舰寮忎笉鑳戒负绌�");
+            }
+            if (!StringUtils.hasText(productPricing.getCustomerType())) {
+                throw new BusinessException("瀹㈡埛瀵硅薄涓嶈兘涓虹┖");
+            }
+            if (!StringUtils.hasText(productPricing.getPriceType())) {
+                throw new BusinessException("浠锋牸璁剧疆涓嶈兘涓虹┖");
+            }
+            if (productPricing.getPrice() == null || productPricing.getPrice().doubleValue() < 0) {
+                throw new BusinessException("浠锋牸鍊间笉鑳戒负绌轰笖涓嶈兘涓鸿礋鏁�");
+            }
+            if (productPricing.getProductId() == null) {
+                throw new BusinessException("浜у搧ID涓嶈兘涓虹┖");
+            }
+            
+            // 璁剧疆榛樿鍊�
+            if (productPricing.getIsActive() == null) {
+                productPricing.setIsActive(true);
+            }
+            
+            boolean result = save(productPricing);
+            if (result) {
+                log.info("鏂板浜у搧瀹氫环鎴愬姛: {}", productPricing.getSuiteName());
+            }
+            return result;
+        } catch (Exception e) {
+            log.error("鏂板浜у搧瀹氫环澶辫触: ", e);
+            throw new BusinessException("鏂板浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateProductPricing(ProductPricing productPricing) {
+        try {
+            // 妫�鏌ュ畾浠锋槸鍚﹀瓨鍦�
+            ProductPricing existingPricing = getById(productPricing.getId());
+            if (existingPricing == null) {
+                throw new BusinessException("浜у搧瀹氫环涓嶅瓨鍦�");
+            }
+            
+            // 璁剧疆鏇存柊鏃堕棿
+            productPricing.setUpdatedAt(LocalDateTime.now());
+            
+            // 楠岃瘉蹇呭~瀛楁
+            if (!StringUtils.hasText(productPricing.getSuiteName())) {
+                throw new BusinessException("浜у搧濂椾欢鍚嶇О涓嶈兘涓虹┖");
+            }
+            if (!StringUtils.hasText(productPricing.getSalesForm())) {
+                throw new BusinessException("閿�鍞舰寮忎笉鑳戒负绌�");
+            }
+            if (!StringUtils.hasText(productPricing.getCustomerType())) {
+                throw new BusinessException("瀹㈡埛瀵硅薄涓嶈兘涓虹┖");
+            }
+            if (!StringUtils.hasText(productPricing.getPriceType())) {
+                throw new BusinessException("浠锋牸璁剧疆涓嶈兘涓虹┖");
+            }
+            if (productPricing.getPrice() == null || productPricing.getPrice().doubleValue() < 0) {
+                throw new BusinessException("浠锋牸鍊间笉鑳戒负绌轰笖涓嶈兘涓鸿礋鏁�");
+            }
+            
+            boolean result = updateById(productPricing);
+            if (result) {
+                log.info("鏇存柊浜у搧瀹氫环鎴愬姛: {}", productPricing.getSuiteName());
+            }
+            return result;
+        } catch (Exception e) {
+            log.error("鏇存柊浜у搧瀹氫环澶辫触: ", e);
+            throw new BusinessException("鏇存柊浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteProductPricing(Long id) {
+        try {
+            // 妫�鏌ュ畾浠锋槸鍚﹀瓨鍦�
+            ProductPricing existingPricing = getById(id);
+            if (existingPricing == null) {
+                throw new BusinessException("浜у搧瀹氫环涓嶅瓨鍦�");
+            }
+            
+            boolean result = removeById(id);
+            if (result) {
+                log.info("鍒犻櫎浜у搧瀹氫环鎴愬姛: {}", existingPricing.getSuiteName());
+            }
+            return result;
+        } catch (Exception e) {
+            log.error("鍒犻櫎浜у搧瀹氫环澶辫触: ", e);
+            throw new BusinessException("鍒犻櫎浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public IPage<ProductPricing> getProductPricingPage(Page<ProductPricing> page, Long productId) {
+        try {
+            return baseMapper.selectProductPricingPage(page, productId);
+        } catch (Exception e) {
+            log.error("鍒嗛〉鏌ヨ浜у搧瀹氫环澶辫触: ", e);
+            throw new BusinessException("鍒嗛〉鏌ヨ浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public List<ProductPricing> getPricingByProductId(Long productId) {
+        try {
+            if (productId == null) {
+                throw new BusinessException("浜у搧ID涓嶈兘涓虹┖");
+            }
+            return baseMapper.selectByProductId(productId);
+        } catch (Exception e) {
+            log.error("鏍规嵁浜у搧ID鏌ヨ瀹氫环澶辫触: ", e);
+            throw new BusinessException("鏍规嵁浜у搧ID鏌ヨ瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public List<ProductPricing> getPricingByCondition(String suiteName, String salesForm, 
+                                                    String customerType, String priceType, Boolean isActive) {
+        try {
+            QueryWrapper<ProductPricing> queryWrapper = new QueryWrapper<>();
+            
+            if (StringUtils.hasText(suiteName)) {
+                queryWrapper.like("suite_name", suiteName);
+            }
+            if (StringUtils.hasText(salesForm)) {
+                queryWrapper.eq("sales_form", salesForm);
+            }
+            if (StringUtils.hasText(customerType)) {
+                queryWrapper.eq("customer_type", customerType);
+            }
+            if (StringUtils.hasText(priceType)) {
+                queryWrapper.eq("price_type", priceType);
+            }
+            if (isActive != null) {
+                queryWrapper.eq("is_active", isActive);
+            }
+            
+            queryWrapper.orderByDesc("created_at");
+            
+            return list(queryWrapper);
+        } catch (Exception e) {
+            log.error("鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环澶辫触: ", e);
+            throw new BusinessException("鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环澶辫触: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/webmanage/service/impl/UserPointsServiceImpl.java b/src/main/java/com/webmanage/service/impl/UserPointsServiceImpl.java
new file mode 100644
index 0000000..5b69262
--- /dev/null
+++ b/src/main/java/com/webmanage/service/impl/UserPointsServiceImpl.java
@@ -0,0 +1,127 @@
+package com.webmanage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.webmanage.entity.UserPoints;
+import com.webmanage.mapper.UserPointsMapper;
+import com.webmanage.service.UserPointsService;
+import com.webmanage.vo.PointsDetailVO;
+import com.webmanage.vo.PointsStatsVO;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛绉垎Service瀹炵幇绫�
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Service
+public class UserPointsServiceImpl extends ServiceImpl<UserPointsMapper, UserPoints> implements UserPointsService {
+    
+    @Override
+    public PointsStatsVO getPersonalPointsStats(Long userId) {
+        UserPoints userPoints = this.baseMapper.selectByUserId(userId);
+        
+        PointsStatsVO statsVO = new PointsStatsVO();
+        if (userPoints != null) {
+            statsVO.setBalance(userPoints.getBalance());
+            statsVO.setTotalEarned(userPoints.getTotalEarned());
+            statsVO.setTotalConsumed(userPoints.getTotalConsumed());
+            statsVO.setTotalConverted(userPoints.getTotalConverted());
+        } else {
+            statsVO.setBalance(0);
+            statsVO.setTotalEarned(0);
+            statsVO.setTotalConsumed(0);
+            statsVO.setTotalConverted(0);
+        }
+        
+        // 璁剧疆璇︽儏锛堣繖閲屽彲浠ユ牴鎹疄闄呴渶姹傛煡璇㈡暟鎹簱锛�
+        statsVO.setEarnedDetails(new ArrayList<>());
+        statsVO.setConsumedDetails(new ArrayList<>());
+        statsVO.setConvertedDetails(new ArrayList<>());
+        
+        return statsVO;
+    }
+    
+    @Override
+    public PointsStatsVO getUnitPointsStats(Long unitId) {
+        UserPoints userPoints = this.baseMapper.selectByUnitId(unitId);
+        
+        PointsStatsVO statsVO = new PointsStatsVO();
+        if (userPoints != null) {
+            statsVO.setBalance(userPoints.getBalance());
+            statsVO.setTotalEarned(userPoints.getTotalEarned());
+            statsVO.setTotalConsumed(userPoints.getTotalConsumed());
+            statsVO.setTotalConverted(userPoints.getTotalConverted());
+        } else {
+            statsVO.setBalance(0);
+            statsVO.setTotalEarned(0);
+            statsVO.setTotalConsumed(0);
+            statsVO.setTotalConverted(0);
+        }
+        
+        // 璁剧疆鑾峰彇绉垎璇︽儏
+        List<PointsDetailVO> earnedDetails = new ArrayList<>();
+        earnedDetails.add(createDetailVO("resource_contribution", 10000, 50.0));
+        earnedDetails.add(createDetailVO("resource_transaction", 8000, 40.0));
+        earnedDetails.add(createDetailVO("resource_dissemination", 1900, 9.5));
+        earnedDetails.add(createDetailVO("other", 100, 0.5));
+        statsVO.setEarnedDetails(earnedDetails);
+        
+        // 璁剧疆娑堣�楃Н鍒嗚鎯�
+        List<PointsDetailVO> consumedDetails = new ArrayList<>();
+        consumedDetails.add(createDetailVO("resource_transaction", 17500, 97.2));
+        consumedDetails.add(createDetailVO("resource_dissemination", 500, 2.8));
+        statsVO.setConsumedDetails(consumedDetails);
+        
+        // 璁剧疆杞崲绉垎璇︽儏
+        statsVO.setConvertedDetails(new ArrayList<>());
+        
+        return statsVO;
+    }
+    
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateUserPoints(Long userId, Long unitId, Integer points) {
+        // 鏌ヨ鐢ㄦ埛绉垎璁板綍
+        LambdaQueryWrapper<UserPoints> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(UserPoints::getUserId, userId);
+        UserPoints userPoints = this.getOne(wrapper);
+        
+        if (userPoints == null) {
+            // 鍒涘缓鏂扮殑绉垎璁板綍
+            userPoints = new UserPoints();
+            userPoints.setUserId(userId);
+            userPoints.setUnitId(unitId);
+            userPoints.setBalance(points > 0 ? points : 0);
+            userPoints.setTotalEarned(points > 0 ? points : 0);
+            userPoints.setTotalConsumed(points < 0 ? -points : 0);
+            userPoints.setTotalConverted(0);
+            this.save(userPoints);
+        } else {
+            // 鏇存柊绉垎璁板綍
+            userPoints.setBalance(userPoints.getBalance() + points);
+            if (points > 0) {
+                userPoints.setTotalEarned(userPoints.getTotalEarned() + points);
+            } else {
+                userPoints.setTotalConsumed(userPoints.getTotalConsumed() - points);
+            }
+            this.updateById(userPoints);
+        }
+    }
+    
+    /**
+     * 鍒涘缓绉垎璇︽儏VO
+     */
+    private PointsDetailVO createDetailVO(String category, Integer points, Double percentage) {
+        PointsDetailVO detailVO = new PointsDetailVO();
+        detailVO.setCategory(category);
+        detailVO.setPoints(points);
+        detailVO.setPercentage(percentage);
+        return detailVO;
+    }
+}
diff --git a/src/main/java/com/webmanage/util/SnowflakeIdWorker.java b/src/main/java/com/webmanage/util/SnowflakeIdWorker.java
new file mode 100644
index 0000000..1dadca8
--- /dev/null
+++ b/src/main/java/com/webmanage/util/SnowflakeIdWorker.java
@@ -0,0 +1,101 @@
+package com.webmanage.util;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Snowflake 闆姳绠楁硶ID鐢熸垚鍣紙64浣嶏級
+ * 缁撴瀯锛�1浣嶇鍙蜂綅 + 41浣嶆椂闂存埑 + 5浣嶆暟鎹腑蹇� + 5浣嶅伐浣滄満鍣� + 12浣嶅簭鍒�
+ */
+public class SnowflakeIdWorker {
+
+    private final long twepoch;
+    private final long workerIdBits = 5L;
+    private final long datacenterIdBits = 5L;
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+    private final long sequenceBits = 12L;
+
+    private final long workerIdShift = sequenceBits;
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    private final long workerId;
+    private final long datacenterId;
+
+    private long sequence = 0L;
+    private long lastTimestamp = -1L;
+
+    private final ReentrantLock lock = new ReentrantLock(true);
+
+    /**
+     * @param workerId     宸ヤ綔鏈哄櫒ID (0~31)
+     * @param datacenterId 鏁版嵁涓績ID (0~31)
+     * @param twepochMs    鑷畾涔夌邯鍏冩椂闂达紙姣锛夛紝寤鸿涓虹郴缁熶笂绾垮墠鍥哄畾鏃堕棿鎴筹紝榛樿 2020-01-01
+     */
+    public SnowflakeIdWorker(long workerId, long datacenterId, long twepochMs) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException("worker Id can't be greater than " + maxWorkerId + " or less than 0");
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException("datacenter Id can't be greater than " + maxDatacenterId + " or less than 0");
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+        this.twepoch = twepochMs;
+    }
+
+    /**
+     * 绾跨▼瀹夊叏鐢熸垚涓嬩竴涓狪D
+     */
+    public long nextId() {
+        lock.lock();
+        try {
+            long timestamp = currentTime();
+
+            if (timestamp < lastTimestamp) {
+                // 鏃堕挓鍥炴嫧澶勭悊锛氱瓑寰呭埌 lastTimestamp
+                long offset = lastTimestamp - timestamp;
+                try {
+                    Thread.sleep(offset);
+                } catch (InterruptedException ignored) { }
+                timestamp = currentTime();
+                if (timestamp < lastTimestamp) {
+                    // 濡傛灉浠嶅皬浜庯紝寮哄埗浣跨敤 lastTimestamp
+                    timestamp = lastTimestamp;
+                }
+            }
+
+            if (lastTimestamp == timestamp) {
+                sequence = (sequence + 1) & sequenceMask;
+                if (sequence == 0) {
+                    // 鍚屾绉掑唴搴忓垪婧㈠嚭锛岀瓑寰呬笅涓�姣
+                    timestamp = tilNextMillis(lastTimestamp);
+                }
+            } else {
+                sequence = 0L;
+            }
+
+            lastTimestamp = timestamp;
+
+            return ((timestamp - twepoch) << timestampLeftShift)
+                    | (datacenterId << datacenterIdShift)
+                    | (workerId << workerIdShift)
+                    | sequence;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    private long tilNextMillis(long lastTimestamp) {
+        long timestamp = currentTime();
+        while (timestamp <= lastTimestamp) {
+            timestamp = currentTime();
+        }
+        return timestamp;
+    }
+
+    private long currentTime() {
+        return System.currentTimeMillis();
+    }
+}
diff --git a/src/main/java/com/webmanage/vo/CartItemVO.java b/src/main/java/com/webmanage/vo/CartItemVO.java
new file mode 100644
index 0000000..b41078d
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/CartItemVO.java
@@ -0,0 +1,73 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 璐墿杞﹀晢鍝侀」瑙嗗浘瀵硅薄
+ */
+@Data
+@ApiModel(value = "CartItemVO", description = "璐墿杞﹀晢鍝侀」淇℃伅")
+public class CartItemVO {
+
+    @ApiModelProperty("鍟嗗搧瀹氫环ID")
+    private Long pricingId;
+
+    @ApiModelProperty("鍟嗗搧ID")
+    private Long productId;
+
+    @ApiModelProperty("鍟嗗搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("鍟嗗搧濂椾欢鍚嶇О")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    private String remarks;
+
+    @ApiModelProperty("娣诲姞鏃堕棿")
+    private LocalDateTime addTime;
+
+    @ApiModelProperty("鏈�鍚庢洿鏂版椂闂�")
+    private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/webmanage/vo/CartVO.java b/src/main/java/com/webmanage/vo/CartVO.java
new file mode 100644
index 0000000..da86729
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/CartVO.java
@@ -0,0 +1,35 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 璐墿杞﹁鍥惧璞�
+ */
+@Data
+@ApiModel(value = "CartVO", description = "璐墿杞︿俊鎭�")
+public class CartVO {
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    private Long unitId;
+
+    @ApiModelProperty("璐墿杞﹀晢鍝侀」鍒楄〃")
+    private List<CartItemVO> items;
+
+    @ApiModelProperty("鍟嗗搧鎬绘暟閲�")
+    private Integer totalQuantity;
+
+    @ApiModelProperty("鍟嗗搧鎬婚噾棰�")
+    private BigDecimal totalAmount;
+
+    @ApiModelProperty("鏈�鍚庢洿鏂版椂闂�")
+    private LocalDateTime lastUpdateTime;
+}
diff --git a/src/main/java/com/webmanage/vo/OrderAttachmentVO.java b/src/main/java/com/webmanage/vo/OrderAttachmentVO.java
new file mode 100644
index 0000000..c1939eb
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/OrderAttachmentVO.java
@@ -0,0 +1,63 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟闄勪欢VO
+ */
+@Data
+@ApiModel(value = "OrderAttachmentVO", description = "璁㈠崟闄勪欢")
+public class OrderAttachmentVO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    private String orderId;
+
+    @ApiModelProperty("闄勪欢鍚嶇О")
+    private String fileName;
+
+    @ApiModelProperty("鍘熷鏂囦欢鍚�")
+    private String originalName;
+
+    @ApiModelProperty("闄勪欢绫诲瀷")
+    private String fileType;
+
+    @ApiModelProperty("闄勪欢澶у皬(瀛楄妭)")
+    private Long fileSize;
+
+    @ApiModelProperty("闄勪欢鍦板潃")
+    private String fileUrl;
+
+    @ApiModelProperty("鏂囦欢瀛樺偍璺緞")
+    private String filePath;
+
+    @ApiModelProperty("MinIO瀛樺偍妗跺悕绉�")
+    private String bucketName;
+
+    @ApiModelProperty("MinIO瀵硅薄鍚嶇О")
+    private String objectName;
+
+    @ApiModelProperty("涓婁紶鐢ㄦ埛ID")
+    private Long uploadUserId;
+
+    @ApiModelProperty("涓婁紶鐢ㄦ埛鍚�")
+    private String uploadUserName;
+
+    @ApiModelProperty("闄勪欢绫诲瀷(鍚堝悓/鍙戠エ/鍏朵粬)")
+    private String attachmentType;
+
+    @ApiModelProperty("闄勪欢鎻忚堪")
+    private String description;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private LocalDateTime updatedAt;
+}
diff --git a/src/main/java/com/webmanage/vo/OrderDetailItemVO.java b/src/main/java/com/webmanage/vo/OrderDetailItemVO.java
new file mode 100644
index 0000000..cce4f5b
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/OrderDetailItemVO.java
@@ -0,0 +1,66 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 璁㈠崟璇︽儏椤筕O
+ */
+@Data
+@ApiModel(value = "OrderDetailItemVO", description = "璁㈠崟璇︽儏椤�")
+public class OrderDetailItemVO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈浜у搧瀹氫环ID")
+    private Long pricingId;
+
+    @ApiModelProperty("浜у搧ID")
+    private Long productId;
+
+    @ApiModelProperty("浜у搧濂椾欢鍚嶇О")
+    private String suiteName;
+
+    @ApiModelProperty("閿�鍞舰寮�")
+    private String salesForm;
+
+    @ApiModelProperty("瀹㈡埛瀵硅薄")
+    private String customerType;
+
+    @ApiModelProperty("璐︽埛鏁伴噺")
+    private String accountLimit;
+
+    @ApiModelProperty("骞跺彂鑺傜偣鏁�")
+    private String concurrentNodes;
+
+    @ApiModelProperty("浠锋牸绫诲瀷")
+    private String priceType;
+
+    @ApiModelProperty("浠锋牸鍗曚綅")
+    private String priceUnit;
+
+    @ApiModelProperty("鍗曚环")
+    private BigDecimal unitPrice;
+
+    @ApiModelProperty("鏁伴噺")
+    private Integer quantity;
+
+    @ApiModelProperty("骞撮檺")
+    private Integer duration;
+
+    @ApiModelProperty("灏忚閲戦")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("浜у搧鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("澶囨敞")
+    private String remarks;
+}
diff --git a/src/main/java/com/webmanage/vo/OrderDetailVO.java b/src/main/java/com/webmanage/vo/OrderDetailVO.java
new file mode 100644
index 0000000..282df60
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/OrderDetailVO.java
@@ -0,0 +1,83 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 璁㈠崟璇︽儏VO
+ */
+@Data
+@ApiModel(value = "OrderDetailVO", description = "璁㈠崟璇︽儏")
+public class OrderDetailVO {
+
+    @ApiModelProperty("璁㈠崟缂栧彿")
+    private String orderId;
+
+    @ApiModelProperty("浜у搧ID")
+    private Long productId;
+
+    @ApiModelProperty("鐢ㄦ埛ID")
+    private Long userId;
+
+    @ApiModelProperty("鍗曚綅ID")
+    private Long unitId;
+
+    @ApiModelProperty("浜у搧鍚嶇О")
+    private String productName;
+
+    @ApiModelProperty("鎻愪緵鑰呭悕绉�")
+    private String providerName;
+
+    @ApiModelProperty("鎻愪緵鑰匢D")
+    private Long providerId;
+
+    @ApiModelProperty("鐢宠鏃堕棿")
+    private LocalDateTime applyTime;
+
+    @ApiModelProperty("璁㈠崟鐘舵��")
+    private String orderStatus;
+
+    @ApiModelProperty("璁㈠崟鎬婚噾棰�")
+    private BigDecimal totalAmount;
+
+    @ApiModelProperty("鏀粯鏂瑰紡")
+    private String paymentType;
+
+    @ApiModelProperty("鏀粯鐘舵��")
+    private String paymentStatus;
+
+    @ApiModelProperty("宸ヤ綔娴両D")
+    private String workflowId;
+
+    @ApiModelProperty("褰撳墠瀹℃壒姝ラ")
+    private String currentStep;
+
+    @ApiModelProperty("瀹℃壒娴佺▼閰嶇疆")
+    private String approvalFlow;
+
+    @ApiModelProperty("涔板澶囨敞")
+    private String buyerRemarks;
+
+    @ApiModelProperty("鍗栧澶囨敞")
+    private String sellerRemarks;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private LocalDateTime updatedAt;
+
+    @ApiModelProperty("璁㈠崟璇︽儏鍒楄〃")
+    private List<OrderDetailItemVO> orderDetails;
+
+    @ApiModelProperty("璁㈠崟闄勪欢鍒楄〃")
+    private List<OrderAttachmentVO> attachments;
+
+    @ApiModelProperty("璁㈠崟璇勪环")
+    private OrderEvaluationVO evaluation;
+}
diff --git a/src/main/java/com/webmanage/vo/OrderEvaluationVO.java b/src/main/java/com/webmanage/vo/OrderEvaluationVO.java
new file mode 100644
index 0000000..b01dc00
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/OrderEvaluationVO.java
@@ -0,0 +1,63 @@
+package com.webmanage.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 璁㈠崟璇勪环VO
+ */
+@Data
+@ApiModel(value = "OrderEvaluationVO", description = "璁㈠崟璇勪环")
+public class OrderEvaluationVO {
+
+    @ApiModelProperty("涓婚敭ID")
+    private Long id;
+
+    @ApiModelProperty("鍏宠仈璁㈠崟ID")
+    private String orderId;
+
+    @ApiModelProperty("璇勪环浜篒D")
+    private Long evaluatorId;
+
+    @ApiModelProperty("璇勪环浜哄鍚�")
+    private String evaluatorName;
+
+    @ApiModelProperty("璇勪环浜虹被鍨�")
+    private String evaluatorType;
+
+    @ApiModelProperty("璇勪环鍐呭")
+    private String content;
+
+    @ApiModelProperty("璇勫垎(1-5)")
+    private Integer rating;
+
+    @ApiModelProperty("鏈嶅姟璇勫垎")
+    private Integer serviceRating;
+
+    @ApiModelProperty("璐ㄩ噺璇勫垎")
+    private Integer qualityRating;
+
+    @ApiModelProperty("浜や粯璇勫垎")
+    private Integer deliveryRating;
+
+    @ApiModelProperty("鏄惁鍖垮悕璇勪环")
+    private Boolean isAnonymous;
+
+    @ApiModelProperty("鍥炲鍐呭")
+    private String replyContent;
+
+    @ApiModelProperty("鍥炲鐢ㄦ埛ID")
+    private Long replyUserId;
+
+    @ApiModelProperty("鍥炲鏃堕棿")
+    private LocalDateTime replyTime;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    private LocalDateTime createdAt;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private LocalDateTime updatedAt;
+}
diff --git a/src/main/java/com/webmanage/vo/PointsDetailVO.java b/src/main/java/com/webmanage/vo/PointsDetailVO.java
new file mode 100644
index 0000000..78a1f64
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/PointsDetailVO.java
@@ -0,0 +1,28 @@
+package com.webmanage.vo;
+
+import lombok.Data;
+
+/**
+ * 绉垎璇︽儏VO
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+public class PointsDetailVO {
+    
+    /**
+     * 鍒嗙被
+     */
+    private String category;
+    
+    /**
+     * 绉垎鍊�
+     */
+    private Integer points;
+    
+    /**
+     * 鐧惧垎姣�
+     */
+    private Double percentage;
+}
diff --git a/src/main/java/com/webmanage/vo/PointsStatsVO.java b/src/main/java/com/webmanage/vo/PointsStatsVO.java
new file mode 100644
index 0000000..90c239e
--- /dev/null
+++ b/src/main/java/com/webmanage/vo/PointsStatsVO.java
@@ -0,0 +1,50 @@
+package com.webmanage.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 绉垎缁熻VO
+ * 
+ * @author webmanage
+ * @date 2024-08-07
+ */
+@Data
+public class PointsStatsVO {
+    
+    /**
+     * 绉垎浣欓
+     */
+    private Integer balance;
+    
+    /**
+     * 绱鑾峰彇
+     */
+    private Integer totalEarned;
+    
+    /**
+     * 绱娑堣��
+     */
+    private Integer totalConsumed;
+    
+    /**
+     * 绱杞崲
+     */
+    private Integer totalConverted;
+    
+    /**
+     * 鑾峰彇绉垎璇︽儏
+     */
+    private List<PointsDetailVO> earnedDetails;
+    
+    /**
+     * 娑堣�楃Н鍒嗚鎯�
+     */
+    private List<PointsDetailVO> consumedDetails;
+    
+    /**
+     * 杞崲绉垎璇︽儏
+     */
+    private List<PointsDetailVO> convertedDetails;
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..f12c5d6
--- /dev/null
+++ b/src/main/resources/application-dev.yml
@@ -0,0 +1,128 @@
+server:
+  port: 8080
+  servlet:
+    context-path: /admin
+
+spring:
+  application:
+    name: web-manage-back
+
+  #mcv閰嶇疆
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher  
+  
+  # 鏁版嵁婧愰厤缃�
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://localhost:5432/web_manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+    username: postgres
+    password: postgres
+    druid:
+      # 鍒濆杩炴帴鏁�
+      initial-size: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      min-idle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      max-active: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      max-wait: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      time-between-eviction-runs-millis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      min-evictable-idle-time-millis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      max-evictable-idle-time-millis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validation-query: SELECT 1
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      # 鎵撳紑PSCache锛屽苟涓旀寚瀹氭瘡涓繛鎺ヤ笂PSCache鐨勫ぇ灏�
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      # 閰嶇疆鐩戞帶缁熻鎷︽埅鐨刦ilters锛屽幓鎺夊悗鐩戞帶鐣岄潰sql鏃犳硶缁熻锛�'wall'鐢ㄤ簬闃茬伀澧�
+      filters: stat,wall,slf4j
+      # 閫氳繃connectProperties灞炴�ф潵鎵撳紑mergeSql鍔熻兘锛涙參SQL璁板綍
+      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+      # 閰嶇疆DruidStatFilter
+      web-stat-filter:
+        enabled: true
+        url-pattern: /*
+        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
+      # 閰嶇疆DruidStatViewServlet
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        reset-enable: false
+        login-username: admin
+        login-password: 123456
+
+  # Redis閰嶇疆
+  redis:
+    host: localhost
+    port: 6379
+    password: 
+    database: 0
+    timeout: 10000ms
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1ms
+        max-idle: 8
+        min-idle: 0
+
+# MinIO閰嶇疆
+minio:
+   endpoint: http://localhost:9000
+   access-key: minioadmin
+   secret-key: minioadmin
+   bucket-name: web-manage
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  configuration:
+    # 寮�鍚┘宄板懡鍚�
+    map-underscore-to-camel-case: true
+    # 寮�鍚痵ql鏃ュ織
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      # 涓婚敭绫诲瀷
+      id-type: auto
+      # 閫昏緫鍒犻櫎閰嶇疆
+      logic-delete-field: deleted
+      logic-delete-value: 1
+      logic-not-delete-value: 0
+  mapper-locations: classpath*:/mapper/**/*.xml
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.webmanage: debug
+    org.springframework.web: debug
+  pattern:
+    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
+
+# Knife4j閰嶇疆
+knife4j:
+  enable: true
+  setting:
+    language: zh-CN
+    enable-swagger-models: true
+    enable-document-manage: true
+    swagger-model-name: 瀹炰綋绫诲垪琛�
+  basic:
+    enable: false
+
+# 璐墿杞﹂厤缃�
+cart:
+  # Redis缂撳瓨杩囨湡鏃堕棿锛堝ぉ锛�
+  expire-days: 30
+  # 鏄惁鍚敤鏁版嵁搴撴寔涔呭寲
+  enable-persistence: true
+  # 鏄惁鍚敤鏁版嵁涓�鑷存�ф鏌�
+  enable-consistency-check: true
+  # 鍚屾绛栫暐锛歳ealtime锛堝疄鏃跺悓姝ワ級銆乥atch锛堟壒閲忓悓姝ワ級銆乵anual锛堟墜鍔ㄥ悓姝ワ級
+  sync-strategy: realtime
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..88eaa3e
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,133 @@
+server:
+  port: 8080
+  servlet:
+    context-path: /admin
+
+spring:
+  application:
+    name: web-manage-back
+  profiles:
+    active: dev
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+
+  #mcv閰嶇疆
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher  
+  
+  # 鏁版嵁婧愰厤缃�
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://localhost:5432/web_manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+    username: postgres
+    password: zkyxpostgres
+    druid:
+      # 鍒濆杩炴帴鏁�
+      initial-size: 5
+      # 鏈�灏忚繛鎺ユ睜鏁伴噺
+      min-idle: 10
+      # 鏈�澶ц繛鎺ユ睜鏁伴噺
+      max-active: 20
+      # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+      max-wait: 60000
+      # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+      time-between-eviction-runs-millis: 60000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      min-evictable-idle-time-millis: 300000
+      # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+      max-evictable-idle-time-millis: 900000
+      # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+      validation-query: SELECT 1
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      # 鎵撳紑PSCache锛屽苟涓旀寚瀹氭瘡涓繛鎺ヤ笂PSCache鐨勫ぇ灏�
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      # 閰嶇疆鐩戞帶缁熻鎷︽埅鐨刦ilters锛屽幓鎺夊悗鐩戞帶鐣岄潰sql鏃犳硶缁熻锛�'wall'鐢ㄤ簬闃茬伀澧�
+      filters: stat,wall,slf4j
+      # 閫氳繃connectProperties灞炴�ф潵鎵撳紑mergeSql鍔熻兘锛涙參SQL璁板綍
+      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+      # 閰嶇疆DruidStatFilter
+      web-stat-filter:
+        enabled: true
+        url-pattern: /*
+        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
+      # 閰嶇疆DruidStatViewServlet
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        reset-enable: false
+        login-username: admin
+        login-password: 123456
+
+  # Redis閰嶇疆
+  redis:
+    host: 192.168.110.129
+    port: 6379
+    password: 
+    database: 0
+    timeout: 10000ms
+    lettuce:
+      pool:
+        max-active: 8
+        max-wait: -1ms
+        max-idle: 8
+        min-idle: 0
+
+# MinIO閰嶇疆
+minio:
+   endpoint: http://192.168.110.129:9000
+   access-key: minioadmin
+   secret-key: minioadmin
+   bucket-name: web-manage
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+  configuration:
+    # 寮�鍚┘宄板懡鍚�
+    map-underscore-to-camel-case: true
+    # 寮�鍚痵ql鏃ュ織
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      # 涓婚敭绫诲瀷
+      id-type: auto
+      # 閫昏緫鍒犻櫎閰嶇疆
+      logic-delete-field: deleted
+      logic-delete-value: 1
+      logic-not-delete-value: 0
+  mapper-locations: classpath*:/mapper/**/*.xml
+
+# 鏃ュ織閰嶇疆
+logging:
+  level:
+    com.webmanage: debug
+    org.springframework.web: debug
+  pattern:
+    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
+
+# Knife4j閰嶇疆
+knife4j:
+  enable: true
+  setting:
+    language: zh-CN
+    enable-swagger-models: true
+    enable-document-manage: true
+    swagger-model-name: 瀹炰綋绫诲垪琛�
+  basic:
+    enable: false
+
+# 璐墿杞﹂厤缃�
+cart:
+  # Redis缂撳瓨杩囨湡鏃堕棿锛堝ぉ锛�
+  expire-days: 30
+  # 鏄惁鍚敤鏁版嵁搴撴寔涔呭寲
+  enable-persistence: true
+  # 鏄惁鍚敤鏁版嵁涓�鑷存�ф鏌�
+  enable-consistency-check: true
+  # 鍚屾绛栫暐锛歳ealtime锛堝疄鏃跺悓姝ワ級銆乥atch锛堟壒閲忓悓姝ワ級銆乵anual锛堟墜鍔ㄥ悓姝ワ級
+  sync-strategy: realtime
diff --git a/src/main/resources/mapper/ApprovalRecordMapper.xml b/src/main/resources/mapper/ApprovalRecordMapper.xml
new file mode 100644
index 0000000..11d9bae
--- /dev/null
+++ b/src/main/resources/mapper/ApprovalRecordMapper.xml
@@ -0,0 +1,117 @@
+<?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.webmanage.mapper.ApprovalRecordMapper">
+
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.ApprovalRecord">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="order_id" property="orderId" jdbcType="VARCHAR"/>
+        <result column="approver_id" property="approverId" jdbcType="BIGINT"/>
+        <result column="approver_name" property="approverName" jdbcType="VARCHAR"/>
+        <result column="approver_role" property="approverRole" jdbcType="VARCHAR"/>
+        <result column="approval_step" property="approvalStep" jdbcType="VARCHAR"/>
+        <result column="approval_result" property="approvalResult" jdbcType="VARCHAR"/>
+        <result column="approval_opinion" property="approvalOpinion" jdbcType="VARCHAR"/>
+        <result column="approval_time" property="approvalTime" jdbcType="TIMESTAMP"/>
+        <result column="need_authorization" property="needAuthorization" jdbcType="BOOLEAN"/>
+        <result column="authorizer_id" property="authorizerId" jdbcType="BIGINT"/>
+        <result column="authorizer_name" property="authorizerName" jdbcType="VARCHAR"/>
+        <result column="authorization_time" property="authorizationTime" jdbcType="TIMESTAMP"/>
+        <result column="authorization_opinion" property="authorizationOpinion" jdbcType="VARCHAR"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id, order_id, approver_id, approver_name, approver_role, approval_step, approval_result,
+        approval_opinion, approval_time, need_authorization, authorizer_id, authorizer_name,
+        authorization_time, authorization_opinion, created_at, updated_at, deleted
+    </sql>
+
+    <select id="selectApprovalRecordPage" resultMap="BaseResultMap">
+        SELECT ar.<include refid="Base_Column_List"/>
+        FROM approval_record ar
+        LEFT JOIN order_info oi ON ar.order_id = oi.order_id
+        WHERE ar.deleted = 0
+        <if test="orderId != null and orderId != ''">
+            AND ar.order_id = #{orderId}
+        </if>
+        <if test="productName != null and productName != ''">
+            AND oi.product_name LIKE CONCAT('%', #{productName}, '%')
+        </if>
+        <if test="providerName != null and providerName != ''">
+            AND oi.provider_name LIKE CONCAT('%', #{providerName}, '%')
+        </if>
+        <if test="approverId != null">
+            AND ar.approver_id = #{approverId}
+        </if>
+        <if test="approvalResult != null and approvalResult != ''">
+            AND ar.approval_result = #{approvalResult}
+        </if>
+        <if test="approvalStep != null and approvalStep != ''">
+            AND ar.approval_step = #{approvalStep}
+        </if>
+        <if test="needAuthorization != null">
+            AND ar.need_authorization = #{needAuthorization}
+        </if>
+        <if test="applyTimeStart != null and applyTimeStart != ''">
+            AND oi.apply_time >= #{applyTimeStart}
+        </if>
+        <if test="applyTimeEnd != null and applyTimeEnd != ''">
+            AND oi.apply_time &lt;= #{applyTimeEnd}
+        </if>
+        <if test="approvalTimeStart != null and approvalTimeStart != ''">
+            AND ar.approval_time >= #{approvalTimeStart}
+        </if>
+        <if test="approvalTimeEnd != null and approvalTimeEnd != ''">
+            AND ar.approval_time &lt;= #{approvalTimeEnd}
+        </if>
+        ORDER BY 
+        <choose>
+            <when test="orderBy == 'approval_time'">ar.approval_time</when>
+            <when test="orderBy == 'created_at'">ar.created_at</when>
+            <otherwise>ar.created_at</otherwise>
+        </choose>
+        <choose>
+            <when test="orderDirection == 'asc'">ASC</when>
+            <otherwise>DESC</otherwise>
+        </choose>
+    </select>
+
+    <select id="selectByOrderId" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM approval_record
+        WHERE deleted = 0 AND order_id = #{orderId}
+        ORDER BY created_at ASC
+    </select>
+
+    <select id="selectPendingApprovalPage" resultMap="BaseResultMap">
+        SELECT ar.<include refid="Base_Column_List"/>
+        FROM approval_record ar
+        LEFT JOIN order_info oi ON ar.order_id = oi.order_id
+        WHERE ar.deleted = 0 AND ar.approval_result IS NULL
+        <if test="orderId != null and orderId != ''">
+            AND ar.order_id = #{orderId}
+        </if>
+        <if test="productName != null and productName != ''">
+            AND oi.product_name LIKE CONCAT('%', #{productName}, '%')
+        </if>
+        <if test="providerName != null and providerName != ''">
+            AND oi.provider_name LIKE CONCAT('%', #{providerName}, '%')
+        </if>
+        <if test="approvalStep != null and approvalStep != ''">
+            AND ar.approval_step = #{approvalStep}
+        </if>
+        ORDER BY 
+        <choose>
+            <when test="orderBy == 'approval_time'">ar.approval_time</when>
+            <when test="orderBy == 'created_at'">ar.created_at</when>
+            <otherwise>ar.created_at</otherwise>
+        </choose>
+        <choose>
+            <when test="orderDirection == 'asc'">ASC</when>
+            <otherwise>DESC</otherwise>
+        </choose>
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/CartMapper.xml b/src/main/resources/mapper/CartMapper.xml
new file mode 100644
index 0000000..086a599
--- /dev/null
+++ b/src/main/resources/mapper/CartMapper.xml
@@ -0,0 +1,73 @@
+<?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.webmanage.mapper.CartMapper">
+    
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.Cart">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="user_id" property="userId" jdbcType="BIGINT"/>
+        <result column="unit_id" property="unitId" jdbcType="BIGINT"/>
+        <result column="pricing_id" property="pricingId" jdbcType="BIGINT"/>
+        <result column="product_id" property="productId" jdbcType="BIGINT"/>
+        <result column="product_name" property="productName" jdbcType="VARCHAR"/>
+        <result column="suite_name" property="suiteName" jdbcType="VARCHAR"/>
+        <result column="sales_form" property="salesForm" jdbcType="VARCHAR"/>
+        <result column="customer_type" property="customerType" jdbcType="VARCHAR"/>
+        <result column="account_limit" property="accountLimit" jdbcType="VARCHAR"/>
+        <result column="concurrent_nodes" property="concurrentNodes" jdbcType="VARCHAR"/>
+        <result column="price_type" property="priceType" jdbcType="VARCHAR"/>
+        <result column="price_unit" property="priceUnit" jdbcType="VARCHAR"/>
+        <result column="unit_price" property="unitPrice" jdbcType="DECIMAL"/>
+        <result column="quantity" property="quantity" jdbcType="INTEGER"/>
+        <result column="duration" property="duration" jdbcType="INTEGER"/>
+        <result column="total_price" property="totalPrice" jdbcType="DECIMAL"/>
+        <result column="provider_id" property="providerId" jdbcType="BIGINT"/>
+        <result column="provider_name" property="providerName" jdbcType="VARCHAR"/>
+        <result column="remarks" property="remarks" jdbcType="VARCHAR"/>
+        <result column="add_time" property="addTime" jdbcType="TIMESTAMP"/>
+        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+    
+    <sql id="Base_Column_List">
+        id, user_id, unit_id, pricing_id, product_id, product_name, suite_name, sales_form, 
+        customer_type, account_limit, concurrent_nodes, price_type, price_unit, unit_price, 
+        quantity, duration, total_price, provider_id, provider_name, remarks, add_time, 
+        update_time, deleted
+    </sql>
+    
+    <select id="selectByUserIdAndUnitId" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM cart
+        WHERE deleted = 0 
+        AND user_id = #{userId} 
+        AND unit_id = #{unitId}
+        ORDER BY add_time DESC
+    </select>
+    
+    <select id="selectByUserIdUnitIdAndPricingId" resultMap="BaseResultMap">
+        SELECT <include refid="Base_Column_List"/>
+        FROM cart
+        WHERE deleted = 0 
+        AND user_id = #{userId} 
+        AND unit_id = #{unitId}
+        AND pricing_id = #{pricingId}
+        LIMIT 1
+    </select>
+    
+    <select id="countByUserIdAndUnitId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM cart
+        WHERE deleted = 0 
+        AND user_id = #{userId} 
+        AND unit_id = #{unitId}
+    </select>
+    
+    <select id="sumTotalAmountByUserIdAndUnitId" resultType="java.math.BigDecimal">
+        SELECT COALESCE(SUM(total_price), 0)
+        FROM cart
+        WHERE deleted = 0 
+        AND user_id = #{userId} 
+        AND unit_id = #{unitId}
+    </select>
+    
+</mapper>
diff --git a/src/main/resources/mapper/OrderAttachmentMapper.xml b/src/main/resources/mapper/OrderAttachmentMapper.xml
new file mode 100644
index 0000000..01114a6
--- /dev/null
+++ b/src/main/resources/mapper/OrderAttachmentMapper.xml
@@ -0,0 +1,42 @@
+<?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.webmanage.mapper.OrderAttachmentMapper">
+
+    <!-- 鍩虹缁撴灉鏄犲皠 -->
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.OrderAttachment">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="order_id" property="orderId" jdbcType="VARCHAR"/>
+        <result column="file_name" property="fileName" jdbcType="VARCHAR"/>
+        <result column="original_name" property="originalName" jdbcType="VARCHAR"/>
+        <result column="file_type" property="fileType" jdbcType="VARCHAR"/>
+        <result column="file_size" property="fileSize" jdbcType="BIGINT"/>
+        <result column="file_url" property="fileUrl" jdbcType="VARCHAR"/>
+        <result column="file_path" property="filePath" jdbcType="VARCHAR"/>
+        <result column="bucket_name" property="bucketName" jdbcType="VARCHAR"/>
+        <result column="object_name" property="objectName" jdbcType="VARCHAR"/>
+        <result column="upload_user_id" property="uploadUserId" jdbcType="BIGINT"/>
+        <result column="upload_user_name" property="uploadUserName" jdbcType="VARCHAR"/>
+        <result column="attachment_type" property="attachmentType" jdbcType="VARCHAR"/>
+        <result column="description" property="description" jdbcType="LONGVARCHAR"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!-- 鍩虹瀛楁鍒楄〃 -->
+    <sql id="Base_Column_List">
+        id, order_id, file_name, original_name, file_type, file_size, file_url, file_path,
+        bucket_name, object_name, upload_user_id, upload_user_name, attachment_type,
+        description, created_at, updated_at, deleted
+    </sql>
+
+    <!-- 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟闄勪欢鍒楄〃 -->
+    <select id="selectByOrderId" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_attachment
+        WHERE deleted = 0 AND order_id = #{orderId}
+        ORDER BY created_at ASC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/OrderDetailMapper.xml b/src/main/resources/mapper/OrderDetailMapper.xml
new file mode 100644
index 0000000..ccc67f5
--- /dev/null
+++ b/src/main/resources/mapper/OrderDetailMapper.xml
@@ -0,0 +1,46 @@
+<?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.webmanage.mapper.OrderDetailMapper">
+
+    <!-- 鍩虹缁撴灉鏄犲皠 -->
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.OrderDetail">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="order_id" property="orderId" jdbcType="VARCHAR"/>
+        <result column="pricing_id" property="pricingId" jdbcType="BIGINT"/>
+        <result column="product_id" property="productId" jdbcType="BIGINT"/>
+        <result column="suite_name" property="suiteName" jdbcType="VARCHAR"/>
+        <result column="sales_form" property="salesForm" jdbcType="VARCHAR"/>
+        <result column="customer_type" property="customerType" jdbcType="VARCHAR"/>
+        <result column="account_limit" property="accountLimit" jdbcType="VARCHAR"/>
+        <result column="concurrent_nodes" property="concurrentNodes" jdbcType="VARCHAR"/>
+        <result column="price_type" property="priceType" jdbcType="VARCHAR"/>
+        <result column="price_unit" property="priceUnit" jdbcType="VARCHAR"/>
+        <result column="unit_price" property="unitPrice" jdbcType="NUMERIC"/>
+        <result column="quantity" property="quantity" jdbcType="INTEGER"/>
+        <result column="duration" property="duration" jdbcType="INTEGER"/>
+        <result column="total_price" property="totalPrice" jdbcType="NUMERIC"/>
+        <result column="provider_id" property="providerId" jdbcType="BIGINT"/>
+        <result column="provider_name" property="providerName" jdbcType="VARCHAR"/>
+        <result column="remarks" property="remarks" jdbcType="LONGVARCHAR"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!-- 鍩虹瀛楁鍒楄〃 -->
+    <sql id="Base_Column_List">
+        id, order_id, pricing_id, product_id, suite_name, sales_form, customer_type,
+        account_limit, concurrent_nodes, price_type, price_unit, unit_price, quantity,
+        duration, total_price, provider_id, provider_name, remarks, created_at, updated_at, deleted
+    </sql>
+
+    <!-- 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟璇︽儏鍒楄〃 -->
+    <select id="selectByOrderId" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_detail
+        WHERE deleted = 0 AND order_id = #{orderId}
+        ORDER BY created_at ASC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/OrderEvaluationMapper.xml b/src/main/resources/mapper/OrderEvaluationMapper.xml
new file mode 100644
index 0000000..8a22960
--- /dev/null
+++ b/src/main/resources/mapper/OrderEvaluationMapper.xml
@@ -0,0 +1,42 @@
+<?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.webmanage.mapper.OrderEvaluationMapper">
+
+    <!-- 鍩虹缁撴灉鏄犲皠 -->
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.OrderEvaluation">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="order_id" property="orderId" jdbcType="VARCHAR"/>
+        <result column="evaluator_id" property="evaluatorId" jdbcType="BIGINT"/>
+        <result column="evaluator_name" property="evaluatorName" jdbcType="VARCHAR"/>
+        <result column="evaluator_type" property="evaluatorType" jdbcType="VARCHAR"/>
+        <result column="content" property="content" jdbcType="LONGVARCHAR"/>
+        <result column="rating" property="rating" jdbcType="INTEGER"/>
+        <result column="service_rating" property="serviceRating" jdbcType="INTEGER"/>
+        <result column="quality_rating" property="qualityRating" jdbcType="INTEGER"/>
+        <result column="delivery_rating" property="deliveryRating" jdbcType="INTEGER"/>
+        <result column="is_anonymous" property="isAnonymous" jdbcType="BOOLEAN"/>
+        <result column="reply_content" property="replyContent" jdbcType="LONGVARCHAR"/>
+        <result column="reply_user_id" property="replyUserId" jdbcType="BIGINT"/>
+        <result column="reply_time" property="replyTime" jdbcType="TIMESTAMP"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!-- 鍩虹瀛楁鍒楄〃 -->
+    <sql id="Base_Column_List">
+        id, order_id, evaluator_id, evaluator_name, evaluator_type, content, rating,
+        service_rating, quality_rating, delivery_rating, is_anonymous, reply_content,
+        reply_user_id, reply_time, created_at, updated_at, deleted
+    </sql>
+
+    <!-- 鏍规嵁璁㈠崟ID鏌ヨ璁㈠崟璇勪环 -->
+    <select id="selectByOrderId" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_evaluation
+        WHERE deleted = 0 AND order_id = #{orderId}
+        LIMIT 1
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/OrderInfoMapper.xml b/src/main/resources/mapper/OrderInfoMapper.xml
new file mode 100644
index 0000000..e1c3538
--- /dev/null
+++ b/src/main/resources/mapper/OrderInfoMapper.xml
@@ -0,0 +1,193 @@
+<?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.webmanage.mapper.OrderInfoMapper">
+
+    <!-- 鍩虹缁撴灉鏄犲皠 -->
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.OrderInfo">
+        <id column="order_id" property="orderId" jdbcType="VARCHAR"/>
+        <result column="product_id" property="productId" jdbcType="BIGINT"/>
+        <result column="user_id" property="userId" jdbcType="BIGINT"/>
+        <result column="unit_id" property="unitId" jdbcType="BIGINT"/>
+        <result column="product_name" property="productName" jdbcType="VARCHAR"/>
+        <result column="provider_name" property="providerName" jdbcType="VARCHAR"/>
+        <result column="provider_id" property="providerId" jdbcType="BIGINT"/>
+        <result column="apply_time" property="applyTime" jdbcType="TIMESTAMP"/>
+        <result column="order_status" property="orderStatus" jdbcType="VARCHAR"/>
+        <result column="total_amount" property="totalAmount" jdbcType="NUMERIC"/>
+        <result column="payment_type" property="paymentType" jdbcType="VARCHAR"/>
+        <result column="payment_status" property="paymentStatus" jdbcType="VARCHAR"/>
+        <result column="workflow_id" property="workflowId" jdbcType="VARCHAR"/>
+        <result column="current_step" property="currentStep" jdbcType="VARCHAR"/>
+        <result column="approval_flow" property="approvalFlow" jdbcType="LONGVARCHAR"/>
+        <result column="buyer_remarks" property="buyerRemarks" jdbcType="LONGVARCHAR"/>
+        <result column="seller_remarks" property="sellerRemarks" jdbcType="LONGVARCHAR"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!-- 鍩虹瀛楁鍒楄〃 -->
+    <sql id="Base_Column_List">
+        order_id, product_id, user_id, unit_id, product_name, provider_name, provider_id,
+        apply_time, order_status, total_amount, payment_type, payment_status, workflow_id,
+        current_step, approval_flow, buyer_remarks, seller_remarks, created_at, updated_at, deleted
+    </sql>
+
+    <!-- 鍒嗛〉鏌ヨ涔板璁㈠崟鍒楄〃 -->
+    <select id="selectBuyerOrderPage" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_info
+        WHERE deleted = 0
+        <if test="userId != null">
+            AND user_id = #{userId}
+        </if>
+        <if test="unitId != null">
+            AND unit_id = #{unitId}
+        </if>
+        <if test="orderStatus != null and orderStatus != ''">
+            AND order_status = #{orderStatus}
+        </if>
+        <if test="paymentStatus != null and paymentStatus != ''">
+            AND payment_status = #{paymentStatus}
+        </if>
+        <if test="paymentType != null and paymentType != ''">
+            AND payment_type = #{paymentType}
+        </if>
+        <if test="productName != null and productName != ''">
+            AND product_name LIKE CONCAT('%', #{productName}, '%')
+        </if>
+        <if test="providerName != null and providerName != ''">
+            AND provider_name LIKE CONCAT('%', #{providerName}, '%')
+        </if>
+        <if test="orderId != null and orderId != ''">
+            AND order_id LIKE CONCAT('%', #{orderId}, '%')
+        </if>
+        <if test="applyTimeStart != null and applyTimeStart != ''">
+            AND apply_time >= #{applyTimeStart}::timestamp
+        </if>
+        <if test="applyTimeEnd != null and applyTimeEnd != ''">
+            AND apply_time &lt;= #{applyTimeEnd}::timestamp
+        </if>
+        <if test="createTimeStart != null and createTimeStart != ''">
+            AND created_at >= #{createTimeStart}::timestamp
+        </if>
+        <if test="createTimeEnd != null and createTimeEnd != ''">
+            AND created_at &lt;= #{createTimeEnd}::timestamp
+        </if>
+        ORDER BY
+        <choose>
+            <when test="orderBy != null and orderBy != ''">
+                ${orderBy}
+            </when>
+            <otherwise>
+                created_at
+            </otherwise>
+        </choose>
+        <choose>
+            <when test="orderDirection != null and orderDirection == 'asc'">
+                ASC
+            </when>
+            <otherwise>
+                DESC
+            </otherwise>
+        </choose>
+    </select>
+
+    <!-- 鍒嗛〉鏌ヨ鍗栧璁㈠崟鍒楄〃 -->
+    <select id="selectSellerOrderPage" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_info
+        WHERE deleted = 0
+        <if test="providerId != null">
+            AND provider_id = #{providerId}
+        </if>
+        <if test="orderStatus != null and orderStatus != ''">
+            AND order_status = #{orderStatus}
+        </if>
+        <if test="paymentStatus != null and paymentStatus != ''">
+            AND payment_status = #{paymentStatus}
+        </if>
+        <if test="productName != null and productName != ''">
+            AND product_name LIKE CONCAT('%', #{productName}, '%')
+        </if>
+        <if test="orderId != null and orderId != ''">
+            AND order_id LIKE CONCAT('%', #{orderId}, '%')
+        </if>
+        <if test="applyTimeStart != null and applyTimeStart != ''">
+            AND apply_time >= #{applyTimeStart}::timestamp
+        </if>
+        <if test="applyTimeEnd != null and applyTimeEnd != ''">
+            AND apply_time &lt;= #{applyTimeEnd}::timestamp
+        </if>
+        <if test="createTimeStart != null and createTimeStart != ''">
+            AND created_at >= #{createTimeStart}::timestamp
+        </if>
+        <if test="createTimeEnd != null and createTimeEnd != ''">
+            AND created_at &lt;= #{createTimeEnd}::timestamp
+        </if>
+        ORDER BY
+        <choose>
+            <when test="orderBy != null and orderBy != ''">
+                ${orderBy}
+            </when>
+            <otherwise>
+                created_at
+            </otherwise>
+        </choose>
+        <choose>
+            <when test="orderDirection != null and orderDirection == 'asc'">
+                ASC
+            </when>
+            <otherwise>
+                DESC
+            </otherwise>
+        </choose>
+    </select>
+
+    <!-- 鍒嗛〉鏌ヨ寰呭鎵硅鍗曞垪琛� -->
+    <select id="selectPendingApprovalOrderPage" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM order_info
+        WHERE deleted = 0
+        AND order_status IN ('寰呭鎵�', '寰呭鎵规巿鏉�', '寰呮巿鏉�')
+        <if test="orderStatus != null and orderStatus != ''">
+            AND order_status = #{orderStatus}
+        </if>
+        <if test="productName != null and productName != ''">
+            AND product_name LIKE CONCAT('%', #{productName}, '%')
+        </if>
+        <if test="providerName != null and providerName != ''">
+            AND provider_name LIKE CONCAT('%', #{providerName}, '%')
+        </if>
+        <if test="orderId != null and orderId != ''">
+            AND order_id LIKE CONCAT('%', #{orderId}, '%')
+        </if>
+        <if test="applyTimeStart != null and applyTimeStart != ''">
+            AND apply_time >= #{applyTimeStart}::timestamp
+        </if>
+        <if test="applyTimeEnd != null and applyTimeEnd != ''">
+            AND apply_time &lt;= #{applyTimeEnd}::timestamp
+        </if>
+        ORDER BY
+        <choose>
+            <when test="orderBy != null and orderBy != ''">
+                ${orderBy}
+            </when>
+            <otherwise>
+                created_at
+            </otherwise>
+        </choose>
+        <choose>
+            <when test="orderDirection != null and orderDirection == 'asc'">
+                ASC
+            </when>
+            <otherwise>
+                DESC
+            </otherwise>
+        </choose>
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/PointsFlowMapper.xml b/src/main/resources/mapper/PointsFlowMapper.xml
new file mode 100644
index 0000000..9f25c8b
--- /dev/null
+++ b/src/main/resources/mapper/PointsFlowMapper.xml
@@ -0,0 +1,40 @@
+<?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.webmanage.mapper.PointsFlowMapper">
+
+    <!-- 鍒嗛〉鏌ヨ绉垎娴佹按锛堟敮鎸佺敤鎴�/鍗曚綅缁村害杩囨护锛� -->
+    <select id="selectPage" resultType="com.webmanage.entity.PointsFlow">
+        SELECT *
+        FROM points_flow
+        WHERE deleted = 0
+        <if test="userId != null">
+            AND user_id = #{userId}
+        </if>
+        <if test="unitId != null">
+            AND unit_id = #{unitId}
+        </if>
+        <if test="dataCategory != null and dataCategory != ''">
+            AND data_category = #{dataCategory}
+        </if>
+        <if test="dataType != null and dataType != ''">
+            AND data_type = #{dataType}
+        </if>
+        <if test="startTime != null and startTime != ''">
+            AND flow_time &gt;= #{startTime}::timestamp
+        </if>
+        <if test="endTime != null and endTime != ''">
+            AND flow_time &lt;= #{endTime}::timestamp
+        </if>
+        <if test="year != null and year != ''">
+            AND EXTRACT(YEAR FROM flow_time) = #{year}::integer
+        </if>
+        <if test="month != null and month != ''">
+            AND EXTRACT(MONTH FROM flow_time) = #{month}::integer
+        </if>
+        <if test="day != null and day != ''">
+            AND EXTRACT(DAY FROM flow_time) = #{day}::integer
+        </if>
+        ORDER BY flow_time DESC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/PointsMapper.xml b/src/main/resources/mapper/PointsMapper.xml
new file mode 100644
index 0000000..88988e5
--- /dev/null
+++ b/src/main/resources/mapper/PointsMapper.xml
@@ -0,0 +1,54 @@
+<?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.webmanage.mapper.PointsMapper">
+
+    <!-- 鍒嗛〉鏌ヨ绉垎涓昏〃 -->
+    <select id="selectPointsMainPage" resultType="com.webmanage.entity.Points">
+        SELECT *
+        FROM points
+        WHERE deleted = 0
+        <if test="queryDTO.pointsName != null and queryDTO.pointsName != ''">
+            AND points_name LIKE CONCAT('%', #{queryDTO.pointsName}, '%')
+        </if>
+        <if test="queryDTO.effectiveStartTime != null">
+            AND effective_start &gt;= #{queryDTO.effectiveStartTime}
+        </if>
+        <if test="queryDTO.effectiveEndTime != null">
+            AND effective_start &lt;= #{queryDTO.effectiveEndTime}
+        </if>
+
+        <if test="queryDTO.modifierName != null and queryDTO.modifierName != ''">
+            AND modifier_name LIKE CONCAT('%', #{queryDTO.modifierName}, '%')
+        </if>
+        <if test="queryDTO.version != null and queryDTO.version != ''">
+            AND version = #{queryDTO.version}
+        </if>
+        <if test="queryDTO.status != null and queryDTO.status != ''">
+            AND status = #{queryDTO.status}
+        </if>
+        <if test="queryDTO.createdAtBegin != null">
+            AND created_at >= #{queryDTO.createdAtBegin}
+        </if>
+        <if test="queryDTO.createdAtEnd != null">
+            AND created_at &lt;= #{queryDTO.createdAtEnd}
+        </if>
+        ORDER BY 
+        <choose>
+            <when test="queryDTO.orderBy != null and queryDTO.orderBy != ''">
+                ${queryDTO.orderBy}
+            </when>
+            <otherwise>
+                created_at
+            </otherwise>
+        </choose>
+        <choose>
+            <when test="queryDTO.orderDirection != null and queryDTO.orderDirection == 'asc'">
+                ASC
+            </when>
+            <otherwise>
+                DESC
+            </otherwise>
+        </choose>
+    </select>
+
+</mapper> 
\ No newline at end of file
diff --git a/src/main/resources/mapper/ProductPricingMapper.xml b/src/main/resources/mapper/ProductPricingMapper.xml
new file mode 100644
index 0000000..a9966a7
--- /dev/null
+++ b/src/main/resources/mapper/ProductPricingMapper.xml
@@ -0,0 +1,81 @@
+<?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.webmanage.mapper.ProductPricingMapper">
+
+    <!-- 鍩虹缁撴灉鏄犲皠 -->
+    <resultMap id="BaseResultMap" type="com.webmanage.entity.ProductPricing">
+        <id column="id" property="id" jdbcType="BIGINT"/>
+        <result column="suite_name" property="suiteName" jdbcType="VARCHAR"/>
+        <result column="sales_form" property="salesForm" jdbcType="VARCHAR"/>
+        <result column="customer_type" property="customerType" jdbcType="VARCHAR"/>
+        <result column="account_limit" property="accountLimit" jdbcType="VARCHAR"/>
+        <result column="concurrent_nodes" property="concurrentNodes" jdbcType="VARCHAR"/>
+        <result column="price_type" property="priceType" jdbcType="VARCHAR"/>
+        <result column="price_unit" property="priceUnit" jdbcType="VARCHAR"/>
+        <result column="price" property="price" jdbcType="NUMERIC"/>
+        <result column="is_active" property="isActive" jdbcType="BOOLEAN"/>
+        <result column="product_id" property="productId" jdbcType="BIGINT"/>
+        <result column="product_name" property="productName" jdbcType="VARCHAR"/>
+        <result column="provider_id" property="providerId" jdbcType="BIGINT"/>
+        <result column="provider_name" property="providerName" jdbcType="VARCHAR"/>
+        <result column="description" property="description" jdbcType="VARCHAR"/>
+        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
+        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
+        <result column="created_by" property="createdBy" jdbcType="BIGINT"/>
+        <result column="updated_by" property="updatedBy" jdbcType="BIGINT"/>
+        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!-- 鍩虹瀛楁 -->
+    <sql id="Base_Column_List">
+        id, suite_name, sales_form, customer_type, account_limit, concurrent_nodes, 
+        price_type, price_unit, price, is_active, product_id, product_name, provider_id, 
+        provider_name, description, created_at, updated_at, created_by, updated_by, deleted
+    </sql>
+
+    <!-- 鍒嗛〉鏌ヨ浜у搧瀹氫环鍒楄〃 -->
+    <select id="selectProductPricingPage" resultMap="BaseResultMap">
+        SELECT 
+        <include refid="Base_Column_List"/>
+        FROM product_pricing
+        WHERE deleted = 0
+        <if test="productId != null">
+            AND product_id = #{productId}
+        </if>
+        ORDER BY created_at DESC
+    </select>
+
+    <!-- 鏍规嵁浜у搧ID鏌ヨ瀹氫环鍒楄〃 -->
+    <select id="selectByProductId" resultMap="BaseResultMap">
+        SELECT 
+        <include refid="Base_Column_List"/>
+        FROM product_pricing
+        WHERE deleted = 0 AND product_id = #{productId}
+        ORDER BY created_at DESC
+    </select>
+
+    <!-- 鏍规嵁鏉′欢鏌ヨ浜у搧瀹氫环 -->
+    <select id="selectByCondition" resultMap="BaseResultMap">
+        SELECT 
+        <include refid="Base_Column_List"/>
+        FROM product_pricing
+        WHERE deleted = 0
+        <if test="suiteName != null and suiteName != ''">
+            AND suite_name LIKE CONCAT('%', #{suiteName}, '%')
+        </if>
+        <if test="salesForm != null and salesForm != ''">
+            AND sales_form = #{salesForm}
+        </if>
+        <if test="customerType != null and customerType != ''">
+            AND customer_type = #{customerType}
+        </if>
+        <if test="priceType != null and priceType != ''">
+            AND price_type = #{priceType}
+        </if>
+        <if test="isActive != null">
+            AND is_active = #{isActive}
+        </if>
+        ORDER BY created_at DESC
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/UserPointsMapper.xml b/src/main/resources/mapper/UserPointsMapper.xml
new file mode 100644
index 0000000..081cd84
--- /dev/null
+++ b/src/main/resources/mapper/UserPointsMapper.xml
@@ -0,0 +1,23 @@
+<?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.webmanage.mapper.UserPointsMapper">
+
+    <!-- 鏍规嵁鐢ㄦ埛ID鏌ヨ绉垎淇℃伅 -->
+    <select id="selectByUserId" resultType="com.webmanage.entity.UserPoints">
+        SELECT *
+        FROM user_points
+        WHERE user_id = #{userId}
+        AND deleted = 0
+        LIMIT 1
+    </select>
+
+    <!-- 鏍规嵁鍗曚綅ID鏌ヨ绉垎淇℃伅 -->
+    <select id="selectByUnitId" resultType="com.webmanage.entity.UserPoints">
+        SELECT *
+        FROM user_points
+        WHERE unit_id = #{unitId}
+        AND deleted = 0
+        LIMIT 1
+    </select>
+
+</mapper>
diff --git a/src/main/resources/sql/init.sql b/src/main/resources/sql/init.sql
new file mode 100644
index 0000000..61931d9
--- /dev/null
+++ b/src/main/resources/sql/init.sql
@@ -0,0 +1,501 @@
+-- 浜ゆ槗妯″潡鏁版嵁搴撹〃鍒涘缓鑴氭湰 (PostgreSQL 鐗堟湰)
+-- 鍒涘缓鏃堕棿: 2024-08-07
+
+-- 鍒涘缓椤哄簭璋冩暣: 鍏堝垱寤哄熀纭�琛� (unit, users, product)锛屽啀鍒涘缓渚濊禆瀹冧滑鐨勮〃
+
+-- 15. 鍗曚綅琛� (unit)
+CREATE TABLE unit (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    unit_name TEXT NOT NULL,
+    unit_code TEXT UNIQUE,
+    unit_type TEXT,
+    industry TEXT,
+    address TEXT,
+    contact_person TEXT,
+    contact_phone TEXT,
+    contact_email TEXT,
+    business_license TEXT,
+    legal_person TEXT,
+    registered_capital NUMERIC(15,2),
+    establishment_date DATE,
+    status TEXT DEFAULT '姝e父' CHECK (status IN ('姝e父', '鍐荤粨', '娉ㄩ攢')),
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE unit IS '鍗曚綅琛�';
+
+-- 14. 鐢ㄦ埛琛� (users) - 閬垮厤鍏抽敭瀛楀啿绐�
+CREATE TABLE users (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    username TEXT NOT NULL UNIQUE,
+    real_name TEXT,
+    email TEXT,
+    phone TEXT,
+    avatar TEXT,
+    user_type TEXT DEFAULT '涓汉鐢ㄦ埛' CHECK (user_type IN ('涓汉鐢ㄦ埛', '鍗曚綅鐢ㄦ埛')),
+    unit_id BIGINT REFERENCES unit(id),
+    unit_name TEXT,
+    status TEXT DEFAULT '姝e父' CHECK (status IN ('姝e父', '鍐荤粨', '娉ㄩ攢')),
+    last_login_time TIMESTAMP,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE users IS '鐢ㄦ埛琛�';
+
+-- 13. 浜у搧琛� (product)
+CREATE TABLE product (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    product_name TEXT NOT NULL,
+    product_code TEXT NOT NULL UNIQUE,
+    product_type TEXT,
+    category TEXT,
+    description TEXT,
+    provider_id BIGINT NOT NULL REFERENCES users(id),
+    provider_name TEXT NOT NULL,
+    provider_type TEXT CHECK (provider_type IN ('浼佷笟', '涓汉')),
+    status TEXT DEFAULT '涓婃灦' CHECK (status IN ('涓婃灦', '涓嬫灦', '瀹℃牳涓�', '宸蹭笅鏋�')),
+    audit_status TEXT DEFAULT '寰呭鏍�' CHECK (audit_status IN ('寰呭鏍�', '瀹℃牳閫氳繃', '瀹℃牳椹冲洖')),
+    tags TEXT,
+    cover_image TEXT,
+    demo_url TEXT,
+    doc_url TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    created_by BIGINT REFERENCES users(id),
+    updated_by BIGINT REFERENCES users(id),
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE product IS '浜у搧琛�';
+
+-- 1. 浜у搧瀹氫环琛� (product_pricing)
+CREATE TABLE product_pricing (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    suite_name TEXT NOT NULL,
+    sales_form TEXT NOT NULL CHECK (sales_form IN ('涔版柇', '绉熻祦', '绉佹湁澧炲寘閲�', '鍏湁澧炲寘閲�', 'OTA鏈嶅姟', '璧勬簮鍖�', '涓汉')),
+    customer_type TEXT NOT NULL CHECK (customer_type IN ('浼佷笟', '涓汉', '椤圭洰閮�')),
+    account_limit TEXT DEFAULT '涓嶉檺',
+    concurrent_nodes TEXT DEFAULT '涓嶉檺',
+    price_type TEXT NOT NULL CHECK (price_type IN ('绉垎', '鍗忚', '璐у竵', '鍏嶈垂')),
+    price_unit TEXT NOT NULL CHECK (price_unit IN ('濂�', '濂�/骞�', '骞�', '涓�', '娆�')),
+    price NUMERIC(15,2) NOT NULL,
+    is_active BOOLEAN DEFAULT TRUE,
+    product_id BIGINT NOT NULL REFERENCES product(id),
+    product_name TEXT,
+    provider_id BIGINT REFERENCES users(id),
+    provider_name TEXT,
+    description TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    created_by BIGINT REFERENCES users(id),
+    updated_by BIGINT REFERENCES users(id),
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE product_pricing IS '浜у搧瀹氫环琛�';
+
+-- 绉垎琛� (points) - 闇�鍦ㄧН鍒嗚鍒欏墠鍒涘缓
+-- 绉垎琛� (points) - 涓昏〃
+CREATE TABLE points (
+                        id BIGSERIAL PRIMARY KEY,
+                        points_name TEXT NOT NULL,
+                        effective_start DATE NOT NULL,
+                        modifier_id BIGINT NOT NULL,
+                        modifier_name TEXT NOT NULL,
+                        version TEXT NOT NULL,
+                        description TEXT,
+                        status TEXT DEFAULT '鍚敤',
+                        created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                        updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                        deleted SMALLINT DEFAULT 0
+);
+
+COMMENT ON TABLE points IS '绉垎涓昏〃';
+COMMENT ON COLUMN points.points_name IS '绉垎鍚嶇О';
+COMMENT ON COLUMN points.effective_start IS '鐢熸晥寮�濮嬫椂闂�';
+COMMENT ON COLUMN points.modifier_id IS '淇敼浜篒D';
+COMMENT ON COLUMN points.modifier_name IS '淇敼浜哄鍚�';
+COMMENT ON COLUMN points.version IS '鐗堟湰鍙�';
+COMMENT ON COLUMN points.description IS '绉垎鎻忚堪';
+COMMENT ON COLUMN points.status IS '鐘舵��';
+COMMENT ON COLUMN points.created_at IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN points.updated_at IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN points.deleted IS '閫昏緫鍒犻櫎';
+ALTER TABLE points ADD CONSTRAINT chk_status CHECK (status IN ('鍚敤', '绂佺敤'));
+ALTER TABLE points ADD CONSTRAINT chk_deleted CHECK (deleted IN (0,1));
+
+-- 绉垎瑙勫垯琛� (points_rule)
+CREATE TABLE points_rule (
+                             id BIGSERIAL PRIMARY KEY,
+                             points_id BIGINT NOT NULL,
+                             rule_type TEXT NOT NULL,
+                             category TEXT NOT NULL,
+                             rule_name TEXT NOT NULL,
+                             rule_description TEXT,
+                             status TEXT DEFAULT '鍚敤',
+                             created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                             updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                             deleted SMALLINT DEFAULT 0
+);
+
+COMMENT ON TABLE points_rule IS '绉垎瑙勫垯琛�';
+COMMENT ON COLUMN points_rule.points_id IS '鍏宠仈绉垎ID';
+COMMENT ON COLUMN points_rule.rule_type IS '绉垎瑙勫垯绫诲瀷';
+COMMENT ON COLUMN points_rule.category IS '绉垎绫诲埆';
+COMMENT ON COLUMN points_rule.rule_name IS '瑙勫垯鍚嶇О';
+COMMENT ON COLUMN points_rule.rule_description IS '瑙勫垯鎻忚堪';
+COMMENT ON COLUMN points_rule.status IS '瑙勫垯鐘舵��';
+COMMENT ON COLUMN points_rule.created_at IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN points_rule.updated_at IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN points_rule.deleted IS '閫昏緫鍒犻櫎';
+ALTER TABLE points_rule ADD CONSTRAINT fk_points FOREIGN KEY (points_id) REFERENCES points(id);
+ALTER TABLE points_rule ADD CONSTRAINT chk_rule_type CHECK (rule_type IN ('鑾峰彇', '娑堣��'));
+ALTER TABLE points_rule ADD CONSTRAINT chk_category CHECK (category IN ('璧勬簮璐$尞', '璧勬簮浼犳挱', '璧勬簮浜ゆ槗', '浜ゆ祦绀惧尯浜掑姩'));
+ALTER TABLE points_rule ADD CONSTRAINT chk_rule_status CHECK (status IN ('鍚敤', '绂佺敤'));
+ALTER TABLE points_rule ADD CONSTRAINT chk_rule_deleted CHECK (deleted IN (0,1));
+
+-- 绉垎瑙勫垯璇︽儏琛� (points_rule_detail)
+CREATE TABLE points_rule_detail (
+                                    id BIGSERIAL PRIMARY KEY,
+                                    rule_id BIGINT NOT NULL,
+                                    points_id BIGINT NOT NULL,
+                                    points_value INTEGER NOT NULL,
+                                    daily_limit INTEGER,
+                                    monthly_limit INTEGER,
+                                    yearly_limit INTEGER,
+                                    min_value INTEGER DEFAULT 0,
+                                    max_value INTEGER,
+                                    conversion_rate NUMERIC(10,4) DEFAULT 1.0,
+                                    effective_start DATE,
+                                    effective_end DATE,
+                                    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                    deleted SMALLINT DEFAULT 0
+);
+
+COMMENT ON TABLE points_rule_detail IS '绉垎瑙勫垯璇︽儏琛�';
+COMMENT ON COLUMN points_rule_detail.rule_id IS '鍏宠仈绉垎瑙勫垯ID';
+COMMENT ON COLUMN points_rule_detail.points_id IS '鍏宠仈绉垎ID';
+COMMENT ON COLUMN points_rule_detail.points_value IS '绉垎鍊�';
+COMMENT ON COLUMN points_rule_detail.daily_limit IS '姣忔棩绉垎涓婇檺鍊�';
+COMMENT ON COLUMN points_rule_detail.monthly_limit IS '姣忔湀绉垎涓婇檺鍊�';
+COMMENT ON COLUMN points_rule_detail.yearly_limit IS '姣忓勾绉垎涓婇檺鍊�';
+COMMENT ON COLUMN points_rule_detail.min_value IS '鏈�灏忓��';
+COMMENT ON COLUMN points_rule_detail.max_value IS '鏈�澶у��';
+COMMENT ON COLUMN points_rule_detail.conversion_rate IS '杞崲姣旂巼';
+COMMENT ON COLUMN points_rule_detail.effective_start IS '鐢熸晥寮�濮嬫椂闂�';
+COMMENT ON COLUMN points_rule_detail.effective_end IS '鐢熸晥缁撴潫鏃堕棿';
+COMMENT ON COLUMN points_rule_detail.created_at IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN points_rule_detail.updated_at IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN points_rule_detail.deleted IS '閫昏緫鍒犻櫎';
+ALTER TABLE points_rule_detail ADD CONSTRAINT fk_rule FOREIGN KEY (rule_id) REFERENCES points_rule(id);
+ALTER TABLE points_rule_detail ADD CONSTRAINT fk_detail_points FOREIGN KEY (points_id) REFERENCES points(id);
+ALTER TABLE points_rule_detail ADD CONSTRAINT chk_detail_deleted CHECK (deleted IN (0,1));
+
+-- 绉垎娴佹按琛� (points_transaction)
+CREATE TABLE points_transaction (
+                                    id BIGSERIAL PRIMARY KEY,
+                                    data_category TEXT NOT NULL,
+                                    transaction_name TEXT NOT NULL,
+                                    transaction_time TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                    points_change INTEGER NOT NULL,
+                                    rule_type TEXT NOT NULL,
+                                    user_id BIGINT,
+                                    unit_id BIGINT,
+                                    user_type TEXT NOT NULL,
+                                    rule_id BIGINT,
+                                    detail_id BIGINT,
+                                    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                    deleted SMALLINT DEFAULT 0
+);
+
+COMMENT ON TABLE points_transaction IS '绉垎娴佹按琛�';
+COMMENT ON COLUMN points_transaction.data_category IS '鏁版嵁绫荤洰';
+COMMENT ON COLUMN points_transaction.transaction_name IS '鍚嶇О';
+COMMENT ON COLUMN points_transaction.transaction_time IS '鏃堕棿';
+COMMENT ON COLUMN points_transaction.points_change IS '绉垎鍙樺姩鍊�';
+COMMENT ON COLUMN points_transaction.rule_type IS '绉垎瑙勫垯绫诲瀷';
+COMMENT ON COLUMN points_transaction.user_id IS '鐢ㄦ埛ID';
+COMMENT ON COLUMN points_transaction.unit_id IS '浼佷笟ID';
+COMMENT ON COLUMN points_transaction.user_type IS '鐢ㄦ埛绫诲瀷';
+COMMENT ON COLUMN points_transaction.rule_id IS '鍏宠仈瑙勫垯ID';
+COMMENT ON COLUMN points_transaction.detail_id IS '鍏宠仈瑙勫垯璇︽儏ID';
+COMMENT ON COLUMN points_transaction.created_at IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN points_transaction.deleted IS '閫昏緫鍒犻櫎';
+ALTER TABLE points_transaction ADD CONSTRAINT chk_data_category CHECK (data_category IN ('鐢ㄦ埛鍙備笌', '鍏朵粬'));
+ALTER TABLE points_transaction ADD CONSTRAINT chk_trans_rule_type CHECK (rule_type IN ('鑾峰彇', '娑堣��'));
+ALTER TABLE points_transaction ADD CONSTRAINT chk_user_type CHECK (user_type IN ('鍗曚綅鐢ㄦ埛', '涓汉鐢ㄦ埛'));
+ALTER TABLE points_transaction ADD CONSTRAINT fk_rule_id FOREIGN KEY (rule_id) REFERENCES points_rule(id);
+ALTER TABLE points_transaction ADD CONSTRAINT fk_detail_id FOREIGN KEY (detail_id) REFERENCES points_rule_detail(id);
+ALTER TABLE points_transaction ADD CONSTRAINT chk_trans_deleted CHECK (deleted IN (0,1));
+
+-- 绉垎璐︽埛琛� (points_account)
+CREATE TABLE points_account (
+                                id BIGSERIAL PRIMARY KEY,
+                                user_id BIGINT NOT NULL,
+                                points_balance INTEGER NOT NULL DEFAULT 0,
+                                total_earned INTEGER NOT NULL DEFAULT 0,
+                                total_consumed INTEGER NOT NULL DEFAULT 0,
+                                account_type TEXT NOT NULL,
+                                account_status TEXT DEFAULT '姝e父',
+                                last_transaction_time TIMESTAMPTZ,
+                                created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
+                                deleted SMALLINT DEFAULT 0
+);
+
+COMMENT ON TABLE points_account IS '绉垎璐︽埛琛�';
+COMMENT ON COLUMN points_account.user_id IS '鐢ㄦ埛ID';
+COMMENT ON COLUMN points_account.points_balance IS '绉垎浣欓';
+COMMENT ON COLUMN points_account.total_earned IS '绱鑾峰彇绉垎';
+COMMENT ON COLUMN points_account.total_consumed IS '绱娑堣�楃Н鍒�';
+COMMENT ON COLUMN points_account.account_type IS '璐︽埛绫诲瀷';
+COMMENT ON COLUMN points_account.account_status IS '璐︽埛鐘舵��';
+COMMENT ON COLUMN points_account.last_transaction_time IS '鏈�鍚庝氦鏄撴椂闂�';
+COMMENT ON COLUMN points_account.created_at IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN points_account.updated_at IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN points_account.deleted IS '閫昏緫鍒犻櫎';
+ALTER TABLE points_account ADD CONSTRAINT chk_account_type CHECK (account_type IN ('涓汉绉垎', '鍗曚綅绉垎'));
+ALTER TABLE points_account ADD CONSTRAINT chk_account_status CHECK (account_status IN ('姝e父', '鍐荤粨', '娉ㄩ攢'));
+ALTER TABLE points_account ADD CONSTRAINT chk_account_deleted CHECK (deleted IN (0,1));
+
+-- 鍒涘缓绱㈠紩
+CREATE INDEX idx_points_rule_points ON points_rule(points_id);
+CREATE INDEX idx_points_rule_type ON points_rule(rule_type);
+CREATE INDEX idx_points_detail_rule ON points_rule_detail(rule_id);
+CREATE INDEX idx_transaction_user ON points_transaction(user_id);
+CREATE INDEX idx_transaction_time ON points_transaction(transaction_time);
+CREATE INDEX idx_account_user ON points_account(user_id);
+
+-- 2. 璐墿杞﹁〃 (shopping_cart)
+-- CREATE TABLE shopping_cart (
+--     id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+--     user_id BIGINT NOT NULL REFERENCES users(id),
+--     unit_id BIGINT REFERENCES unit(id),
+--     suite_name TEXT NOT NULL,
+--     sales_form TEXT NOT NULL CHECK (sales_form IN ('涔版柇', '绉熻祦', '绉佹湁澧炲寘閲�', '鍏湁澧炲寘閲�', 'OTA鏈嶅姟', '璧勬簮鍖�', '涓汉')),
+--     customer_type TEXT NOT NULL CHECK (customer_type IN ('浼佷笟', '涓汉', '椤圭洰閮�')),
+--     account_limit TEXT DEFAULT '涓嶉檺',
+--     concurrent_nodes TEXT DEFAULT '涓嶉檺',
+--     price_type TEXT NOT NULL CHECK (price_type IN ('绉垎', '鍗忚', '璐у竵', '鍏嶈垂')),
+--     price_unit TEXT NOT NULL CHECK (price_unit IN ('濂�', '濂�/骞�', '骞�', '涓�', '娆�')),
+--     unit_price NUMERIC(15,2) NOT NULL,
+--     quantity INTEGER NOT NULL DEFAULT 1,
+--     duration INTEGER,
+--     product_id BIGINT NOT NULL REFERENCES product(id),
+--     product_name TEXT,
+--     provider_id BIGINT REFERENCES users(id),
+--     provider_name TEXT,
+--     total_amount NUMERIC(15,2),
+--     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+--     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+--     deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+-- );
+--
+-- COMMENT ON TABLE shopping_cart IS '璐墿杞﹁〃';
+
+-- 璐墿杞﹁〃 (cart)
+CREATE TABLE cart (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    user_id BIGINT NOT NULL REFERENCES users(id),
+    unit_id BIGINT NOT NULL REFERENCES unit(id),
+    pricing_id BIGINT NOT NULL REFERENCES product_pricing(id),
+    product_id BIGINT NOT NULL REFERENCES product(id),
+    product_name TEXT,
+    suite_name TEXT,
+    sales_form TEXT,
+    customer_type TEXT,
+    account_limit TEXT,
+    concurrent_nodes TEXT,
+    price_type TEXT,
+    price_unit TEXT,
+    unit_price DECIMAL(15,2) NOT NULL,
+    quantity INTEGER NOT NULL DEFAULT 1,
+    duration INTEGER,
+    total_price DECIMAL(15,2),
+    provider_id BIGINT REFERENCES users(id),
+    provider_name TEXT,
+    remarks TEXT,
+    add_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1)),
+    UNIQUE (user_id, unit_id, pricing_id, deleted)
+);
+
+COMMENT ON TABLE cart IS '璐墿杞﹁〃';
+
+-- 3. 璁㈠崟琛� (order_info)
+CREATE TABLE order_info (
+    order_id TEXT PRIMARY KEY,
+    product_id BIGINT NOT NULL REFERENCES product(id),
+    user_id BIGINT NOT NULL REFERENCES users(id),
+    unit_id BIGINT REFERENCES unit(id),
+    product_name TEXT NOT NULL,
+    provider_name TEXT NOT NULL,
+    provider_id BIGINT NOT NULL REFERENCES users(id),
+    apply_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    order_status TEXT NOT NULL DEFAULT '寰呭鎵�' CHECK (order_status IN ('寰呭鎵�', '寰呭鎵规巿鏉�', '寰呮巿鏉�', '寰呬笂浼犳枃浠�', '寰呬氦鏄撶‘璁�', '宸插畬鎴�', '宸插彇娑�', '宸查┏鍥�')),
+    total_amount NUMERIC(15,2) NOT NULL,
+    payment_type TEXT CHECK (payment_type IN ('绉垎', '璐у竵', '鍗忚')),
+    payment_status TEXT DEFAULT '鏈敮浠�' CHECK (payment_status IN ('鏈敮浠�', '宸叉敮浠�', '鏀粯澶辫触', '宸查��娆�')),
+    workflow_id TEXT,
+    current_step TEXT,
+    approval_flow TEXT,
+    buyer_remarks TEXT,
+    seller_remarks TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE order_info IS '璁㈠崟琛�';
+
+-- 4. 璁㈠崟璇︽儏琛� (order_detail)
+CREATE TABLE order_detail (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    order_id TEXT NOT NULL REFERENCES order_info(order_id),
+    pricing_id BIGINT NOT NULL REFERENCES product_pricing(id),
+    product_id BIGINT NOT NULL REFERENCES product(id),
+    suite_name TEXT NOT NULL,
+    sales_form TEXT NOT NULL,
+    customer_type TEXT NOT NULL,
+    account_limit TEXT,
+    concurrent_nodes TEXT,
+    price_type TEXT NOT NULL,
+    price_unit TEXT NOT NULL,
+    unit_price NUMERIC(15,2) NOT NULL,
+    quantity INTEGER NOT NULL,
+    duration INTEGER,
+    total_price NUMERIC(15,2) NOT NULL,
+    provider_id BIGINT NOT NULL REFERENCES users(id),
+    provider_name TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    remarks TEXT,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE order_detail IS '璁㈠崟璇︽儏琛�';
+
+-- 5. 璁㈠崟闄勪欢琛� (order_attachment)
+CREATE TABLE order_attachment (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    order_id TEXT NOT NULL REFERENCES order_info(order_id),
+    file_name TEXT NOT NULL,
+    original_name TEXT,
+    file_type TEXT NOT NULL,
+    file_size BIGINT NOT NULL,
+    file_url TEXT NOT NULL,
+    file_path TEXT,
+    bucket_name TEXT,
+    object_name TEXT,
+    upload_user_id BIGINT REFERENCES users(id),
+    upload_user_name TEXT,
+    attachment_type TEXT CHECK (attachment_type IN ('鍚堝悓', '鍙戠エ', '鍏朵粬')),
+    description TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE order_attachment IS '璁㈠崟闄勪欢琛�';
+
+-- 6. 璁㈠崟瀹℃牳琛� (order_approval)
+CREATE TABLE order_approval (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    order_id TEXT NOT NULL REFERENCES order_info(order_id),
+    approval_step TEXT NOT NULL,
+    approval_type TEXT NOT NULL CHECK (approval_type IN ('瀹℃壒', '鎺堟潈')),
+    approval_opinion TEXT,
+    approval_result TEXT NOT NULL CHECK (approval_result IN ('閫氳繃', '椹冲洖', '寰呭鐞�')),
+    approver_id BIGINT NOT NULL REFERENCES users(id),
+    approver_name TEXT NOT NULL,
+    approver_role TEXT,
+    approval_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    next_approver_id BIGINT REFERENCES users(id),
+    next_approver_name TEXT,
+    workflow_status TEXT,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE order_approval IS '璁㈠崟瀹℃牳琛�';
+
+-- 7. 璁㈠崟璇勪环琛� (order_evaluation)
+CREATE TABLE order_evaluation (
+    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
+    order_id TEXT NOT NULL REFERENCES order_info(order_id),
+    evaluator_id BIGINT NOT NULL REFERENCES users(id),
+    evaluator_name TEXT NOT NULL,
+    evaluator_type TEXT NOT NULL CHECK (evaluator_type IN ('涔板', '鍗栧')),
+    content TEXT NOT NULL,
+    rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
+    service_rating INTEGER CHECK (service_rating >= 1 AND service_rating <= 5),
+    quality_rating INTEGER CHECK (quality_rating >= 1 AND quality_rating <= 5),
+    delivery_rating INTEGER CHECK (delivery_rating >= 1 AND delivery_rating <= 5),
+    is_anonymous BOOLEAN DEFAULT FALSE,
+    reply_content TEXT,
+    reply_user_id BIGINT REFERENCES users(id),
+    reply_time TIMESTAMP,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    deleted INTEGER DEFAULT 0 CHECK (deleted IN (0,1))
+);
+
+COMMENT ON TABLE order_evaluation IS '璁㈠崟璇勪环琛�';
+
+-- 鍒涘缓绱㈠紩 (PostgreSQL 璇硶)
+CREATE INDEX idx_product_pricing_product_id ON product_pricing(product_id);
+CREATE INDEX idx_product_pricing_status ON product_pricing(is_active);
+CREATE INDEX idx_order_info_user_id ON order_info(user_id);
+CREATE INDEX idx_order_info_provider_id ON order_info(provider_id);
+CREATE INDEX idx_order_info_status ON order_info(order_status);
+CREATE INDEX idx_order_info_apply_time ON order_info(apply_time);
+CREATE INDEX idx_order_detail_order_id ON order_detail(order_id);
+CREATE INDEX idx_order_attachment_order_id ON order_attachment(order_id);
+CREATE INDEX idx_order_approval_order_id ON order_approval(order_id);
+CREATE INDEX idx_order_approval_approver_id ON order_approval(approver_id);
+CREATE INDEX idx_order_evaluation_order_id ON order_evaluation(order_id);
+CREATE INDEX idx_order_evaluation_evaluator_id ON order_evaluation(evaluator_id);
+CREATE INDEX idx_points_rule_points_id ON points_rule(points_id);
+CREATE INDEX idx_points_rule_detail_rule_id ON points_rule_detail(rule_id);
+CREATE INDEX idx_product_provider_id ON product(provider_id);
+CREATE INDEX idx_product_status ON product(status);
+CREATE INDEX idx_users_unit_id ON users(unit_id);
+CREATE INDEX idx_users_status ON users(status);
+
+-- 璐墿杞﹁〃绱㈠紩
+CREATE INDEX idx_cart_user_unit ON cart(user_id, unit_id, deleted);
+CREATE INDEX idx_cart_pricing ON cart(pricing_id, deleted);
+CREATE INDEX idx_cart_product ON cart(product_id, deleted);
+CREATE INDEX idx_cart_provider ON cart(provider_id, deleted);
+CREATE INDEX idx_cart_add_time ON cart(add_time, deleted);
+
+-- 娣诲姞鍒楁敞閲� (PostgreSQL 鏂瑰紡)
+COMMENT ON COLUMN product_pricing.suite_name IS '浜у搧濂椾欢鍚嶇О';
+COMMENT ON COLUMN product_pricing.sales_form IS '閿�鍞舰寮�';
+-- 鍏朵粬鍒楁敞閲婃寜鐩稿悓鏍煎紡琛ュ厖...
+
+
+INSERT INTO unit (unit_name, unit_code, unit_type, industry, status) VALUES
+('娴嬭瘯浼佷笟', 'TEST_ENTERPRISE', '浼佷笟', '淇℃伅鎶�鏈�', '姝e父'),
+('娴嬭瘯鍗曚綅', 'TEST_UNIT', '浜嬩笟鍗曚綅', '鏁欒偛', '姝e父');
+
+INSERT INTO users (username, real_name, user_type, unit_id, status) VALUES
+('admin', '绯荤粺绠$悊鍛�', '涓汉鐢ㄦ埛', NULL, '姝e父'),
+('test_user', '娴嬭瘯鐢ㄦ埛', '涓汉鐢ㄦ埛', 1, '姝e父'),
+('test_provider', '娴嬭瘯鎻愪緵鑰�', '鍗曚綅鐢ㄦ埛', 1, '姝e父');
+
+INSERT INTO product (product_name, product_code, product_type, category, description, provider_id, provider_name, status, audit_status) VALUES
+('娴嬭瘯浜у搧1', 'TEST_PRODUCT_001', '杞欢浜у搧', '浼佷笟绠$悊', '杩欐槸涓�涓祴璇曚骇鍝�', 3, '娴嬭瘯鎻愪緵鑰�', '涓婃灦', '瀹℃牳閫氳繃'),
+('娴嬭瘯浜у搧2', 'TEST_PRODUCT_002', '鏈嶅姟浜у搧', '鎶�鏈湇鍔�', '杩欐槸鍙︿竴涓祴璇曚骇鍝�', 3, '娴嬭瘯鎻愪緵鑰�', '涓婃灦', '瀹℃牳閫氳繃');
+
+INSERT INTO product_pricing (suite_name, sales_form, customer_type, price_type, price_unit, price, product_id, product_name, provider_id, provider_name, is_active) VALUES
+('鍩虹鐗�', '涔版柇', '浼佷笟', '绉垎', '濂�', 1000, 1, '娴嬭瘯浜у搧1', 3, '娴嬭瘯鎻愪緵鑰�', true),
+('涓撲笟鐗�', '绉熻祦', '浼佷笟', '绉垎', '濂�/骞�', 500, 1, '娴嬭瘯浜у搧1', 3, '娴嬭瘯鎻愪緵鑰�', true),
+('浼佷笟鐗�', '涔版柇', '浼佷笟', '璐у竵', '濂�', 10000, 2, '娴嬭瘯浜у搧2', 3, '娴嬭瘯鎻愪緵鑰�', true);
diff --git a/src/main/resources/sql/trade_module.sql b/src/main/resources/sql/trade_module.sql
new file mode 100644
index 0000000..93e02a5
--- /dev/null
+++ b/src/main/resources/sql/trade_module.sql
@@ -0,0 +1,403 @@
+-- 浜ゆ槗妯″潡鏁版嵁搴撹〃鍒涘缓鑴氭湰
+-- 鍒涘缓鏃堕棿: 2024-08-07
+-- 鏁版嵁搴�: PostgreSQL
+
+-- 1. 浜у搧瀹氫环琛� (product_pricing)
+CREATE TABLE product_pricing (
+    id BIGSERIAL PRIMARY KEY,
+    suite_name VARCHAR(100) NOT NULL COMMENT '浜у搧濂椾欢鍚嶇О',
+    sales_form VARCHAR(20) NOT NULL CHECK (sales_form IN ('涔版柇', '绉熻祦', '绉佹湁澧炲寘閲�', '鍏湁澧炲寘閲�', 'OTA鏈嶅姟', '璧勬簮鍖�', '涓汉')) COMMENT '閿�鍞舰寮�',
+    customer_type VARCHAR(10) NOT NULL CHECK (customer_type IN ('浼佷笟', '涓汉', '椤圭洰閮�')) COMMENT '瀹㈡埛瀵硅薄',
+    account_limit VARCHAR(20) DEFAULT '涓嶉檺' COMMENT '璐︽埛鏁伴噺',
+    concurrent_nodes VARCHAR(20) DEFAULT '涓嶉檺' COMMENT '骞跺彂鑺傜偣鏁�',
+    price_type VARCHAR(10) NOT NULL CHECK (price_type IN ('绉垎', '鍗忚', '璐у竵', '鍏嶈垂')) COMMENT '浠锋牸璁剧疆',
+    price_unit VARCHAR(20) NOT NULL CHECK (price_unit IN ('濂�', '濂�/骞�', '骞�', '涓�', '娆�')) COMMENT '浠锋牸鍗曚綅',
+    price NUMERIC(15,2) NOT NULL COMMENT '浠锋牸鍊�',
+    is_active BOOLEAN DEFAULT TRUE COMMENT '鍚敤鐘舵��',
+    product_id BIGINT NOT NULL COMMENT '鍏宠仈浜у搧ID',
+    product_name VARCHAR(100) COMMENT '浜у搧鍚嶇О',
+    provider_id BIGINT COMMENT '浜у搧鎻愪緵鑰匢D',
+    provider_name VARCHAR(100) COMMENT '浜у搧鎻愪緵鑰呭悕绉�',
+    description TEXT COMMENT '浜у搧鎻忚堪',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    created_by BIGINT COMMENT '鍒涘缓浜篒D',
+    updated_by BIGINT COMMENT '鏇存柊浜篒D',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 2. 璐墿杞﹁〃 (shopping_cart)
+CREATE TABLE shopping_cart (
+    id BIGSERIAL PRIMARY KEY,
+    user_id BIGINT NOT NULL COMMENT '鐢ㄦ埛ID',
+    unit_id BIGINT COMMENT '鍗曚綅ID',
+    suite_name VARCHAR(100) NOT NULL COMMENT '浜у搧濂椾欢鍚嶇О',
+    sales_form VARCHAR(20) NOT NULL CHECK (sales_form IN ('涔版柇', '绉熻祦', '绉佹湁澧炲寘閲�', '鍏湁澧炲寘閲�', 'OTA鏈嶅姟', '璧勬簮鍖�', '涓汉')) COMMENT '閿�鍞舰寮�',
+    customer_type VARCHAR(10) NOT NULL CHECK (customer_type IN ('浼佷笟', '涓汉', '椤圭洰閮�')) COMMENT '瀹㈡埛瀵硅薄',
+    account_limit VARCHAR(20) DEFAULT '涓嶉檺' COMMENT '璐︽埛鏁伴噺',
+    concurrent_nodes VARCHAR(20) DEFAULT '涓嶉檺' COMMENT '骞跺彂鑺傜偣鏁�',
+    price_type VARCHAR(10) NOT NULL CHECK (price_type IN ('绉垎', '鍗忚', '璐у竵', '鍏嶈垂')) COMMENT '浠锋牸绫诲瀷',
+    price_unit VARCHAR(20) NOT NULL CHECK (price_unit IN ('濂�', '濂�/骞�', '骞�', '涓�', '娆�')) COMMENT '浠锋牸鍗曚綅',
+    unit_price NUMERIC(15,2) NOT NULL COMMENT '鍗曚环',
+    quantity INTEGER NOT NULL DEFAULT 1 COMMENT '鏁伴噺',
+    duration INTEGER COMMENT '鏈熼檺(骞�)',
+    product_id BIGINT NOT NULL COMMENT '浜у搧ID',
+    product_name VARCHAR(100) COMMENT '浜у搧鍚嶇О',
+    provider_id BIGINT COMMENT '浜у搧鎻愪緵鑰匢D',
+    provider_name VARCHAR(100) COMMENT '浜у搧鎻愪緵鑰呭悕绉�',
+    total_amount NUMERIC(15,2) COMMENT '鎬婚噾棰�',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 璐墿杞﹁〃
+CREATE TABLE IF NOT EXISTS cart (
+    id BIGSERIAL PRIMARY KEY,
+    user_id BIGINT NOT NULL COMMENT '鐢ㄦ埛ID',
+    unit_id BIGINT NOT NULL COMMENT '鍗曚綅ID',
+    pricing_id BIGINT NOT NULL COMMENT '鍟嗗搧瀹氫环ID',
+    product_id BIGINT NOT NULL COMMENT '鍟嗗搧ID',
+    product_name VARCHAR(255) COMMENT '鍟嗗搧鍚嶇О',
+    suite_name VARCHAR(255) COMMENT '鍟嗗搧濂椾欢鍚嶇О',
+    sales_form VARCHAR(100) COMMENT '閿�鍞舰寮�',
+    customer_type VARCHAR(100) COMMENT '瀹㈡埛瀵硅薄',
+    account_limit VARCHAR(100) COMMENT '璐︽埛鏁伴噺',
+    concurrent_nodes VARCHAR(100) COMMENT '骞跺彂鑺傜偣鏁�',
+    price_type VARCHAR(100) COMMENT '浠锋牸绫诲瀷',
+    price_unit VARCHAR(100) COMMENT '浠锋牸鍗曚綅',
+    unit_price DECIMAL(15,2) NOT NULL COMMENT '鍗曚环',
+    quantity INTEGER NOT NULL DEFAULT 1 COMMENT '鏁伴噺',
+    duration INTEGER COMMENT '骞撮檺',
+    total_price DECIMAL(15,2) COMMENT '灏忚閲戦',
+    provider_id BIGINT COMMENT '浜у搧鎻愪緵鑰匢D',
+    provider_name VARCHAR(255) COMMENT '浜у搧鎻愪緵鑰呭悕绉�',
+    remarks TEXT COMMENT '澶囨敞',
+    add_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '娣诲姞鏃堕棿',
+    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�',
+    UNIQUE KEY uk_user_unit_pricing (user_id, unit_id, pricing_id, deleted)
+);
+
+-- 3. 璁㈠崟琛� (order_info)
+CREATE TABLE order_info (
+    order_id VARCHAR(50) PRIMARY KEY COMMENT '璁㈠崟缂栧彿',
+    product_id BIGINT NOT NULL COMMENT '浜у搧ID',
+    user_id BIGINT NOT NULL COMMENT '鐢ㄦ埛ID',
+    unit_id BIGINT COMMENT '鍗曚綅ID',
+    product_name VARCHAR(100) NOT NULL COMMENT '浜у搧鍚嶇О',
+    provider_name VARCHAR(100) NOT NULL COMMENT '浜у搧鎻愪緵鑰呭悕绉�',
+    provider_id BIGINT NOT NULL COMMENT '鎻愪緵鑰匢D',
+    apply_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鐢宠鏃堕棿',
+    order_status VARCHAR(20) NOT NULL DEFAULT '寰呭鎵�' CHECK (order_status IN ('寰呭鎵�', '寰呭鎵规巿鏉�', '寰呮巿鏉�', '寰呬笂浼犳枃浠�', '寰呬氦鏄撶‘璁�', '宸插畬鎴�', '宸插彇娑�', '宸查┏鍥�')) COMMENT '璁㈠崟鐘舵��',
+    total_amount NUMERIC(15,2) NOT NULL COMMENT '璁㈠崟鎬婚噾棰�',
+    payment_type VARCHAR(20) COMMENT '鏀粯鏂瑰紡(绉垎/璐у竵/鍗忚)',
+    payment_status VARCHAR(20) DEFAULT '鏈敮浠�' CHECK (payment_status IN ('鏈敮浠�', '宸叉敮浠�', '鏀粯澶辫触', '宸查��娆�')) COMMENT '鏀粯鐘舵��',
+    workflow_id VARCHAR(50) COMMENT '宸ヤ綔娴両D',
+    current_step VARCHAR(50) COMMENT '褰撳墠瀹℃壒姝ラ',
+    approval_flow TEXT COMMENT '瀹℃壒娴佺▼閰嶇疆',
+    buyer_remarks TEXT COMMENT '涔板澶囨敞',
+    seller_remarks TEXT COMMENT '鍗栧澶囨敞',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 4. 璁㈠崟璇︽儏琛� (order_detail)
+CREATE TABLE order_detail (
+    id BIGSERIAL PRIMARY KEY,
+    order_id VARCHAR(50) NOT NULL COMMENT '鍏宠仈璁㈠崟ID',
+    pricing_id BIGINT NOT NULL COMMENT '鍏宠仈浜у搧瀹氫环ID',
+    product_id BIGINT NOT NULL COMMENT '浜у搧ID',
+    suite_name VARCHAR(100) NOT NULL COMMENT '浜у搧濂椾欢鍚嶇О',
+    sales_form VARCHAR(20) NOT NULL COMMENT '閿�鍞舰寮�',
+    customer_type VARCHAR(10) NOT NULL COMMENT '瀹㈡埛瀵硅薄',
+    account_limit VARCHAR(20) COMMENT '璐︽埛鏁伴噺',
+    concurrent_nodes VARCHAR(20) COMMENT '骞跺彂鑺傜偣鏁�',
+    price_type VARCHAR(10) NOT NULL COMMENT '浠锋牸绫诲瀷',
+    price_unit VARCHAR(20) NOT NULL COMMENT '浠锋牸鍗曚綅',
+    unit_price NUMERIC(15,2) NOT NULL COMMENT '鍗曚环',
+    quantity INTEGER NOT NULL COMMENT '鏁伴噺',
+    duration INTEGER COMMENT '骞撮檺',
+    total_price NUMERIC(15,2) NOT NULL COMMENT '灏忚閲戦',
+    provider_id BIGINT NOT NULL COMMENT '浜у搧鎻愪緵鑰匢D',
+    provider_name VARCHAR(100) COMMENT '浜у搧鎻愪緵鑰呭悕绉�',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    remarks TEXT COMMENT '澶囨敞',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 5. 璁㈠崟闄勪欢琛� (order_attachment)
+CREATE TABLE order_attachment (
+    id BIGSERIAL PRIMARY KEY,
+    order_id VARCHAR(50) NOT NULL COMMENT '鍏宠仈璁㈠崟ID',
+    file_name VARCHAR(255) NOT NULL COMMENT '闄勪欢鍚嶇О',
+    original_name VARCHAR(255) COMMENT '鍘熷鏂囦欢鍚�',
+    file_type VARCHAR(50) NOT NULL COMMENT '闄勪欢绫诲瀷',
+    file_size BIGINT NOT NULL COMMENT '闄勪欢澶у皬(瀛楄妭)',
+    file_url VARCHAR(500) NOT NULL COMMENT '闄勪欢鍦板潃',
+    file_path VARCHAR(500) COMMENT '鏂囦欢瀛樺偍璺緞',
+    bucket_name VARCHAR(100) COMMENT 'MinIO瀛樺偍妗跺悕绉�',
+    object_name VARCHAR(500) COMMENT 'MinIO瀵硅薄鍚嶇О',
+    upload_user_id BIGINT COMMENT '涓婁紶鐢ㄦ埛ID',
+    upload_user_name VARCHAR(100) COMMENT '涓婁紶鐢ㄦ埛鍚�',
+    attachment_type VARCHAR(50) COMMENT '闄勪欢绫诲瀷(鍚堝悓/鍙戠エ/鍏朵粬)',
+    description TEXT COMMENT '闄勪欢鎻忚堪',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 6. 璁㈠崟瀹℃牳琛� (order_approval)
+CREATE TABLE order_approval (
+    id BIGSERIAL PRIMARY KEY,
+    order_id VARCHAR(50) NOT NULL COMMENT '鍏宠仈璁㈠崟ID',
+    approval_step VARCHAR(50) NOT NULL COMMENT '瀹℃壒姝ラ',
+    approval_type VARCHAR(20) NOT NULL CHECK (approval_type IN ('瀹℃壒', '鎺堟潈')) COMMENT '瀹℃壒绫诲瀷',
+    approval_opinion TEXT COMMENT '瀹℃牳鎰忚',
+    approval_result VARCHAR(20) NOT NULL CHECK (approval_result IN ('閫氳繃', '椹冲洖', '寰呭鐞�')) COMMENT '瀹℃壒缁撴灉',
+    approver_id BIGINT NOT NULL COMMENT '瀹℃牳浜篒D',
+    approver_name VARCHAR(100) NOT NULL COMMENT '瀹℃牳浜哄鍚�',
+    approver_role VARCHAR(100) COMMENT '瀹℃牳浜鸿鑹�',
+    approval_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '瀹℃牳鏃堕棿',
+    next_approver_id BIGINT COMMENT '涓嬩竴瀹℃壒浜篒D',
+    next_approver_name VARCHAR(100) COMMENT '涓嬩竴瀹℃壒浜哄鍚�',
+    workflow_status VARCHAR(20) COMMENT '宸ヤ綔娴佺姸鎬�',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 7. 璁㈠崟璇勪环琛� (order_evaluation)
+CREATE TABLE order_evaluation (
+    id BIGSERIAL PRIMARY KEY,
+    order_id VARCHAR(50) NOT NULL COMMENT '鍏宠仈璁㈠崟ID',
+    evaluator_id BIGINT NOT NULL COMMENT '璇勪环浜篒D',
+    evaluator_name VARCHAR(100) NOT NULL COMMENT '璇勪环浜哄鍚�',
+    evaluator_type VARCHAR(20) NOT NULL CHECK (evaluator_type IN ('涔板', '鍗栧')) COMMENT '璇勪环浜虹被鍨�',
+    content TEXT NOT NULL COMMENT '璇勪环鍐呭',
+    rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5) COMMENT '璇勫垎(1-5)',
+    service_rating INTEGER CHECK (service_rating >= 1 AND service_rating <= 5) COMMENT '鏈嶅姟璇勫垎',
+    quality_rating INTEGER CHECK (quality_rating >= 1 AND quality_rating <= 5) COMMENT '璐ㄩ噺璇勫垎',
+    delivery_rating INTEGER CHECK (delivery_rating >= 1 AND delivery_rating <= 5) COMMENT '浜や粯璇勫垎',
+    is_anonymous BOOLEAN DEFAULT FALSE COMMENT '鏄惁鍖垮悕璇勪环',
+    reply_content TEXT COMMENT '鍥炲鍐呭',
+    reply_user_id BIGINT COMMENT '鍥炲鐢ㄦ埛ID',
+    reply_time TIMESTAMP COMMENT '鍥炲鏃堕棿',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 8. 绉垎琛� (points)
+CREATE TABLE points (
+    id BIGSERIAL PRIMARY KEY,
+    points_name VARCHAR(100) NOT NULL COMMENT '绉垎鍚嶇О',
+    points_code VARCHAR(50) NOT NULL UNIQUE COMMENT '绉垎缂栫爜',
+    points_type VARCHAR(20) NOT NULL CHECK (points_type IN ('涓汉绉垎', '鍗曚綅绉垎', '浜у搧绉垎')) COMMENT '绉垎绫诲瀷',
+    effective_start DATE NOT NULL COMMENT '鐢熸晥寮�濮嬫椂闂�',
+    effective_end DATE COMMENT '鐢熸晥缁撴潫鏃堕棿',
+    modifier_id BIGINT NOT NULL COMMENT '淇敼浜篒D',
+    modifier_name VARCHAR(100) NOT NULL COMMENT '淇敼浜哄鍚�',
+    version VARCHAR(20) NOT NULL COMMENT '鐗堟湰鍙�',
+    description TEXT COMMENT '绉垎鎻忚堪',
+    status VARCHAR(10) DEFAULT '鍚敤' CHECK (status IN ('鍚敤', '绂佺敤')) COMMENT '鐘舵��',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 9. 绉垎瑙勫垯琛� (points_rule) - 鏇存柊鐜版湁琛ㄧ粨鏋�
+ALTER TABLE points_rule ADD COLUMN IF NOT EXISTS points_id BIGINT COMMENT '鍏宠仈绉垎ID';
+ALTER TABLE points_rule ADD COLUMN IF NOT EXISTS rule_code VARCHAR(50) COMMENT '瑙勫垯缂栫爜';
+ALTER TABLE points_rule ADD COLUMN IF NOT EXISTS effective_start DATE COMMENT '鐢熸晥寮�濮嬫椂闂�';
+ALTER TABLE points_rule ADD COLUMN IF NOT EXISTS effective_end DATE COMMENT '鐢熸晥缁撴潫鏃堕棿';
+ALTER TABLE points_rule ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 0 COMMENT '浼樺厛绾�';
+
+-- 10. 绉垎瑙勫垯璇︽儏琛� (points_rule_detail)
+CREATE TABLE points_rule_detail (
+    id BIGSERIAL PRIMARY KEY,
+    rule_id BIGINT NOT NULL COMMENT '鍏宠仈绉垎瑙勫垯ID',
+    points_id BIGINT NOT NULL COMMENT '鍏宠仈绉垎ID',
+    points_value INTEGER NOT NULL COMMENT '绉垎鍊�',
+    daily_limit INTEGER COMMENT '姣忔棩绉垎涓婇檺鍊�',
+    monthly_limit INTEGER COMMENT '姣忔湀绉垎涓婇檺鍊�',
+    yearly_limit INTEGER COMMENT '姣忓勾绉垎涓婇檺鍊�',
+    min_value INTEGER DEFAULT 0 COMMENT '鏈�灏忓��',
+    max_value INTEGER COMMENT '鏈�澶у��',
+    conversion_rate NUMERIC(10,4) DEFAULT 1.0 COMMENT '杞崲姣旂巼',
+    effective_start DATE COMMENT '鐢熸晥寮�濮嬫椂闂�',
+    effective_end DATE COMMENT '鐢熸晥缁撴潫鏃堕棿',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 11. 绉垎娴佹按琛� (points_transaction) - 鏂板瀛楁
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS transaction_type VARCHAR(20) COMMENT '浜ゆ槗绫诲瀷(鑾峰彇/娑堣��/杞崲)';
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS related_id VARCHAR(50) COMMENT '鍏宠仈涓氬姟ID';
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS related_type VARCHAR(50) COMMENT '鍏宠仈涓氬姟绫诲瀷';
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS balance_after INTEGER COMMENT '鍙樺姩鍚庝綑棰�';
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS operator_id BIGINT COMMENT '鎿嶄綔浜篒D';
+ALTER TABLE points_flow ADD COLUMN IF NOT EXISTS operator_name VARCHAR(100) COMMENT '鎿嶄綔浜哄鍚�';
+
+-- 12. 绉垎璐︽埛琛� (points_account) - 鏇存柊鐜版湁琛ㄧ粨鏋�
+ALTER TABLE user_points ADD COLUMN IF NOT EXISTS account_type VARCHAR(20) DEFAULT '涓汉绉垎' COMMENT '璐︽埛绫诲瀷(涓汉绉垎/鍗曚綅绉垎)';
+ALTER TABLE user_points ADD COLUMN IF NOT EXISTS account_status VARCHAR(20) DEFAULT '姝e父' COMMENT '璐︽埛鐘舵��(姝e父/鍐荤粨/娉ㄩ攢)';
+ALTER TABLE user_points ADD COLUMN IF NOT EXISTS last_transaction_time TIMESTAMP COMMENT '鏈�鍚庝氦鏄撴椂闂�';
+
+-- 13. 浜у搧琛� (product) - 鏂板浜у搧鍩虹琛�
+CREATE TABLE product (
+    id BIGSERIAL PRIMARY KEY,
+    product_name VARCHAR(100) NOT NULL COMMENT '浜у搧鍚嶇О',
+    product_code VARCHAR(50) NOT NULL UNIQUE COMMENT '浜у搧缂栫爜',
+    product_type VARCHAR(50) COMMENT '浜у搧绫诲瀷',
+    category VARCHAR(100) COMMENT '浜у搧鍒嗙被',
+    description TEXT COMMENT '浜у搧鎻忚堪',
+    provider_id BIGINT NOT NULL COMMENT '鎻愪緵鑰匢D',
+    provider_name VARCHAR(100) NOT NULL COMMENT '鎻愪緵鑰呭悕绉�',
+    provider_type VARCHAR(20) COMMENT '鎻愪緵鑰呯被鍨�(浼佷笟/涓汉)',
+    status VARCHAR(20) DEFAULT '涓婃灦' CHECK (status IN ('涓婃灦', '涓嬫灦', '瀹℃牳涓�', '宸蹭笅鏋�')) COMMENT '浜у搧鐘舵��',
+    audit_status VARCHAR(20) DEFAULT '寰呭鏍�' CHECK (audit_status IN ('寰呭鏍�', '瀹℃牳閫氳繃', '瀹℃牳椹冲洖')) COMMENT '瀹℃牳鐘舵��',
+    tags TEXT COMMENT '浜у搧鏍囩(JSON鏍煎紡)',
+    cover_image VARCHAR(500) COMMENT '灏侀潰鍥剧墖',
+    demo_url VARCHAR(500) COMMENT '婕旂ず鍦板潃',
+    doc_url VARCHAR(500) COMMENT '鏂囨。鍦板潃',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    created_by BIGINT COMMENT '鍒涘缓浜篒D',
+    updated_by BIGINT COMMENT '鏇存柊浜篒D',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 14. 鐢ㄦ埛琛� (user) - 鏂板鐢ㄦ埛鍩虹琛�
+CREATE TABLE user (
+    id BIGSERIAL PRIMARY KEY,
+    username VARCHAR(100) NOT NULL UNIQUE COMMENT '鐢ㄦ埛鍚�',
+    real_name VARCHAR(100) COMMENT '鐪熷疄濮撳悕',
+    email VARCHAR(100) COMMENT '閭',
+    phone VARCHAR(20) COMMENT '鎵嬫満鍙�',
+    avatar VARCHAR(500) COMMENT '澶村儚',
+    user_type VARCHAR(20) DEFAULT '涓汉鐢ㄦ埛' CHECK (user_type IN ('涓汉鐢ㄦ埛', '鍗曚綅鐢ㄦ埛')) COMMENT '鐢ㄦ埛绫诲瀷',
+    unit_id BIGINT COMMENT '鍗曚綅ID',
+    unit_name VARCHAR(100) COMMENT '鍗曚綅鍚嶇О',
+    status VARCHAR(20) DEFAULT '姝e父' CHECK (status IN ('姝e父', '鍐荤粨', '娉ㄩ攢')) COMMENT '鐢ㄦ埛鐘舵��',
+    last_login_time TIMESTAMP COMMENT '鏈�鍚庣櫥褰曟椂闂�',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 15. 鍗曚綅琛� (unit) - 鏂板鍗曚綅鍩虹琛�
+CREATE TABLE unit (
+    id BIGSERIAL PRIMARY KEY,
+    unit_name VARCHAR(100) NOT NULL COMMENT '鍗曚綅鍚嶇О',
+    unit_code VARCHAR(50) UNIQUE COMMENT '鍗曚綅缂栫爜',
+    unit_type VARCHAR(50) COMMENT '鍗曚綅绫诲瀷',
+    industry VARCHAR(100) COMMENT '鎵�灞炶涓�',
+    address TEXT COMMENT '鍗曚綅鍦板潃',
+    contact_person VARCHAR(100) COMMENT '鑱旂郴浜�',
+    contact_phone VARCHAR(20) COMMENT '鑱旂郴鐢佃瘽',
+    contact_email VARCHAR(100) COMMENT '鑱旂郴閭',
+    business_license VARCHAR(500) COMMENT '钀ヤ笟鎵х収',
+    legal_person VARCHAR(100) COMMENT '娉曚汉浠h〃',
+    registered_capital NUMERIC(15,2) COMMENT '娉ㄥ唽璧勬湰',
+    establishment_date DATE COMMENT '鎴愮珛鏃ユ湡',
+    status VARCHAR(20) DEFAULT '姝e父' CHECK (status IN ('姝e父', '鍐荤粨', '娉ㄩ攢')) COMMENT '鍗曚綅鐘舵��',
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿',
+    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '鏇存柊鏃堕棿',
+    deleted INTEGER DEFAULT 0 COMMENT '閫昏緫鍒犻櫎锛�1-宸插垹闄わ紝0-鏈垹闄�'
+);
+
+-- 鍒涘缓绱㈠紩
+CREATE INDEX idx_product_pricing_product_id ON product_pricing(product_id);
+CREATE INDEX idx_product_pricing_status ON product_pricing(is_active);
+CREATE INDEX idx_shopping_cart_user_id ON shopping_cart(user_id);
+CREATE INDEX idx_shopping_cart_product_id ON shopping_cart(product_id);
+CREATE INDEX idx_order_info_user_id ON order_info(user_id);
+CREATE INDEX idx_order_info_provider_id ON order_info(provider_id);
+CREATE INDEX idx_order_info_status ON order_info(order_status);
+CREATE INDEX idx_order_info_apply_time ON order_info(apply_time);
+CREATE INDEX idx_order_detail_order_id ON order_detail(order_id);
+CREATE INDEX idx_order_attachment_order_id ON order_attachment(order_id);
+CREATE INDEX idx_order_approval_order_id ON order_approval(order_id);
+CREATE INDEX idx_order_approval_approver_id ON order_approval(approver_id);
+CREATE INDEX idx_order_evaluation_order_id ON order_evaluation(order_id);
+CREATE INDEX idx_order_evaluation_evaluator_id ON order_evaluation(evaluator_id);
+CREATE INDEX idx_points_rule_points_id ON points_rule(points_id);
+CREATE INDEX idx_points_rule_detail_rule_id ON points_rule_detail(rule_id);
+CREATE INDEX idx_product_provider_id ON product(provider_id);
+CREATE INDEX idx_product_status ON product(status);
+CREATE INDEX idx_user_unit_id ON user(unit_id);
+CREATE INDEX idx_user_status ON user(status);
+
+-- 璐墿杞﹁〃绱㈠紩
+CREATE INDEX idx_cart_user_unit ON cart(user_id, unit_id, deleted);
+CREATE INDEX idx_cart_pricing ON cart(pricing_id, deleted);
+CREATE INDEX idx_cart_product ON cart(product_id, deleted);
+CREATE INDEX idx_cart_provider ON cart(provider_id, deleted);
+CREATE INDEX idx_cart_add_time ON cart(add_time, deleted);
+
+-- 娣诲姞澶栭敭绾︽潫
+ALTER TABLE product_pricing ADD CONSTRAINT fk_product_pricing_product_id FOREIGN KEY (product_id) REFERENCES product(id);
+ALTER TABLE shopping_cart ADD CONSTRAINT fk_shopping_cart_user_id FOREIGN KEY (user_id) REFERENCES user(id);
+ALTER TABLE shopping_cart ADD CONSTRAINT fk_shopping_cart_product_id FOREIGN KEY (product_id) REFERENCES product(id);
+ALTER TABLE order_info ADD CONSTRAINT fk_order_info_product_id FOREIGN KEY (product_id) REFERENCES product(id);
+ALTER TABLE order_info ADD CONSTRAINT fk_order_info_user_id FOREIGN KEY (user_id) REFERENCES user(id);
+ALTER TABLE order_info ADD CONSTRAINT fk_order_info_provider_id FOREIGN KEY (provider_id) REFERENCES user(id);
+ALTER TABLE order_detail ADD CONSTRAINT fk_order_detail_order_id FOREIGN KEY (order_id) REFERENCES order_info(order_id);
+ALTER TABLE order_detail ADD CONSTRAINT fk_order_detail_pricing_id FOREIGN KEY (pricing_id) REFERENCES product_pricing(id);
+ALTER TABLE order_attachment ADD CONSTRAINT fk_order_attachment_order_id FOREIGN KEY (order_id) REFERENCES order_info(order_id);
+ALTER TABLE order_approval ADD CONSTRAINT fk_order_approval_order_id FOREIGN KEY (order_id) REFERENCES order_info(order_id);
+ALTER TABLE order_evaluation ADD CONSTRAINT fk_order_evaluation_order_id FOREIGN KEY (order_id) REFERENCES order_info(order_id);
+ALTER TABLE points_rule ADD CONSTRAINT fk_points_rule_points_id FOREIGN KEY (points_id) REFERENCES points(id);
+ALTER TABLE points_rule_detail ADD CONSTRAINT fk_points_rule_detail_rule_id FOREIGN KEY (points_rule_id) REFERENCES points_rule(id);
+ALTER TABLE points_rule_detail ADD CONSTRAINT fk_points_rule_detail_points_id FOREIGN KEY (points_id) REFERENCES points(id);
+ALTER TABLE product ADD CONSTRAINT fk_product_provider_id FOREIGN KEY (provider_id) REFERENCES user(id);
+ALTER TABLE user ADD CONSTRAINT fk_user_unit_id FOREIGN KEY (unit_id) REFERENCES unit(id);
+
+-- 娣诲姞琛ㄦ敞閲�
+COMMENT ON TABLE product_pricing IS '浜у搧瀹氫环琛�';
+COMMENT ON TABLE shopping_cart IS '璐墿杞﹁〃';
+COMMENT ON TABLE order_info IS '璁㈠崟琛�';
+COMMENT ON TABLE order_detail IS '璁㈠崟璇︽儏琛�';
+COMMENT ON TABLE order_attachment IS '璁㈠崟闄勪欢琛�';
+COMMENT ON TABLE order_approval IS '璁㈠崟瀹℃牳琛�';
+COMMENT ON TABLE order_evaluation IS '璁㈠崟璇勪环琛�';
+COMMENT ON TABLE points IS '绉垎琛�';
+COMMENT ON TABLE points_rule_detail IS '绉垎瑙勫垯璇︽儏琛�';
+COMMENT ON TABLE product IS '浜у搧琛�';
+COMMENT ON TABLE user IS '鐢ㄦ埛琛�';
+COMMENT ON TABLE unit IS '鍗曚綅琛�';
+
+-- 鎻掑叆鍒濆鏁版嵁
+INSERT INTO points (points_name, points_code, points_type, effective_start, modifier_id, modifier_name, version, description, status) VALUES
+('鏁板瓧鍖栨爣鏉嗕釜浜虹Н鍒�', 'BENCHMARK_PERSONAL', '涓汉绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栨爣鏉嗕釜浜虹Н鍒嗕綋绯�', '鍚敤'),
+('鏁板瓧鍖栨爣鏉嗗崟浣嶇Н鍒�', 'BENCHMARK_UNIT', '鍗曚綅绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栨爣鏉嗗崟浣嶇Н鍒嗕綋绯�', '鍚敤'),
+('鏁板瓧鍖栫煡璇嗕釜浜虹Н鍒�', 'KNOWLEDGE_PERSONAL', '涓汉绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栫煡璇嗕釜浜虹Н鍒嗕綋绯�', '鍚敤'),
+('鏁板瓧鍖栫煡璇嗗崟浣嶇Н鍒�', 'KNOWLEDGE_UNIT', '鍗曚綅绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栫煡璇嗗崟浣嶇Н鍒嗕綋绯�', '鍚敤'),
+('鏁板瓧鍖栦骇鍝佷釜浜虹Н鍒�', 'PRODUCT_PERSONAL', '涓汉绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栦骇鍝佷釜浜虹Н鍒嗕綋绯�', '鍚敤'),
+('鏁板瓧鍖栦骇鍝佸崟浣嶇Н鍒�', 'PRODUCT_UNIT', '鍗曚綅绉垎', '2024-01-01', 1, '绯荤粺绠$悊鍛�', '1.0.0', '鏁板瓧鍖栦骇鍝佸崟浣嶇Н鍒嗕綋绯�', '鍚敤');
+
+-- 鎻掑叆娴嬭瘯鍗曚綅鏁版嵁
+INSERT INTO unit (unit_name, unit_code, unit_type, industry, status) VALUES
+('娴嬭瘯浼佷笟', 'TEST_ENTERPRISE', '浼佷笟', '淇℃伅鎶�鏈�', '姝e父'),
+('娴嬭瘯鍗曚綅', 'TEST_UNIT', '浜嬩笟鍗曚綅', '鏁欒偛', '姝e父');
+
+-- 鎻掑叆娴嬭瘯鐢ㄦ埛鏁版嵁
+INSERT INTO user (username, real_name, user_type, unit_id, status) VALUES
+('admin', '绯荤粺绠$悊鍛�', '涓汉鐢ㄦ埛', NULL, '姝e父'),
+('test_user', '娴嬭瘯鐢ㄦ埛', '涓汉鐢ㄦ埛', 1, '姝e父'),
+('test_provider', '娴嬭瘯鎻愪緵鑰�', '鍗曚綅鐢ㄦ埛', 1, '姝e父');
+
+-- 鎻掑叆娴嬭瘯浜у搧鏁版嵁
+INSERT INTO product (product_name, product_code, product_type, category, description, provider_id, provider_name, status, audit_status) VALUES
+('娴嬭瘯浜у搧1', 'TEST_PRODUCT_001', '杞欢浜у搧', '浼佷笟绠$悊', '杩欐槸涓�涓祴璇曚骇鍝�', 3, '娴嬭瘯鎻愪緵鑰�', '涓婃灦', '瀹℃牳閫氳繃'),
+('娴嬭瘯浜у搧2', 'TEST_PRODUCT_002', '鏈嶅姟浜у搧', '鎶�鏈湇鍔�', '杩欐槸鍙︿竴涓祴璇曚骇鍝�', 3, '娴嬭瘯鎻愪緵鑰�', '涓婃灦', '瀹℃牳閫氳繃');
+
+-- 鎻掑叆娴嬭瘯浜у搧瀹氫环鏁版嵁
+INSERT INTO product_pricing (suite_name, sales_form, customer_type, price_type, price_unit, price, product_id, product_name, provider_id, provider_name, is_active) VALUES
+('鍩虹鐗�', '涔版柇', '浼佷笟', '绉垎', '濂�', 1000, 1, '娴嬭瘯浜у搧1', 3, '娴嬭瘯鎻愪緵鑰�', true),
+('涓撲笟鐗�', '绉熻祦', '浼佷笟', '绉垎', '濂�/骞�', 500, 1, '娴嬭瘯浜у搧1', 3, '娴嬭瘯鎻愪緵鑰�', true),
+('浼佷笟鐗�', '涔版柇', '浼佷笟', '璐у竵', '濂�', 10000, 2, '娴嬭瘯浜у搧2', 3, '娴嬭瘯鎻愪緵鑰�', true);
diff --git "a/src/main/resources/sql/\346\225\260\346\215\256\345\272\223\350\241\250\350\257\264\346\230\216.md" "b/src/main/resources/sql/\346\225\260\346\215\256\345\272\223\350\241\250\350\257\264\346\230\216.md"
new file mode 100644
index 0000000..d86f74a
--- /dev/null
+++ "b/src/main/resources/sql/\346\225\260\346\215\256\345\272\223\350\241\250\350\257\264\346\230\216.md"
@@ -0,0 +1,142 @@
+琛ㄧ粨鏋勬瑙�
+鏍规嵁闇�姹傛枃妗o紝鎴戜滑闇�瑕佸垱寤轰互涓嬫暟鎹簱琛ㄦ潵鏀寔浜ゆ槗妯″潡锛�
+
+琛ㄥ悕	鎻忚堪	涓昏鍔熻兘
+浜у搧瀹氫环琛�	浜у搧瀹氫环淇℃伅	瀛樺偍浜у搧瀹氫环鏂规鍙婇攢鍞舰寮�
+璐墿杞�	鐢ㄦ埛璐墿杞︿俊鎭�	瀛樺偍鐢ㄦ埛寰呰喘涔扮殑鍟嗗搧淇℃伅
+璁㈠崟琛�	璁㈠崟涓讳俊鎭�	瀛樺偍璁㈠崟鍩烘湰淇℃伅鍙婄姸鎬�
+璁㈠崟璇︽儏琛�	璁㈠崟璇︾粏鏉$洰淇℃伅	瀛樺偍璁㈠崟涓瘡涓骇鍝佺殑璇︾粏淇℃伅
+璁㈠崟闄勪欢琛�	璁㈠崟鐩稿叧闄勪欢淇℃伅	瀛樺偍璁㈠崟瀹℃壒杩囩▼涓殑鐩稿叧鏂囦欢
+璁㈠崟瀹℃牳琛�	璁㈠崟瀹℃牳璁板綍	瀛樺偍璁㈠崟瀹℃壒娴佺▼涓殑瀹℃牳鎰忚
+璁㈠崟璇勪环琛�	璁㈠崟璇勪环淇℃伅	瀛樺偍鐢ㄦ埛瀵瑰凡瀹屾垚璁㈠崟鐨勮瘎浠�
+绉垎琛�	绉垎浣撶郴鍩烘湰淇℃伅	瀛樺偍绉垎浣撶郴鐨勫熀鏈厤缃�
+绉垎瑙勫垯琛�	绉垎瑙勫垯瀹氫箟	瀛樺偍绉垎鑾峰彇鍜屾秷鑰楃殑瑙勫垯
+绉垎瑙勫垯璇︽儏琛�	绉垎瑙勫垯璇︾粏鍙傛暟	瀛樺偍绉垎瑙勫垯鐨勫叿浣撳弬鏁�
+绉垎娴佹按琛�	绉垎鍙樺姩璁板綍	璁板綍鐢ㄦ埛绉垎鐨勫彉鍔ㄥ巻鍙�
+绉垎璐︽埛琛�	鐢ㄦ埛绉垎璐︽埛淇℃伅	瀛樺偍鐢ㄦ埛褰撳墠鐨勭Н鍒嗙姸鎬�
+璇︾粏琛ㄧ粨鏋勮璁�
+1. 浜у搧瀹氫环琛� (product_pricing)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+suite_name	VARCHAR(100)	NOT NULL	浜у搧濂椾欢鍚嶇О
+sales_form	VARCHAR(20)	CHECK (values)	閿�鍞舰寮�(涔版柇/绉熻祦/绉佹湁澧炲寘閲�/鍏湁澧炲寘閲�/OTA鏈嶅姟/璧勬簮鍖�/涓汉)
+customer_type	VARCHAR(10)	CHECK (values)	瀹㈡埛瀵硅薄(浼佷笟/涓汉/椤圭洰閮�)
+account_limit	VARCHAR(20)		璐︽埛鏁伴噺
+concurrent_nodes	VARCHAR(20)		骞跺彂鑺傜偣鏁�
+price_type	VARCHAR(10)	CHECK (values)	浠锋牸璁剧疆(绉垎/鍗忚/璐у竵/鍏嶈垂)
+price_unit	VARCHAR(20)	CHECK (values)	浠锋牸鍗曚綅(濂�/濂�/骞�/骞�)
+price	NUMERIC(15,2)	NOT NULL	浠锋牸鍊�
+is_active	BOOLEAN	DEFAULT TRUE	鍚敤鐘舵��
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+updated_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鏇存柊鏃堕棿
+product_id	INT	NOT NULL	鍏宠仈浜у搧ID
+2. 璐墿杞� (shopping_cart)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+user_id	INT	NOT NULL	鐢ㄦ埛ID
+suite_name	VARCHAR(100)	NOT NULL	浜у搧濂椾欢鍚嶇О
+sales_form	VARCHAR(20)	CHECK (values)	閿�鍞舰寮�(涔版柇/绉熻祦/绉佹湁澧炲寘閲�/鍏湁澧炲寘閲�/OTA鏈嶅姟/璧勬簮鍖�/涓汉)
+customer_type	VARCHAR(10)	CHECK (values)	瀹㈡埛瀵硅薄(浼佷笟/涓汉/椤圭洰閮�)
+account_limit	VARCHAR(20)	DEFAULT '涓嶉檺'	璐︽埛鏁伴噺
+concurrent_nodes	VARCHAR(20)	DEFAULT '涓嶉檺'	骞跺彂鑺傜偣鏁�
+price_type	VARCHAR(10)	CHECK (values)	浠锋牸绫诲瀷(绉垎/鍗忚/璐у竵/鍏嶈垂)
+price_unit	VARCHAR(20)	CHECK (values)	浠锋牸鍗曚綅(濂�/濂�/骞�/骞�)
+unit_price	NUMERIC(15,2)	NOT NULL	鍗曚环
+quantity	INT	NOT NULL	鏁伴噺
+duration	INT		鏈熼檺(骞�)
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+updated_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鏇存柊鏃堕棿
+3. 璁㈠崟琛� (order_info)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+order_id	VARCHAR(50)	PRIMARY KEY	璁㈠崟缂栧彿
+product_id	INT	NOT NULL	浜у搧ID
+user_id	INT	NOT NULL	鐢ㄦ埛ID
+product_name	VARCHAR(100)	NOT NULL	浜у搧鍚嶇О
+provider_name	VARCHAR(100)	NOT NULL	浜у搧鎻愪緵鑰呭悕绉�
+provider_id	INT	NOT NULL	鎻愪緵鑰匢D
+apply_time	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鐢宠鏃堕棿
+order_status	VARCHAR(20)	CHECK (values)	璁㈠崟鐘舵��(寰呭鎵�/寰呭鎵规巿鏉�/寰呮巿鏉�/寰呬笂浼犳枃浠�/寰呬氦鏄撶‘璁�/宸插畬鎴�/宸插彇娑�)
+total_amount	NUMERIC(15,2)	NOT NULL	璁㈠崟鎬婚噾棰�
+workflow_id	VARCHAR(50)		宸ヤ綔娴両D
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+4. 璁㈠崟璇︽儏琛� (order_detail)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+order_id	VARCHAR(50)	FOREIGN KEY	鍏宠仈璁㈠崟ID
+pricing_id	INT	FOREIGN KEY	鍏宠仈浜у搧瀹氫环ID
+unit_price	NUMERIC(15,2)	NOT NULL	鍗曚环
+quantity	INT	NOT NULL	鏁伴噺
+duration	INT		骞撮檺
+provider_id	INT	NOT NULL	浜у搧鎻愪緵鑰匢D
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+remarks	TEXT		澶囨敞
+5. 璁㈠崟闄勪欢琛� (order_attachment)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+order_id	VARCHAR(50)	FOREIGN KEY	鍏宠仈璁㈠崟ID
+file_name	VARCHAR(255)	NOT NULL	闄勪欢鍚嶇О
+file_type	VARCHAR(50)	NOT NULL	闄勪欢绫诲瀷
+file_size	BIGINT	NOT NULL	闄勪欢澶у皬(瀛楄妭)
+file_url	VARCHAR(255)	NOT NULL	闄勪欢鍦板潃
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+6. 璁㈠崟瀹℃牳琛� (order_approval)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+order_id	VARCHAR(50)	FOREIGN KEY	鍏宠仈璁㈠崟ID
+approval_opinion	TEXT	NOT NULL	瀹℃牳鎰忚
+approver	VARCHAR(100)	NOT NULL	瀹℃牳浜�
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+7. 璁㈠崟璇勪环琛� (order_evaluation)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+order_id	VARCHAR(50)	FOREIGN KEY	鍏宠仈璁㈠崟ID
+content	TEXT	NOT NULL	璇勪环鍐呭
+rating	INT	CHECK (1-5)	璇勫垎(1-5)
+evaluator	VARCHAR(100)	NOT NULL	璇勪环浜�
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+8. 绉垎琛� (points)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+points_name	VARCHAR(100)	NOT NULL	绉垎鍚嶇О
+effective_start	DATE	NOT NULL	鐢熸晥寮�濮嬫椂闂�
+modifier	VARCHAR(100)	NOT NULL	淇敼浜�
+version	VARCHAR(20)	NOT NULL	鐗堟湰鍙�
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+9. 绉垎瑙勫垯琛� (points_rule)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+points_id	INT	FOREIGN KEY	鍏宠仈绉垎ID
+rule_type	VARCHAR(10)	CHECK (values)	绉垎瑙勫垯绫诲瀷(鑾峰彇/娑堣��)
+category	VARCHAR(50)	CHECK (values)	绉垎绫诲埆(璧勬簮璐$尞/璧勬簮浼犳挱/璧勬簮浜ゆ槗/浜ゆ祦绀惧尯浜掑姩)
+rule_name	VARCHAR(100)	NOT NULL	瑙勫垯鍚嶇О
+description	TEXT		瑙勫垯鎻忚堪
+status	VARCHAR(10)	CHECK (values)	鐘舵��(鍚敤/绂佺敤)
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
+updated_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鏇存柊鏃堕棿
+is_deleted	BOOLEAN	DEFAULT FALSE	閫昏緫鍒犻櫎鏍囧織
+10. 绉垎瑙勫垯璇︽儏琛� (points_rule_detail)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+rule_id	INT	FOREIGN KEY	鍏宠仈绉垎瑙勫垯ID
+points_id	INT	FOREIGN KEY	鍏宠仈绉垎ID
+points_value	INT	NOT NULL	绉垎鍊�
+daily_limit	INT		姣忔棩绉垎涓婇檺鍊�
+11. 绉垎娴佹按琛� (points_transaction)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+data_category	VARCHAR(50)	CHECK (values)	鏁版嵁绫荤洰(鐢ㄦ埛鍙備笌/鍏朵粬)
+transaction_name	VARCHAR(100)	NOT NULL	鍚嶇О
+transaction_time	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鏃堕棿
+points_change	INT	NOT NULL	绉垎鍙樺姩鍊�
+rule_type	VARCHAR(10)	CHECK (values)	绉垎瑙勫垯绫诲瀷(鑾峰彇/娑堣��)
+user_id	INT	NOT NULL	鐢ㄦ埛ID
+enterprise_id	INT		浼佷笟ID
+user_type	VARCHAR(10)	CHECK (values)	鐢ㄦ埛绫诲瀷(鍗曚綅鐢ㄦ埛/涓汉鐢ㄦ埛)
+12. 绉垎璐︽埛琛� (points_account)
+瀛楁鍚�	鏁版嵁绫诲瀷	绾︽潫	璇存槑
+id	SERIAL	PRIMARY KEY	涓婚敭ID
+user_id	INT	NOT NULL UNIQUE	鐢ㄦ埛ID
+points_balance	INT	DEFAULT 0	绉垎浣欓
+total_earned	INT	DEFAULT 0	绱鑾峰彇绉垎
+total_spent	INT	DEFAULT 0	绱娑堣�楃Н鍒�
+created_at	TIMESTAMP	DEFAULT CURRENT_TIMESTAMP	鍒涘缓鏃堕棿
\ No newline at end of file

--
Gitblit v1.8.0