diff --git a/backend/src/main/java/ltd/qubit/survey/controller/UserController.java b/backend/src/main/java/ltd/qubit/survey/controller/UserController.java index 4ec9d5d..c030888 100644 --- a/backend/src/main/java/ltd/qubit/survey/controller/UserController.java +++ b/backend/src/main/java/ltd/qubit/survey/controller/UserController.java @@ -6,6 +6,7 @@ import ltd.qubit.survey.service.UserService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -40,6 +41,33 @@ public class UserController { .orElseThrow(() -> new IllegalArgumentException("用户不存在")); } + /** + * 根据手机号查询用户 + * + * @param phone 手机号 + * @return 用户信息 + */ + @GetMapping("/user/phone/{phone}") + public User findByPhone(@PathVariable String phone) { + return userService.findByPhone(phone) + .orElse(null); + } + + /** + * 更新用户信息 + * + * @param id 用户ID + * @param user 用户信息 + * @return 更新后的用户信息 + */ + @PutMapping("/user/{id}") + public User update(@PathVariable Long id, @RequestBody User user) { + if (!id.equals(user.getId())) { + throw new IllegalArgumentException("用户ID不匹配"); + } + return userService.update(user); + } + /** * 检查手机号是否已注册 * @@ -48,6 +76,6 @@ public class UserController { */ @GetMapping("/user/check/{phone}") public boolean checkPhone(@PathVariable String phone) { - return userService.isPhoneRegistered(phone); + return userService.findByPhone(phone).isPresent(); } } \ No newline at end of file diff --git a/backend/src/main/java/ltd/qubit/survey/dao/UserDao.java b/backend/src/main/java/ltd/qubit/survey/dao/UserDao.java index 7e12669..37e95c9 100644 --- a/backend/src/main/java/ltd/qubit/survey/dao/UserDao.java +++ b/backend/src/main/java/ltd/qubit/survey/dao/UserDao.java @@ -3,17 +3,19 @@ package ltd.qubit.survey.dao; import java.util.List; import java.util.Optional; import ltd.qubit.survey.model.User; -import ltd.qubit.survey.model.WorkArea; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** - * 用户DAO接口 + * 用户DAO */ +@Mapper public interface UserDao extends BaseDao { /** * 根据手机号查询用户 * * @param phone 手机号 - * @return 用户对象 + * @return 用户信息 */ - Optional findByPhone(String phone); + Optional findByPhone(@Param("phone") String phone); } \ No newline at end of file diff --git a/backend/src/main/java/ltd/qubit/survey/model/Question.java b/backend/src/main/java/ltd/qubit/survey/model/Question.java index 142ce7b..b59af88 100644 --- a/backend/src/main/java/ltd/qubit/survey/model/Question.java +++ b/backend/src/main/java/ltd/qubit/survey/model/Question.java @@ -29,11 +29,6 @@ public class Question { */ private QuestionType type; - /** - * 针对的工作领域(为null表示通用问题) - */ - private WorkArea workArea; - /** * 是否必答 */ diff --git a/backend/src/main/java/ltd/qubit/survey/model/WorkArea.java b/backend/src/main/java/ltd/qubit/survey/model/WorkArea.java deleted file mode 100644 index f13981d..0000000 --- a/backend/src/main/java/ltd/qubit/survey/model/WorkArea.java +++ /dev/null @@ -1,51 +0,0 @@ -package ltd.qubit.survey.model; - -/** - * 工作领域枚举 - */ -public enum WorkArea { - /** - * 研发领域 - */ - RD("研发"), - - /** - * 项目领域 - */ - PROJECT("项目"), - - /** - * 保险领域 - */ - INSURANCE("保险"), - - /** - * 财务领域 - */ - FINANCE("财务"), - - /** - * 运营领域 - */ - OPERATION("运营"), - - /** - * 客服领域 - */ - CUSTOMER_SERVICE("客服"), - - /** - * 综合管理领域 - */ - ADMIN("综合管理"); - - private final String displayName; - - WorkArea(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } -} \ No newline at end of file diff --git a/backend/src/main/java/ltd/qubit/survey/service/UserService.java b/backend/src/main/java/ltd/qubit/survey/service/UserService.java index 81515cd..6e55942 100644 --- a/backend/src/main/java/ltd/qubit/survey/service/UserService.java +++ b/backend/src/main/java/ltd/qubit/survey/service/UserService.java @@ -3,18 +3,54 @@ package ltd.qubit.survey.service; import java.util.List; import java.util.Optional; import ltd.qubit.survey.model.User; -import org.springframework.transaction.annotation.Transactional; /** - * 用户服务接口 + * 用户服务 */ -@Transactional(readOnly = true) -public interface UserService extends BaseService { +public interface UserService { + /** + * 创建用户 + * + * @param user 用户信息 + * @return 创建成功的用户信息 + */ + User create(User user); + + /** + * 删除用户 + * + * @param id 用户ID + */ + void delete(Long id); + + /** + * 更新用户信息 + * + * @param user 用户信息 + * @return 更新后的用户信息 + */ + User update(User user); + + /** + * 根据ID查询用户 + * + * @param id 用户ID + * @return 用户信息 + */ + Optional findById(Long id); + + /** + * 查询所有用户 + * + * @return 用户列表 + */ + List findAll(); + /** * 根据手机号查询用户 * * @param phone 手机号 - * @return 用户对象 + * @return 用户信息 */ Optional findByPhone(String phone); @@ -22,16 +58,15 @@ public interface UserService extends BaseService { * 用户注册 * * @param user 用户信息 - * @return 注册成功的用户 + * @return 注册成功的用户信息 */ - @Transactional User register(User user); /** - * 检查手机号是否已被注册 + * 用户登录或注册 * - * @param phone 手机号 - * @return 是否已注册 + * @param user 用户信息 + * @return 登录或注册成功的用户信息 */ - boolean isPhoneRegistered(String phone); + User loginOrRegister(User user); } \ No newline at end of file diff --git a/backend/src/main/java/ltd/qubit/survey/service/impl/UserServiceImpl.java b/backend/src/main/java/ltd/qubit/survey/service/impl/UserServiceImpl.java index f149c3e..edcb7f2 100644 --- a/backend/src/main/java/ltd/qubit/survey/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/ltd/qubit/survey/service/impl/UserServiceImpl.java @@ -8,6 +8,7 @@ import ltd.qubit.survey.dao.UserDao; import ltd.qubit.survey.model.User; import ltd.qubit.survey.service.UserService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * 用户服务实现类 @@ -18,6 +19,7 @@ public class UserServiceImpl implements UserService { private final UserDao userDao; @Override + @Transactional public User create(User user) { user.setCreatedAt(Instant.now()); userDao.insert(user); @@ -25,12 +27,18 @@ public class UserServiceImpl implements UserService { } @Override + @Transactional public void delete(Long id) { userDao.deleteById(id); } @Override + @Transactional public User update(User user) { + Optional existingUser = findById(user.getId()); + if (existingUser.isEmpty()) { + throw new IllegalArgumentException("用户不存在"); + } userDao.update(user); return user; } @@ -51,16 +59,25 @@ public class UserServiceImpl implements UserService { } @Override + @Transactional public User register(User user) { - // 检查手机号是否已注册 - if (isPhoneRegistered(user.getPhone())) { + Optional existingUser = findByPhone(user.getPhone()); + if (existingUser.isPresent()) { throw new IllegalArgumentException("手机号已被注册"); } return create(user); } @Override - public boolean isPhoneRegistered(String phone) { - return userDao.findByPhone(phone).isPresent(); + @Transactional + public User loginOrRegister(User user) { + Optional existingUser = findByPhone(user.getPhone()); + if (existingUser.isPresent()) { + User updatedUser = existingUser.get(); + updatedUser.setName(user.getName()); + updatedUser.setPositionType(user.getPositionType()); + return update(updatedUser); + } + return register(user); } } \ No newline at end of file diff --git a/backend/src/main/resources/mybatis/mapper/UserMapper.xml b/backend/src/main/resources/mybatis/mapper/UserMapper.xml index 43db318..4f1f787 100644 --- a/backend/src/main/resources/mybatis/mapper/UserMapper.xml +++ b/backend/src/main/resources/mybatis/mapper/UserMapper.xml @@ -4,55 +4,54 @@ - + - - `id`, `name`, `phone`, `position_type`, `created_at` + + id, phone, name, position_type, created_at - INSERT INTO `user` (`name`, `phone`, `position_type`) - VALUES (#{name}, #{phone}, #{positionType}) + INSERT INTO user (phone, name, position_type, created_at) + VALUES (#{phone}, #{name}, #{positionType}, NOW()) - UPDATE `user` - SET `name` = #{name}, - `phone` = #{phone}, - `position_type` = #{positionType} - WHERE `id` = #{id} + UPDATE user + SET name = #{name}, + position_type = #{positionType} + WHERE id = #{id} - DELETE FROM `user` WHERE `id` = #{id} + DELETE FROM user WHERE id = #{id} \ No newline at end of file diff --git a/backend/src/main/resources/mybatis/mybatis-config.xml b/backend/src/main/resources/mybatis/mybatis-config.xml index f330cc0..847cc6e 100644 --- a/backend/src/main/resources/mybatis/mybatis-config.xml +++ b/backend/src/main/resources/mybatis/mybatis-config.xml @@ -20,8 +20,6 @@ - { const userId = ref(localStorage.getItem('userId') || ''); const userInfo = ref(null); - // 注册用户 - async function registerUser(data) { + // 用户登录/注册 + async function loginOrRegister(data) { try { - console.log('发送注册请求,数据:', data); - const response = await register(data); - console.log('注册请求响应:', response); + console.log('发送登录/注册请求,数据:', data); + const response = await getUserInfoByPhone(data.phone); - // 检查响应数据结构 - if (!response) { - throw new Error('注册失败:服务器无响应'); + let userData; + if (response) { + // 用户存在,更新信息 + console.log('用户已存在,更新信息'); + userData = await updateUser({ + ...response, + name: data.name, + positionType: data.positionType + }); + } else { + // 用户不存在,注册新用户 + console.log('用户不存在,创建新用户'); + userData = await register(data); } - // 后端直接返回 User 对象,response 就是 User 对象 - const userData = response; console.log('用户数据:', userData); if (!userData || !userData.id) { - throw new Error('注册失败:无效的用户数据'); + throw new Error('登录失败:无效的用户数据'); } // 保存用户信息 @@ -36,30 +43,11 @@ export const useUserStore = defineStore('user', () => { console.log('用户信息已保存,userId:', userId.value); return userData; } catch (error) { - console.error('注册请求失败:', error); + console.error('登录/注册请求失败:', error); if (error.response) { console.error('错误响应:', error.response); } - const message = error.response?.data?.message || error.message || '注册失败,请稍后重试'; - showToast(message); - throw error; - } - } - - // 检查手机号是否已注册 - async function checkPhoneNumber(phone) { - try { - console.log('检查手机号:', phone); - const response = await checkPhone(phone); - console.log('检查手机号响应:', response); - // 如果响应是包装过的,尝试获取实际数据 - return response.data ?? response; - } catch (error) { - console.error('检查手机号失败:', error); - if (error.response) { - console.error('错误响应:', error.response); - } - const message = error.response?.data?.message || error.message || '检查手机号失败,请稍后重试'; + const message = error.response?.data?.message || error.message || '登录失败,请稍后重试'; showToast(message); throw error; } @@ -71,7 +59,6 @@ export const useUserStore = defineStore('user', () => { console.log('获取用户信息:', id); const response = await getUserInfo(id); console.log('获取用户信息响应:', response); - // 如果响应是包装过的,尝试获取实际数据 const userData = response.data || response; userInfo.value = userData; return userData; @@ -86,10 +73,27 @@ export const useUserStore = defineStore('user', () => { } } + // 根据手机号获取用户信息 + async function getUserInfoByPhoneNumber(phone) { + try { + console.log('根据手机号获取用户信息:', phone); + const response = await getUserInfoByPhone(phone); + console.log('获取用户信息响应:', response); + return response; + } catch (error) { + console.error('获取用户信息失败:', error); + if (error.response) { + console.error('错误响应:', error.response); + } + throw error; + } + } + // 退出登录 function logout() { const surveyStore = useSurveyStore(); userId.value = null; + userInfo.value = null; localStorage.removeItem('userId'); surveyStore.resetSurvey(); } @@ -97,9 +101,9 @@ export const useUserStore = defineStore('user', () => { return { userId, userInfo, - registerUser, - checkPhoneNumber, + loginOrRegister, fetchUserInfo, + getUserInfoByPhone: getUserInfoByPhoneNumber, logout, }; }); \ No newline at end of file diff --git a/frontend/src/views/RegisterView.vue b/frontend/src/views/RegisterView.vue index b449567..4b33a60 100644 --- a/frontend/src/views/RegisterView.vue +++ b/frontend/src/views/RegisterView.vue @@ -1,6 +1,6 @@