jiapu пре 3 месеци
родитељ
комит
b25ce8c4ec

+ 1 - 1
cfc-backend/AGENTS.md

@@ -184,7 +184,7 @@ mvn clean compile   # 编译验证通过即可
 
 ### 规范要点
 
-- **迁移编号**:按现c有顺序递增(当前最大编号 `迁移N`,在文件末尾搜索 `// 迁移` 确认最新编号)
+- **迁移编号**:按现有顺序递增(当前最大编号 `迁移N`,在文件末尾搜索 `// 迁移` 确认最新编号)
 - **注释格式**:`// 迁移N: 表名 操作说明(原因/需求编号)`
 - **日志**:每个成功的 ALTER/CREATE 后加 `log.info()`,失败统一用空 catch 或 `// 忽略`
 - **幂等性**:所有迁移必须可重复执行而不报错(try-catch 包裹 + 列存在检查)

+ 82 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/AssessmentAppointmentService.java

@@ -4,12 +4,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.etotem.cfc.entity.AssessmentAppointment;
 import com.etotem.cfc.entity.AssessmentOrder;
+import com.etotem.cfc.entity.GuidePackage;
+import com.etotem.cfc.entity.User;
 import com.etotem.cfc.mapper.AssessmentAppointmentMapper;
+import com.etotem.cfc.mapper.AssessmentOrderMapper;
+import com.etotem.cfc.mapper.GuidePackageMapper;
+import com.etotem.cfc.mapper.UserMapper;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
+import java.util.Random;
 
 import lombok.extern.slf4j.Slf4j;
 
@@ -20,6 +27,15 @@ public class AssessmentAppointmentService extends ServiceImpl<AssessmentAppointm
     @Resource
     private AssessmentAppointmentMapper assessmentAppointmentMapper;
 
+    @Resource
+    private AssessmentOrderMapper assessmentOrderMapper;
+
+    @Resource
+    private GuidePackageMapper guidePackageMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
     @Resource
     private EnergyService energyService;
 
@@ -43,6 +59,11 @@ public class AssessmentAppointmentService extends ServiceImpl<AssessmentAppointm
         appointment.setUpdatedAt(new Date());
         this.save(appointment);
 
+        // 自动创建关联订单(如果有 packageId)
+        if (appointment.getPackageId() != null) {
+            createOrderForAppointment(appointment);
+        }
+
         // 测评预约能量发放
         try {
             energyService.awardEnergy(childId, "appointment", appointment.getId(), 10,
@@ -54,6 +75,47 @@ public class AssessmentAppointmentService extends ServiceImpl<AssessmentAppointm
         return appointment;
     }
 
+    /**
+     * 为预约自动创建订单
+     */
+    private void createOrderForAppointment(AssessmentAppointment appointment) {
+        try {
+            // 查询方案信息
+            GuidePackage pkg = guidePackageMapper.selectById(appointment.getPackageId());
+            String packageName = pkg != null ? pkg.getName() : null;
+            int price = pkg != null && pkg.getPrice() != null ? pkg.getPrice() : 0;
+
+            // 查询规划师昵称
+            String guideName = null;
+            Long guideId = appointment.getGuideId() != null ? appointment.getGuideId() : appointment.getTeacherId();
+            if (guideId != null) {
+                User guide = userMapper.selectById(guideId);
+                if (guide != null) guideName = guide.getNickname();
+            }
+
+            AssessmentOrder order = new AssessmentOrder();
+            order.setOrderNo("A" + System.currentTimeMillis() + String.format("%04d", new Random().nextInt(10000)));
+            order.setFamilyId(appointment.getFamilyId());
+            order.setUserId(appointment.getUserId());
+            order.setChildId(appointment.getChildId());
+            order.setGuideId(guideId);
+            order.setPackageId(appointment.getPackageId());
+            order.setGuideName(guideName);
+            order.setPackageName(packageName);
+            order.setTotalPrice((long) price);
+            order.setDiscountAmount(0L);
+            order.setActualPrice((long) price);
+            order.setAppointmentId(appointment.getId());
+            order.setStatus("pending");
+            order.setCreatedAt(new Date());
+            order.setUpdatedAt(new Date());
+            assessmentOrderMapper.insert(order);
+            log.info("预约自动创建订单成功: appointmentId={}, orderNo={}", appointment.getId(), order.getOrderNo());
+        } catch (Exception e) {
+            log.warn("预约自动创建订单失败: appointmentId={}, error={}", appointment.getId(), e.getMessage());
+        }
+    }
+
     public boolean confirmAppointment(Long id, Long teacherId) {
         AssessmentAppointment appointment = assessmentAppointmentMapper.selectById(id);
         if (appointment == null) return false;
@@ -88,7 +150,26 @@ public class AssessmentAppointmentService extends ServiceImpl<AssessmentAppointm
         if (appointment == null) return false;
         appointment.setStatus(3); // cancelled
         appointment.setUpdatedAt(new Date());
-        return assessmentAppointmentMapper.updateById(appointment) > 0;
+        boolean updated = assessmentAppointmentMapper.updateById(appointment) > 0;
+
+        // 同步取消关联订单
+        if (updated) {
+            try {
+                LambdaQueryWrapper<AssessmentOrder> orderWrapper = new LambdaQueryWrapper<>();
+                orderWrapper.eq(AssessmentOrder::getAppointmentId, id);
+                AssessmentOrder order = assessmentOrderMapper.selectOne(orderWrapper);
+                if (order != null && "pending".equals(order.getStatus())) {
+                    order.setStatus("cancelled");
+                    order.setUpdatedAt(new Date());
+                    assessmentOrderMapper.updateById(order);
+                    log.info("预约取消同步取消订单: appointmentId={}, orderNo={}", id, order.getOrderNo());
+                }
+            } catch (Exception e) {
+                log.warn("预约取消同步取消订单失败: appointmentId={}, error={}", id, e.getMessage());
+            }
+        }
+
+        return updated;
     }
 
     public List<AssessmentAppointment> getByUserId(Long userId) {

+ 26 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/AssessmentOrderService.java

@@ -5,7 +5,9 @@ import com.etotem.cfc.service.api.AssessmentOrderServiceInterface;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.etotem.cfc.entity.AssessmentOrder;
+import com.etotem.cfc.entity.AssessmentAppointment;
 import com.etotem.cfc.mapper.AssessmentOrderMapper;
+import com.etotem.cfc.mapper.AssessmentAppointmentMapper;
 import com.etotem.cfc.service.CommissionService;
 import org.springframework.stereotype.Service;
 
@@ -15,12 +17,18 @@ import java.util.Date;
 import java.util.List;
 import java.util.Random;
 
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 @Service
 public class AssessmentOrderService extends ServiceImpl<AssessmentOrderMapper, AssessmentOrder> {
 
     @Resource
     private AssessmentOrderMapper assessmentOrderMapper;
 
+    @Resource
+    private AssessmentAppointmentMapper assessmentAppointmentMapper;
+
     @Resource
     private CommissionService commissionService;
 
@@ -147,6 +155,23 @@ public class AssessmentOrderService extends ServiceImpl<AssessmentOrderMapper, A
         order.setPayTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
         order.setPayType(payType);
         order.setUpdatedAt(new Date());
-        return this.updateById(order);
+        boolean updated = this.updateById(order);
+
+        // 支付成功后自动确认关联预约
+        if (updated && order.getAppointmentId() != null) {
+            try {
+                AssessmentAppointment appointment = assessmentAppointmentMapper.selectById(order.getAppointmentId());
+                if (appointment != null && appointment.getStatus() != null && appointment.getStatus() == 0) {
+                    appointment.setStatus(1); // 待确认 → 已确认
+                    appointment.setUpdatedAt(new Date());
+                    assessmentAppointmentMapper.updateById(appointment);
+                    log.info("订单支付成功自动确认预约: orderNo={}, appointmentId={}", orderNo, order.getAppointmentId());
+                }
+            } catch (Exception e) {
+                log.warn("订单支付后确认预约失败: orderNo={}, error={}", orderNo, e.getMessage());
+            }
+        }
+
+        return updated;
     }
 }