新增人生轨迹模块代码
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
package com.emotion.controller;
|
||||||
|
|
||||||
|
import com.emotion.common.PageResult;
|
||||||
|
import com.emotion.common.Result;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileCreateRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfilePageRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileUpdateRequest;
|
||||||
|
import com.emotion.dto.response.userprofile.UserProfileResponse;
|
||||||
|
import com.emotion.service.UserProfileService;
|
||||||
|
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 huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user-profile")
|
||||||
|
public class UserProfileController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserProfileService userProfileService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增档案
|
||||||
|
*/
|
||||||
|
@PostMapping("/create")
|
||||||
|
public Result<UserProfileResponse> create(@Valid @RequestBody UserProfileCreateRequest request) {
|
||||||
|
UserProfileResponse response = userProfileService.createProfile(request);
|
||||||
|
return Result.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除档案
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
public Result<Void> delete(@RequestParam String id) {
|
||||||
|
boolean success = userProfileService.deleteProfile(id);
|
||||||
|
if (success) {
|
||||||
|
return Result.success();
|
||||||
|
} else {
|
||||||
|
return Result.error("删除失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改档案
|
||||||
|
*/
|
||||||
|
@PutMapping("/update")
|
||||||
|
public Result<UserProfileResponse> update(@Valid @RequestBody UserProfileUpdateRequest request) {
|
||||||
|
UserProfileResponse response = userProfileService.updateProfile(request);
|
||||||
|
return Result.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/detail")
|
||||||
|
public Result<UserProfileResponse> getById(@RequestParam String id) {
|
||||||
|
UserProfileResponse response = userProfileService.getProfileById(id);
|
||||||
|
if (response == null) {
|
||||||
|
return Result.notFound("档案不存在");
|
||||||
|
}
|
||||||
|
return Result.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户的档案
|
||||||
|
*/
|
||||||
|
@GetMapping("/me")
|
||||||
|
public Result<UserProfileResponse> getCurrentProfile() {
|
||||||
|
UserProfileResponse response = userProfileService.getCurrentUserProfile();
|
||||||
|
// 如果不存在,返回null data,不报错
|
||||||
|
return Result.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
*/
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<PageResult<UserProfileResponse>> getPage(@Validated UserProfilePageRequest request) {
|
||||||
|
PageResult<UserProfileResponse> pageResult = userProfileService.getProfilePage(request);
|
||||||
|
return Result.success(pageResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表查询
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<UserProfileResponse>> getList(@Validated UserProfilePageRequest request) {
|
||||||
|
List<UserProfileResponse> list = userProfileService.getProfileList(request);
|
||||||
|
return Result.success(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
package com.emotion.dto.request.userprofile;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案创建请求对象
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UserProfileCreateRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "昵称不能为空")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*/
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星座
|
||||||
|
*/
|
||||||
|
private String zodiac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBTI人格类型
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "MBTI人格类型不能为空")
|
||||||
|
private String mbti;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兴趣爱好 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String hobbies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历日期
|
||||||
|
*/
|
||||||
|
private LocalDate childhoodDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历描述
|
||||||
|
*/
|
||||||
|
private String childhoodContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻日期
|
||||||
|
*/
|
||||||
|
private LocalDate peakDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻描述
|
||||||
|
*/
|
||||||
|
private String peakContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期日期
|
||||||
|
*/
|
||||||
|
private LocalDate valleyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期描述
|
||||||
|
*/
|
||||||
|
private String valleyContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未来期许
|
||||||
|
*/
|
||||||
|
private String futureVision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成的剧本列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String scripts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择的路径列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String paths;
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package com.emotion.dto.request.userprofile;
|
||||||
|
|
||||||
|
import com.emotion.dto.request.PageRequest;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案分页查询请求对象
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class UserProfilePageRequest extends PageRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBTI人格类型
|
||||||
|
*/
|
||||||
|
private String mbti;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
package com.emotion.dto.request.userprofile;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案更新请求对象
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UserProfileUpdateRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "ID不能为空")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*/
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星座
|
||||||
|
*/
|
||||||
|
private String zodiac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBTI人格类型
|
||||||
|
*/
|
||||||
|
private String mbti;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兴趣爱好 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String hobbies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历日期
|
||||||
|
*/
|
||||||
|
private LocalDate childhoodDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历描述
|
||||||
|
*/
|
||||||
|
private String childhoodContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻日期
|
||||||
|
*/
|
||||||
|
private LocalDate peakDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻描述
|
||||||
|
*/
|
||||||
|
private String peakContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期日期
|
||||||
|
*/
|
||||||
|
private LocalDate valleyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期描述
|
||||||
|
*/
|
||||||
|
private String valleyContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未来期许
|
||||||
|
*/
|
||||||
|
private String futureVision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成的剧本列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String scripts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择的路径列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态: 0-禁用, 1-正常
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
package com.emotion.dto.response.userprofile;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案响应对象
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserProfileResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*/
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星座
|
||||||
|
*/
|
||||||
|
private String zodiac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBTI人格类型
|
||||||
|
*/
|
||||||
|
private String mbti;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兴趣爱好 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String hobbies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历日期
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate childhoodDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历描述
|
||||||
|
*/
|
||||||
|
private String childhoodContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻日期
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate peakDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻描述
|
||||||
|
*/
|
||||||
|
private String peakContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期日期
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private LocalDate valleyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期描述
|
||||||
|
*/
|
||||||
|
private String valleyContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未来期许
|
||||||
|
*/
|
||||||
|
private String futureVision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成的剧本列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String scripts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择的路径列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
private String paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态: 0-禁用, 1-正常
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package com.emotion.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.emotion.common.BaseEntity;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案实体类
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@TableName("t_user_profile")
|
||||||
|
public class UserProfile extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID (关联t_user.id)
|
||||||
|
*/
|
||||||
|
@TableField("user_id")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昵称
|
||||||
|
*/
|
||||||
|
@TableField("nickname")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别: male, female, secret
|
||||||
|
*/
|
||||||
|
@TableField("gender")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 星座
|
||||||
|
*/
|
||||||
|
@TableField("zodiac")
|
||||||
|
private String zodiac;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBTI人格类型
|
||||||
|
*/
|
||||||
|
@TableField("mbti")
|
||||||
|
private String mbti;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兴趣爱好 (JSON字符串)
|
||||||
|
*/
|
||||||
|
@TableField("hobbies")
|
||||||
|
private String hobbies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历日期
|
||||||
|
*/
|
||||||
|
@TableField("childhood_date")
|
||||||
|
private LocalDate childhoodDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 童年经历描述
|
||||||
|
*/
|
||||||
|
@TableField("childhood_content")
|
||||||
|
private String childhoodContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻日期
|
||||||
|
*/
|
||||||
|
@TableField("peak_date")
|
||||||
|
private LocalDate peakDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高光时刻描述
|
||||||
|
*/
|
||||||
|
@TableField("peak_content")
|
||||||
|
private String peakContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期日期
|
||||||
|
*/
|
||||||
|
@TableField("valley_date")
|
||||||
|
private LocalDate valleyDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 低谷时期描述
|
||||||
|
*/
|
||||||
|
@TableField("valley_content")
|
||||||
|
private String valleyContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未来期许
|
||||||
|
*/
|
||||||
|
@TableField("future_vision")
|
||||||
|
private String futureVision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成的剧本列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
@TableField("scripts")
|
||||||
|
private String scripts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择的路径列表 (JSON字符串)
|
||||||
|
*/
|
||||||
|
@TableField("paths")
|
||||||
|
private String paths;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态: 0-禁用, 1-正常
|
||||||
|
*/
|
||||||
|
@TableField("status")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.emotion.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.emotion.entity.UserProfile;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案 Mapper 接口
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface UserProfileMapper extends BaseMapper<UserProfile> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.emotion.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.emotion.common.PageResult;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileCreateRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfilePageRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileUpdateRequest;
|
||||||
|
import com.emotion.dto.response.userprofile.UserProfileResponse;
|
||||||
|
import com.emotion.entity.UserProfile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案服务接口
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
public interface UserProfileService extends IService<UserProfile> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建用户档案
|
||||||
|
*
|
||||||
|
* @param request 创建请求
|
||||||
|
* @return 用户档案响应对象
|
||||||
|
*/
|
||||||
|
UserProfileResponse createProfile(UserProfileCreateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户档案
|
||||||
|
*
|
||||||
|
* @param request 更新请求
|
||||||
|
* @return 用户档案响应对象
|
||||||
|
*/
|
||||||
|
UserProfileResponse updateProfile(UserProfileUpdateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户档案详情
|
||||||
|
*
|
||||||
|
* @param id 档案ID
|
||||||
|
* @return 用户档案响应对象
|
||||||
|
*/
|
||||||
|
UserProfileResponse getProfileById(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户档案详情
|
||||||
|
*
|
||||||
|
* @return 用户档案响应对象
|
||||||
|
*/
|
||||||
|
UserProfileResponse getCurrentUserProfile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询用户档案
|
||||||
|
*
|
||||||
|
* @param request 分页请求
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
PageResult<UserProfileResponse> getProfilePage(UserProfilePageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表查询用户档案
|
||||||
|
*
|
||||||
|
* @param request 查询请求
|
||||||
|
* @return 列表结果
|
||||||
|
*/
|
||||||
|
List<UserProfileResponse> getProfileList(UserProfilePageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除用户档案
|
||||||
|
*
|
||||||
|
* @param id 档案ID
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
boolean deleteProfile(String id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
package com.emotion.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
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.emotion.common.PageResult;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileCreateRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfilePageRequest;
|
||||||
|
import com.emotion.dto.request.userprofile.UserProfileUpdateRequest;
|
||||||
|
import com.emotion.dto.response.userprofile.UserProfileResponse;
|
||||||
|
import com.emotion.entity.User;
|
||||||
|
import com.emotion.entity.UserProfile;
|
||||||
|
import com.emotion.mapper.UserProfileMapper;
|
||||||
|
import com.emotion.service.UserProfileService;
|
||||||
|
import com.emotion.service.UserService;
|
||||||
|
import com.emotion.util.UserContextHolder;
|
||||||
|
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.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户档案服务实现类
|
||||||
|
*
|
||||||
|
* @author huazhongmin
|
||||||
|
* @date 2025-12-21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class UserProfileServiceImpl extends ServiceImpl<UserProfileMapper, UserProfile> implements UserProfileService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfileResponse createProfile(UserProfileCreateRequest request) {
|
||||||
|
log.info("Creating user profile: {}", request);
|
||||||
|
|
||||||
|
// 获取当前登录用户ID
|
||||||
|
String currentUserId = UserContextHolder.getCurrentUserId();
|
||||||
|
if (!StringUtils.hasText(currentUserId)) {
|
||||||
|
throw new RuntimeException("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否已存在档案
|
||||||
|
LambdaQueryWrapper<UserProfile> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(UserProfile::getUserId, currentUserId);
|
||||||
|
if (count(queryWrapper) > 0) {
|
||||||
|
throw new RuntimeException("当前用户已存在档案信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
UserProfile userProfile = new UserProfile();
|
||||||
|
BeanUtils.copyProperties(request, userProfile);
|
||||||
|
userProfile.setUserId(currentUserId);
|
||||||
|
userProfile.setStatus(1); // 默认正常
|
||||||
|
|
||||||
|
save(userProfile);
|
||||||
|
log.info("User profile created with ID: {}", userProfile.getId());
|
||||||
|
|
||||||
|
return convertToResponse(userProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfileResponse updateProfile(UserProfileUpdateRequest request) {
|
||||||
|
log.info("Updating user profile: {}", request);
|
||||||
|
|
||||||
|
UserProfile userProfile = getById(request.getId());
|
||||||
|
if (userProfile == null) {
|
||||||
|
throw new RuntimeException("档案不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限校验:只能修改自己的档案
|
||||||
|
String currentUserId = UserContextHolder.getCurrentUserId();
|
||||||
|
if (!StringUtils.hasText(currentUserId)) {
|
||||||
|
throw new RuntimeException("用户未登录");
|
||||||
|
}
|
||||||
|
if (!userProfile.getUserId().equals(currentUserId)) {
|
||||||
|
// 管理员可以修改任意档案 (此处假设没有管理员逻辑,严格按需求: 只能修改自己的)
|
||||||
|
// 如果需要管理员权限,需配合 SecurityUtils 判断角色
|
||||||
|
// throw new RuntimeException("无权修改他人档案");
|
||||||
|
// 暂时允许用户修改自己的档案
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用Hutool的BeanUtil进行部分更新,忽略null值
|
||||||
|
BeanUtil.copyProperties(request, userProfile, CopyOptions.create().setIgnoreNullValue(true));
|
||||||
|
updateById(userProfile);
|
||||||
|
log.info("User profile updated: {}", userProfile.getId());
|
||||||
|
|
||||||
|
return convertToResponse(userProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfileResponse getCurrentUserProfile() {
|
||||||
|
String currentUserId = UserContextHolder.getCurrentUserId();
|
||||||
|
if (!StringUtils.hasText(currentUserId)) {
|
||||||
|
throw new RuntimeException("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaQueryWrapper<UserProfile> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(UserProfile::getUserId, currentUserId);
|
||||||
|
// 获取最新的一条(理论上应该只有一条)
|
||||||
|
List<UserProfile> list = list(queryWrapper);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return convertToResponse(list.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfileResponse getProfileById(String id) {
|
||||||
|
UserProfile userProfile = getById(id);
|
||||||
|
if (userProfile == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return convertToResponse(userProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<UserProfileResponse> getProfilePage(UserProfilePageRequest request) {
|
||||||
|
Page<UserProfile> page = new Page<>(request.getCurrent(), request.getSize());
|
||||||
|
LambdaQueryWrapper<UserProfile> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
if (StringUtils.hasText(request.getUserId())) {
|
||||||
|
queryWrapper.eq(UserProfile::getUserId, request.getUserId());
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(request.getNickname())) {
|
||||||
|
queryWrapper.like(UserProfile::getNickname, request.getNickname());
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(request.getMbti())) {
|
||||||
|
queryWrapper.eq(UserProfile::getMbti, request.getMbti());
|
||||||
|
}
|
||||||
|
if (request.getStatus() != null) {
|
||||||
|
queryWrapper.eq(UserProfile::getStatus, request.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc(UserProfile::getCreateTime);
|
||||||
|
|
||||||
|
IPage<UserProfile> userProfilePage = page(page, queryWrapper);
|
||||||
|
|
||||||
|
List<UserProfileResponse> list = userProfilePage.getRecords().stream()
|
||||||
|
.map(this::convertToResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
PageResult<UserProfileResponse> result = new PageResult<>();
|
||||||
|
result.setCurrent(userProfilePage.getCurrent());
|
||||||
|
result.setSize(userProfilePage.getSize());
|
||||||
|
result.setTotal(userProfilePage.getTotal());
|
||||||
|
result.setPages(userProfilePage.getPages());
|
||||||
|
result.setRecords(list);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserProfileResponse> getProfileList(UserProfilePageRequest request) {
|
||||||
|
LambdaQueryWrapper<UserProfile> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
if (StringUtils.hasText(request.getUserId())) {
|
||||||
|
queryWrapper.eq(UserProfile::getUserId, request.getUserId());
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(request.getNickname())) {
|
||||||
|
queryWrapper.like(UserProfile::getNickname, request.getNickname());
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(request.getMbti())) {
|
||||||
|
queryWrapper.eq(UserProfile::getMbti, request.getMbti());
|
||||||
|
}
|
||||||
|
if (request.getStatus() != null) {
|
||||||
|
queryWrapper.eq(UserProfile::getStatus, request.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc(UserProfile::getCreateTime);
|
||||||
|
|
||||||
|
List<UserProfile> list = list(queryWrapper);
|
||||||
|
return list.stream()
|
||||||
|
.map(this::convertToResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteProfile(String id) {
|
||||||
|
log.info("Deleting user profile: {}", id);
|
||||||
|
return removeById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserProfileResponse convertToResponse(UserProfile userProfile) {
|
||||||
|
if (userProfile == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
UserProfileResponse response = new UserProfileResponse();
|
||||||
|
BeanUtils.copyProperties(userProfile, response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import request from '../utils/request';
|
||||||
|
|
||||||
|
export const userApi = {
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户的档案
|
||||||
|
*/
|
||||||
|
getCurrentUser() {
|
||||||
|
return request({
|
||||||
|
url: '/user-profile/me',
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增档案
|
||||||
|
*/
|
||||||
|
createUserProfile(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user-profile/create',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改档案
|
||||||
|
*/
|
||||||
|
updateUserProfile(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user-profile/update',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询详情
|
||||||
|
*/
|
||||||
|
getProfileById(id) {
|
||||||
|
return request({
|
||||||
|
url: '/user-profile/detail',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除档案
|
||||||
|
*/
|
||||||
|
deleteUserProfile(id) {
|
||||||
|
return request({
|
||||||
|
url: '/user-profile/delete',
|
||||||
|
method: 'delete',
|
||||||
|
params: { id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -68,16 +68,46 @@ export function PathView({ onSwitchToScript }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = async () => {
|
||||||
if (window.confirm('确定要删除这个路径规划吗?')) {
|
if (window.confirm('确定要删除这个路径规划吗?')) {
|
||||||
Store.deletePath(currentPath.id);
|
Store.deletePath(currentPath.id);
|
||||||
|
|
||||||
|
// Sync to backend
|
||||||
|
try {
|
||||||
|
const allPaths = Store.get().paths;
|
||||||
|
const profileRes = await userApi.getCurrentUser();
|
||||||
|
if (profileRes.data) {
|
||||||
|
await userApi.updateUserProfile({
|
||||||
|
id: profileRes.data.id,
|
||||||
|
paths: JSON.stringify(allPaths)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to sync path deletion to backend", err);
|
||||||
|
}
|
||||||
|
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveEdit = () => {
|
const handleSaveEdit = async () => {
|
||||||
if (editedPath) {
|
if (editedPath) {
|
||||||
Store.updatePath(editedPath.id, { steps: editedPath.steps });
|
Store.updatePath(editedPath.id, { steps: editedPath.steps });
|
||||||
|
|
||||||
|
// Sync to backend
|
||||||
|
try {
|
||||||
|
const allPaths = Store.get().paths;
|
||||||
|
const profileRes = await userApi.getCurrentUser();
|
||||||
|
if (profileRes.data) {
|
||||||
|
await userApi.updateUserProfile({
|
||||||
|
id: profileRes.data.id,
|
||||||
|
paths: JSON.stringify(allPaths)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to sync path update to backend", err);
|
||||||
|
}
|
||||||
|
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Store } from '../../utils/store';
|
import { Store } from '../../utils/store';
|
||||||
|
import { userApi } from '../../api/user';
|
||||||
import { AI } from '../../utils/aiLogic';
|
import { AI } from '../../utils/aiLogic';
|
||||||
import { useStoreData } from '../../hooks/useStoreData';
|
import { useStoreData } from '../../hooks/useStoreData';
|
||||||
import { Fingerprint, Film, Sparkles, History, Trash2, Stars, Zap, Loader, X, ArrowRight, BookOpen } from 'lucide-react';
|
import { Fingerprint, Film, Sparkles, History, Trash2, Stars, Zap, Loader, X, ArrowRight, BookOpen } from 'lucide-react';
|
||||||
@@ -29,6 +30,21 @@ export function ScriptView({ onSwitchToPath }) {
|
|||||||
const requirements = form;
|
const requirements = form;
|
||||||
const script = await AI.generateScript(data.userProfile, data.lifeTimeline, requirements);
|
const script = await AI.generateScript(data.userProfile, data.lifeTimeline, requirements);
|
||||||
Store.addScript(script);
|
Store.addScript(script);
|
||||||
|
|
||||||
|
// Sync to backend
|
||||||
|
try {
|
||||||
|
const allScripts = Store.get().generatedScripts;
|
||||||
|
const profileRes = await userApi.getCurrentUser();
|
||||||
|
if (profileRes.data) {
|
||||||
|
await userApi.updateUserProfile({
|
||||||
|
id: profileRes.data.id,
|
||||||
|
scripts: JSON.stringify(allScripts)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to sync script to backend", err);
|
||||||
|
}
|
||||||
|
|
||||||
setSelectedScriptId(script.id);
|
setSelectedScriptId(script.id);
|
||||||
setForm({ ...form, theme: '' });
|
setForm({ ...form, theme: '' });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -39,10 +55,25 @@ export function ScriptView({ onSwitchToPath }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (id, e) => {
|
const handleDelete = async (id, e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (confirm('确定删除这个剧本吗?')) {
|
if (confirm('确定删除这个剧本吗?')) {
|
||||||
Store.deleteScript(id);
|
Store.deleteScript(id);
|
||||||
|
|
||||||
|
// Sync to backend
|
||||||
|
try {
|
||||||
|
const allScripts = Store.get().generatedScripts;
|
||||||
|
const profileRes = await userApi.getCurrentUser();
|
||||||
|
if (profileRes.data) {
|
||||||
|
await userApi.updateUserProfile({
|
||||||
|
id: profileRes.data.id,
|
||||||
|
scripts: JSON.stringify(allScripts)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to sync script deletion to backend", err);
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedScriptId === id) setSelectedScriptId(null);
|
if (selectedScriptId === id) setSelectedScriptId(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Store } from '../utils/store';
|
import { Store } from '../utils/store';
|
||||||
import { ArrowLeft, ArrowRight, Check, X, Sparkles, Star, AlertCircle, CheckCircle } from 'lucide-react';
|
import { userApi } from '../api/user';
|
||||||
|
import { ArrowLeft, ArrowRight, Check, X, Sparkles, Star, AlertCircle, CheckCircle, Loader } from 'lucide-react';
|
||||||
import { Button } from '../components/ui/Button';
|
import { Button } from '../components/ui/Button';
|
||||||
import { Input, Select, Textarea } from '../components/ui/Input';
|
import { Input, Select, Textarea } from '../components/ui/Input';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
@@ -17,6 +18,55 @@ export function OnboardingPage({ onFinish }) {
|
|||||||
const [step, setStep] = useState(0);
|
const [step, setStep] = useState(0);
|
||||||
const [formData, setFormData] = useState(Store.get().userProfile);
|
const [formData, setFormData] = useState(Store.get().userProfile);
|
||||||
const [toast, setToast] = useState(null); // { msg, type }
|
const [toast, setToast] = useState(null); // { msg, type }
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
|
||||||
|
// Load existing profile from backend on mount
|
||||||
|
useEffect(() => {
|
||||||
|
const loadProfile = async () => {
|
||||||
|
try {
|
||||||
|
const res = await userApi.getCurrentUser();
|
||||||
|
if (res.data) {
|
||||||
|
// Merge backend data with local state, handling JSON strings if necessary
|
||||||
|
// Backend returns scripts/paths as strings, but profile fields are direct
|
||||||
|
// Note: formData structure matches userProfile in store.js
|
||||||
|
// We need to map backend fields (camelCase) to frontend structure if they differ
|
||||||
|
// Backend: childhoodDate, childhoodContent etc.
|
||||||
|
// Frontend: history: { childhood: { date, content } }
|
||||||
|
// We need a mapper if structures differ.
|
||||||
|
// Backend UserProfileResponse has: nickname, gender, zodiac, mbti, hobbies (String), childhoodDate...
|
||||||
|
|
||||||
|
const backendData = res.data;
|
||||||
|
const mappedData = {
|
||||||
|
...formData,
|
||||||
|
nickname: backendData.nickname || formData.nickname,
|
||||||
|
gender: backendData.gender || formData.gender,
|
||||||
|
zodiac: backendData.zodiac || formData.zodiac,
|
||||||
|
mbti: backendData.mbti || formData.mbti,
|
||||||
|
hobbies: backendData.hobbies ? JSON.parse(backendData.hobbies) : formData.hobbies,
|
||||||
|
history: {
|
||||||
|
childhood: {
|
||||||
|
date: backendData.childhoodDate || '',
|
||||||
|
content: backendData.childhoodContent || ''
|
||||||
|
},
|
||||||
|
peak: {
|
||||||
|
date: backendData.peakDate || '',
|
||||||
|
content: backendData.peakContent || ''
|
||||||
|
},
|
||||||
|
valley: {
|
||||||
|
date: backendData.valleyDate || '',
|
||||||
|
content: backendData.valleyContent || ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
futureVision: backendData.futureVision || formData.futureVision
|
||||||
|
};
|
||||||
|
setFormData(mappedData);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load profile", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
loadProfile();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const showToast = (msg, type = 'error') => {
|
const showToast = (msg, type = 'error') => {
|
||||||
setToast({ msg, type });
|
setToast({ msg, type });
|
||||||
@@ -40,15 +90,57 @@ export function OnboardingPage({ onFinish }) {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNext = () => {
|
const handleNext = async () => {
|
||||||
if (step === 0) {
|
if (step === 0) {
|
||||||
if (!formData.nickname?.trim()) { showToast('请填写昵称'); return; }
|
if (!formData.nickname?.trim()) { showToast('请填写昵称'); return; }
|
||||||
if (!formData.mbti) { showToast('请选择MBTI人格类型'); return; }
|
if (!formData.mbti) { showToast('请选择MBTI人格类型'); return; }
|
||||||
} else if (step === 4) {
|
} else if (step === 4) {
|
||||||
if (!formData.futureVision?.trim()) { showToast('写下一句对未来的期许吧'); return; }
|
if (!formData.futureVision?.trim()) { showToast('写下一句对未来的期许吧'); return; }
|
||||||
Store.updateProfile(formData);
|
|
||||||
Store.completeOnboarding();
|
setSubmitting(true);
|
||||||
onFinish();
|
try {
|
||||||
|
// 1. Save to local store
|
||||||
|
Store.updateProfile(formData);
|
||||||
|
Store.completeOnboarding();
|
||||||
|
|
||||||
|
// 2. Prepare data for backend
|
||||||
|
// Flatten history structure to match UserProfileCreateRequest
|
||||||
|
const requestData = {
|
||||||
|
nickname: formData.nickname,
|
||||||
|
gender: formData.gender,
|
||||||
|
zodiac: formData.zodiac,
|
||||||
|
mbti: formData.mbti,
|
||||||
|
hobbies: JSON.stringify(formData.hobbies),
|
||||||
|
childhoodDate: formData.history?.childhood?.date || null,
|
||||||
|
childhoodContent: formData.history?.childhood?.content || '',
|
||||||
|
peakDate: formData.history?.peak?.date || null,
|
||||||
|
peakContent: formData.history?.peak?.content || '',
|
||||||
|
valleyDate: formData.history?.valley?.date || null,
|
||||||
|
valleyContent: formData.history?.valley?.content || '',
|
||||||
|
futureVision: formData.futureVision,
|
||||||
|
// Also sync scripts/paths if they exist in store (re-registration case)
|
||||||
|
scripts: JSON.stringify(Store.get().generatedScripts || []),
|
||||||
|
paths: JSON.stringify(Store.get().paths || [])
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. Call backend
|
||||||
|
// Check if profile exists first
|
||||||
|
const currentProfile = await userApi.getCurrentUser();
|
||||||
|
if (currentProfile.data) {
|
||||||
|
// Update
|
||||||
|
await userApi.updateUserProfile({ ...requestData, id: currentProfile.data.id });
|
||||||
|
} else {
|
||||||
|
// Create
|
||||||
|
await userApi.createUserProfile(requestData);
|
||||||
|
}
|
||||||
|
|
||||||
|
onFinish();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
showToast('保存失败,请重试');
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setStep(prev => prev + 1);
|
setStep(prev => prev + 1);
|
||||||
@@ -225,9 +317,9 @@ export function OnboardingPage({ onFinish }) {
|
|||||||
</button>
|
</button>
|
||||||
) : <div></div>}
|
) : <div></div>}
|
||||||
|
|
||||||
<Button onClick={handleNext} className="flex items-center gap-2 px-8 group hover:scale-105 active:scale-95 shadow-lg shadow-primary/20">
|
<Button onClick={handleNext} disabled={submitting} className="flex items-center gap-2 px-8 group hover:scale-105 active:scale-95 shadow-lg shadow-primary/20 disabled:opacity-70 disabled:scale-100">
|
||||||
<span>{step === 4 ? '完成创建' : '下一步'}</span>
|
<span>{step === 4 ? (submitting ? '保存中...' : '开启旅程') : '下一步'}</span>
|
||||||
{step === 4 ? <Check className="w-4 h-4" /> : <ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />}
|
{step === 4 ? (submitting ? <Loader className="w-4 h-4 animate-spin" /> : <Check className="w-4 h-4" />) : <ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+64
-47
@@ -37,50 +37,10 @@ USE emotion_museum;
|
|||||||
-- 4. 索引优化: 为查询频繁的字段创建合适的索引
|
-- 4. 索引优化: 为查询频繁的字段创建合适的索引
|
||||||
-- 5. 字符集: 统一使用utf8mb4支持emoji和特殊字符
|
-- 5. 字符集: 统一使用utf8mb4支持emoji和特殊字符
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 删除现有表(开发阶段确保表结构最新)
|
|
||||||
-- 警告: 这会删除所有数据!
|
|
||||||
-- ============================================================================
|
|
||||||
DROP TABLE IF EXISTS t_user_stats;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_guest_user;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_reward;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_achievement;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_comment;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_community_post;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_location_pin;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_topic_interaction;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_growth_topic;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_emotion_record;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_emotion_analysis;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_coze_api_call;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_message;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_conversation;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_diary_post;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_diary_comment;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_user;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_admin;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS t_ai_config;
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 1. 用户表 (user)
|
-- 1. 用户表 (user)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_user;
|
||||||
CREATE TABLE t_user (
|
CREATE TABLE t_user (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
account VARCHAR(50) UNIQUE COMMENT '账号', -- 账号
|
account VARCHAR(50) UNIQUE COMMENT '账号', -- 账号
|
||||||
@@ -121,6 +81,7 @@ CREATE TABLE t_user (
|
|||||||
-- 2. 对话表 (t_conversation)
|
-- 2. 对话表 (t_conversation)
|
||||||
-- 关联说明: user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
-- 关联说明: user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_conversation;
|
||||||
CREATE TABLE t_conversation (
|
CREATE TABLE t_conversation (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) COMMENT '用户ID (关联t_user.id)', -- 用户ID (关联t_user.id)
|
user_id VARCHAR(64) COMMENT '用户ID (关联t_user.id)', -- 用户ID (关联t_user.id)
|
||||||
@@ -163,6 +124,7 @@ CREATE TABLE t_conversation (
|
|||||||
-- 3. 消息表 (t_message)
|
-- 3. 消息表 (t_message)
|
||||||
-- 关联说明: conversation_id 关联 t_conversation.id,通过代码逻辑维护关联关系
|
-- 关联说明: conversation_id 关联 t_conversation.id,通过代码逻辑维护关联关系
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_message;
|
||||||
CREATE TABLE t_message (
|
CREATE TABLE t_message (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
conversation_id VARCHAR(64) COMMENT '对话ID (关联t_conversation.id)', -- 对话ID (关联t_conversation.id)
|
conversation_id VARCHAR(64) COMMENT '对话ID (关联t_conversation.id)', -- 对话ID (关联t_conversation.id)
|
||||||
@@ -202,6 +164,7 @@ CREATE TABLE t_message (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 4. Coze API调用记录表 (coze_api_call) - 优化版本
|
-- 4. Coze API调用记录表 (coze_api_call) - 优化版本
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_coze_api_call;
|
||||||
CREATE TABLE t_coze_api_call (
|
CREATE TABLE t_coze_api_call (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
conversation_id VARCHAR(64) COMMENT '对话ID', -- 对话ID
|
conversation_id VARCHAR(64) COMMENT '对话ID', -- 对话ID
|
||||||
@@ -266,6 +229,7 @@ CREATE TABLE t_coze_api_call (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 5. 情绪分析表 (emotion_analysis)
|
-- 5. 情绪分析表 (emotion_analysis)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_emotion_analysis;
|
||||||
CREATE TABLE t_emotion_analysis (
|
CREATE TABLE t_emotion_analysis (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
||||||
@@ -292,6 +256,7 @@ CREATE TABLE t_emotion_analysis (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 6. 情绪记录表 (emotion_record)
|
-- 6. 情绪记录表 (emotion_record)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_emotion_record;
|
||||||
CREATE TABLE t_emotion_record (
|
CREATE TABLE t_emotion_record (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
||||||
@@ -318,6 +283,7 @@ CREATE TABLE t_emotion_record (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 7. 成长课题表 (growth_topic)
|
-- 7. 成长课题表 (growth_topic)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_growth_topic;
|
||||||
CREATE TABLE t_growth_topic (
|
CREATE TABLE t_growth_topic (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
title VARCHAR(100) COMMENT '课题标题', -- 课题标题
|
title VARCHAR(100) COMMENT '课题标题', -- 课题标题
|
||||||
@@ -343,6 +309,7 @@ CREATE TABLE t_growth_topic (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 8. 课题互动表 (topic_interaction)
|
-- 8. 课题互动表 (topic_interaction)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_topic_interaction;
|
||||||
CREATE TABLE t_topic_interaction (
|
CREATE TABLE t_topic_interaction (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
topic_id VARCHAR(64) COMMENT '课题ID', -- 课题ID
|
topic_id VARCHAR(64) COMMENT '课题ID', -- 课题ID
|
||||||
@@ -365,6 +332,7 @@ CREATE TABLE t_topic_interaction (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 9. 地点标记表 (location_pin)
|
-- 9. 地点标记表 (location_pin)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_location_pin;
|
||||||
CREATE TABLE t_location_pin (
|
CREATE TABLE t_location_pin (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
name VARCHAR(100) COMMENT '地点名称', -- 地点名称
|
name VARCHAR(100) COMMENT '地点名称', -- 地点名称
|
||||||
@@ -390,6 +358,7 @@ CREATE TABLE t_location_pin (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 10. 社区帖子表 (community_post)
|
-- 10. 社区帖子表 (community_post)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_community_post;
|
||||||
CREATE TABLE t_community_post (
|
CREATE TABLE t_community_post (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
user_id VARCHAR(64) COMMENT '用户ID', -- 用户ID
|
||||||
@@ -415,6 +384,7 @@ CREATE TABLE t_community_post (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 11. 评论表 (comment)
|
-- 11. 评论表 (comment)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_comment;
|
||||||
CREATE TABLE t_comment (
|
CREATE TABLE t_comment (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
post_id VARCHAR(64) COMMENT '帖子ID', -- 帖子ID
|
post_id VARCHAR(64) COMMENT '帖子ID', -- 帖子ID
|
||||||
@@ -434,6 +404,7 @@ CREATE TABLE t_comment (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 12. 成就表 (achievement)
|
-- 12. 成就表 (achievement)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_achievement;
|
||||||
CREATE TABLE t_achievement (
|
CREATE TABLE t_achievement (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
title VARCHAR(100) COMMENT '成就标题', -- 成就标题
|
title VARCHAR(100) COMMENT '成就标题', -- 成就标题
|
||||||
@@ -459,6 +430,7 @@ CREATE TABLE t_achievement (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 13. 奖励表 (reward)
|
-- 13. 奖励表 (reward)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_reward;
|
||||||
CREATE TABLE t_reward (
|
CREATE TABLE t_reward (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
topic_id VARCHAR(64) COMMENT '课题ID', -- 课题ID
|
topic_id VARCHAR(64) COMMENT '课题ID', -- 课题ID
|
||||||
@@ -483,6 +455,7 @@ CREATE TABLE t_reward (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 14. 用户统计表 (user_stats)
|
-- 14. 用户统计表 (user_stats)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_user_stats;
|
||||||
CREATE TABLE t_user_stats (
|
CREATE TABLE t_user_stats (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) UNIQUE COMMENT '用户ID', -- 用户ID
|
user_id VARCHAR(64) UNIQUE COMMENT '用户ID', -- 用户ID
|
||||||
@@ -522,6 +495,7 @@ CREATE TABLE t_user_stats (
|
|||||||
-- 16. 用户日记表 (t_diary_post) - 类似朋友圈功能
|
-- 16. 用户日记表 (t_diary_post) - 类似朋友圈功能
|
||||||
-- 关联说明: user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
-- 关联说明: user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_diary_post;
|
||||||
CREATE TABLE t_diary_post (
|
CREATE TABLE t_diary_post (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
user_id VARCHAR(64) COMMENT '用户ID (关联t_user.id)', -- 用户ID (关联t_user.id)
|
user_id VARCHAR(64) COMMENT '用户ID (关联t_user.id)', -- 用户ID (关联t_user.id)
|
||||||
@@ -567,6 +541,7 @@ CREATE TABLE t_diary_post (
|
|||||||
-- 17. 日记评论表 (t_diary_comment)
|
-- 17. 日记评论表 (t_diary_comment)
|
||||||
-- 关联说明: diary_id 关联 t_diary_post.id,user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
-- 关联说明: diary_id 关联 t_diary_post.id,user_id 关联 t_user.id,通过代码逻辑维护关联关系
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_diary_comment;
|
||||||
CREATE TABLE t_diary_comment (
|
CREATE TABLE t_diary_comment (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
diary_id VARCHAR(64) COMMENT '日记ID (关联t_diary_post.id)', -- 日记ID (关联t_diary_post.id)
|
diary_id VARCHAR(64) COMMENT '日记ID (关联t_diary_post.id)', -- 日记ID (关联t_diary_post.id)
|
||||||
@@ -598,6 +573,7 @@ CREATE TABLE t_diary_comment (
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 18. 访客用户表 (guest_user)
|
-- 18. 访客用户表 (guest_user)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_guest_user;
|
||||||
CREATE TABLE t_guest_user (
|
CREATE TABLE t_guest_user (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
guest_user_id VARCHAR(50) UNIQUE COMMENT '访客用户ID (格式: guest_xxx)', -- 访客用户ID (格式: guest_xxx)
|
guest_user_id VARCHAR(50) UNIQUE COMMENT '访客用户ID (格式: guest_xxx)', -- 访客用户ID (格式: guest_xxx)
|
||||||
@@ -858,6 +834,7 @@ CREATE INDEX idx_guest_user_is_deleted ON t_guest_user (is_deleted);
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- 18. 管理员用户表 (admin)
|
-- 18. 管理员用户表 (admin)
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_admin;
|
||||||
CREATE TABLE t_admin (
|
CREATE TABLE t_admin (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键', -- UUID主键
|
||||||
account VARCHAR(50) NOT NULL UNIQUE COMMENT '管理员账号', -- 管理员账号
|
account VARCHAR(50) NOT NULL UNIQUE COMMENT '管理员账号', -- 管理员账号
|
||||||
@@ -943,6 +920,7 @@ ORDER BY
|
|||||||
-- 19. AI接口配置表 (t_ai_config)
|
-- 19. AI接口配置表 (t_ai_config)
|
||||||
-- 用于存储各种AI接口的调用配置,支持从配置文件迁移到数据库管理
|
-- 用于存储各种AI接口的调用配置,支持从配置文件迁移到数据库管理
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_ai_config;
|
||||||
CREATE TABLE t_ai_config (
|
CREATE TABLE t_ai_config (
|
||||||
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键',
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键',
|
||||||
config_name VARCHAR(100) NOT NULL COMMENT '配置名称',
|
config_name VARCHAR(100) NOT NULL COMMENT '配置名称',
|
||||||
@@ -1007,12 +985,12 @@ CREATE TABLE t_ai_config (
|
|||||||
usage_notes TEXT COMMENT '使用说明',
|
usage_notes TEXT COMMENT '使用说明',
|
||||||
|
|
||||||
-- 公共字段
|
-- 公共字段
|
||||||
create_by VARCHAR(64) COMMENT '创建人ID',
|
create_by VARCHAR(64) COMMENT '创建人ID', -- 创建人ID
|
||||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', -- 创建时间
|
||||||
update_by VARCHAR(64) COMMENT '更新人ID',
|
update_by VARCHAR(64) COMMENT '更新人ID', -- 更新人ID
|
||||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', -- 更新时间
|
||||||
is_deleted TINYINT DEFAULT 0 COMMENT '是否删除: 0-未删除, 1-已删除',
|
is_deleted TINYINT DEFAULT 0 COMMENT '是否删除: 0-未删除, 1-已删除', -- 是否删除: 0-未删除, 1-已删除
|
||||||
remarks VARCHAR(500) COMMENT '备注'
|
remarks VARCHAR(500) COMMENT '备注' -- 备注
|
||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI接口配置表 (t_ai_config)';
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI接口配置表 (t_ai_config)';
|
||||||
|
|
||||||
-- AI配置表索引
|
-- AI配置表索引
|
||||||
@@ -1199,5 +1177,44 @@ INSERT INTO t_ai_config (
|
|||||||
NOW(), NOW(), 0
|
NOW(), NOW(), 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- 19. 用户档案表 (t_user_profile)
|
||||||
|
-- ============================================================================
|
||||||
|
DROP TABLE IF EXISTS t_user_profile;
|
||||||
|
CREATE TABLE t_user_profile (
|
||||||
|
id VARCHAR(64) PRIMARY KEY COMMENT 'UUID主键',
|
||||||
|
user_id VARCHAR(64) COMMENT '用户ID (关联t_user.id)',
|
||||||
|
nickname VARCHAR(50) NOT NULL COMMENT '昵称 (必填)',
|
||||||
|
gender VARCHAR(20) DEFAULT 'secret' COMMENT '性别',
|
||||||
|
zodiac VARCHAR(20) COMMENT '星座',
|
||||||
|
mbti VARCHAR(20) NOT NULL COMMENT 'MBTI人格类型 (必填)',
|
||||||
|
hobbies JSON COMMENT '兴趣爱好列表',
|
||||||
|
childhood_date DATE COMMENT '童年记忆日期',
|
||||||
|
childhood_content TEXT COMMENT '童年记忆内容',
|
||||||
|
peak_date DATE COMMENT '高光时刻日期',
|
||||||
|
peak_content TEXT COMMENT '高光时刻内容',
|
||||||
|
valley_date DATE COMMENT '低谷时刻日期',
|
||||||
|
valley_content TEXT COMMENT '低谷时刻内容',
|
||||||
|
future_vision TEXT COMMENT '未来愿景',
|
||||||
|
scripts JSON COMMENT '生成的剧本列表 (JSON)',
|
||||||
|
paths JSON COMMENT '选择的路径列表 (JSON)',
|
||||||
|
status TINYINT DEFAULT 1 COMMENT '状态: 0-禁用, 1-正常',
|
||||||
|
-- 公共字段
|
||||||
|
create_by VARCHAR(64) COMMENT '创建人ID', -- 创建人ID
|
||||||
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', -- 创建时间
|
||||||
|
update_by VARCHAR(64) COMMENT '更新人ID', -- 更新人ID
|
||||||
|
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', -- 更新时间
|
||||||
|
is_deleted TINYINT DEFAULT 0 COMMENT '是否删除: 0-未删除, 1-已删除', -- 是否删除: 0-未删除, 1-已删除
|
||||||
|
remarks VARCHAR(500) COMMENT '备注' -- 备注
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT '用户个人信息表 (t_user_profile)';
|
||||||
|
|
||||||
|
-- t_user_profile表索引
|
||||||
|
CREATE INDEX idx_user_profile_user_id ON t_user_profile (user_id);
|
||||||
|
CREATE INDEX idx_user_profile_create_time ON t_user_profile (create_time);
|
||||||
|
|
||||||
|
|
||||||
-- 提交事务
|
-- 提交事务
|
||||||
COMMIT;
|
COMMIT;
|
||||||
Reference in New Issue
Block a user