| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- package modules.user;
- import com.alibaba.fastjson.JSONObject;
- import com.jdcloud.sdk.service.sms.model.BatchSendResponse;
- import com.jfinal.aop.Before;
- import com.jfinal.aop.Inject;
- import com.jfinal.kit.HashKit;
- import com.jfinal.kit.StrKit;
- import common.interceptor.LoginInterceptor;
- import common.interceptor.empty.EmptyInterface;
- import common.interceptor.role.RequiredRoleInterface;
- import common.model.User;
- import common.utils.http.MyController;
- import common.utils.http.MyRet;
- import common.utils.http.VerifyCode;
- import common.utils.hyg.AESUtils;
- import common.utils.jdcloud.SMS;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class UserController extends MyController {
- // 验证码相关的常量
- private static final long SEND_VERIFY_CODE_DELAY = 60 * 1000; // 验证码发送间隔
- private static final long VERIFY_CODE_EXPIRATION_TIME = 5 * 60 * 1000; // 验证码有效期,5 分钟 (300 秒)
-
- // 角色相关常量
- public static final int ROLE_SUPER_ADMIN = 0; // 超级管理员
- public static final int ROLE_CHECK_ADMIN = 1; // 审核管理员
- public static final int ROLE_USER = 2; // 普通用户
-
- @Inject
- private UserService service;
- public void hello() {
- renderJson(MyRet.ok(service.hello()));
- }
-
- @EmptyInterface({"mobile_number"})
- public void sendVerifyCode() {
- // --- 核心修改部分 ---
- // 通过 MyController 获取解析后的 JSON 对象,拦截器也使用了这个方法
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- // 从 JSON 对象中获取 mobile_number
- String mobileNumber = requestBodyJson.getString("mobile_number");
- // 2. 校验发送间隔
- // 从 Session 中获取上次发送验证码的时间戳
- Long lastSendTime = getSessionAttr("last_send_verify_code_time");
- if (lastSendTime != null) {
- long currentTime = System.currentTimeMillis();
- if (currentTime - lastSendTime < SEND_VERIFY_CODE_DELAY) {
- // 计算还需要等待多少秒
- long remainingSeconds = (SEND_VERIFY_CODE_DELAY - (currentTime - lastSendTime)) / 1000 + 1; // +1 确保显示完整秒数
- renderJson(MyRet.fail("验证码发送过于频繁,请 " + remainingSeconds + " 秒后再试"));
- return;
- }
- }
- // 3. 生成验证码
- String verifyCode = VerifyCode.randomVerifyCode();
- // 4. 将验证码和发送时间戳存入 Session
- setSessionAttr("verify_code", verifyCode); // 验证码本身
- setSessionAttr("last_send_verify_code_time", System.currentTimeMillis()); // 记录本次发送时间戳
- // 5. 实际发送验证码(这里是模拟发送)
- BatchSendResponse response = SMS.sendVerifyCodeByMobileNumber(mobileNumber, verifyCode);
- String jsonResponse = JSONObject.toJSONString(response);
- boolean isSentSuccessfully = response.getResult().getStatus();
- if (isSentSuccessfully) {
- renderJson(MyRet.ok("验证码已发送,请注意查收。").setData(jsonResponse));
- } else {
- // 短信服务商返回发送失败的情况处理
- renderJson(MyRet.fail("验证码发送失败,请稍后再试").setData(jsonResponse));
- }
- }
- @EmptyInterface({"mobile_number", "pwd_md5", "repeat_pwd_md5", "verify_code"})
- public void register() {
- // --- 核心修改部分:从 JSON 请求体中获取参数 ---
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- // 因为 EmptyInterceptor 已经保证了这些字段不为空,这里可以直接获取
- String mobileNumber = requestBodyJson.getString("mobile_number");
- String pwd = requestBodyJson.getString("pwd_md5");
- String repeatPwd = requestBodyJson.getString("repeat_pwd_md5");
- String userVerifyCode = requestBodyJson.getString("verify_code");
- // 2. 密码重复校验
- if (!pwd.equals(repeatPwd)) {
- renderJson(MyRet.fail("两次输入密码不一致"));
- return;
- }
- // 3. 验证码校验
- MyRet verifyCodeRet = checkVerifyCode(userVerifyCode);
- if (!verifyCodeRet.isOk()) {
- renderJson(verifyCodeRet);
- return;
- }
- // 4. 构建 User 对象并处理业务逻辑
- // 因为 getPara("mobile_number") 已经获取了手机号,这里可以手动设置
- // 或者优化 getModel 的用法,让它只获取数据库字段,然后手动设置 mobileNumber。
- // 但为了保持原先 getModel 的语义,这里继续使用。
- User user = getModel(User.class, "", true);
- // 确保 mobile_number 填充正确
- if (StrKit.isBlank(user.getStr("mobile_number"))) {
- // 如果 getModel 没能获取到 mobile_number,则手动设置,确保数据完整性
- user.set("mobile_number", mobileNumber);
- }
- // 参数补充
- user.set("role", 2); // 例如:2表示普通用户
- // 密码加密并存储
- user.set("pwd_md5_md5", HashKit.md5(pwd));
- user.set("integral", 0);
- user.set("is_deleted", 0); // 0表示未禁用
- // 5. 调用服务层进行用户保存
- renderJson(service.saveUser(user));
- }
- @EmptyInterface({"mobile_number"})
- public void login() {
- // --- 从 JSON 请求体中获取参数 ---
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- // 因为 EmptyInterceptor 已经保证了这些字段不为空,这里可以直接获取
- String mobileNumber = requestBodyJson.getString("mobile_number");
- String pwdMd5 = requestBodyJson.getString("pwd_md5");
- String verifyCode = requestBodyJson.getString("verify_code");
- // 1. 校验手机号是否被注册
- if (!service.isUserExists(mobileNumber)) {
- renderJson(MyRet.fail("该手机号未注册。"));
- return;
- }
-
- // 2.判断是使用密码还是验证码登录
- MyRet ret = MyRet.fail("参数缺失,需要pwd_md5或verify_code").setData(requestBodyJson);
- // 如果传入了密码优先使用密码登录
- if (StrKit.notBlank(pwdMd5)) {
- ret = service.login(mobileNumber, HashKit.md5(pwdMd5));
- }
- // 如果有验证码传入进行验证码校验
- if (StrKit.notBlank(verifyCode)) {
- MyRet verifyCodeRet = checkVerifyCode(verifyCode);
- if (!verifyCodeRet.isOk()) {
- renderJson(verifyCodeRet);
- return;
- }
-
- ret = service.verifyCodeLogin(mobileNumber);
- }
-
- if (ret.isOk()) {
- String token = createToken("dl-token");
- // 更新用户登录时间
- service.updateUserLoginTime(mobileNumber);
- // 更新用户token
- service.updateToken(mobileNumber, token);
-
- // 将token传回前端
- ret.set("token", token);
- // 其它参数的封装
- setSessionAttr("user_id", ((User)ret.get("data")).getStr("id"));
- setSessionAttr("mobile_number", ((User)ret.get("data")).getStr("mobile_number"));
- setSessionAttr("role", ((User)ret.get("data")).getStr("role"));
- }
-
- renderJson(ret);
- }
-
- // 慧用工免登请求地址,用来换取手机号
- public void tokenToMobileNumber() {
- String token = getPara("token");
-
- // 顶层 Map 用于封装整个 JSON 结构
- Map<String, Object> responseJson = new HashMap<>();
- // data Map 用于封装 workerMobile 等信息
- Map<String, String> data = new HashMap<>();
- if (StrKit.notBlank(token)) {
- String mobileNumber = service.findMobileNumberByToken(token);
- if (StrKit.notBlank(mobileNumber)) {
- // 成功获取手机号
- responseJson.put("statusCode", "000000");
- responseJson.put("statusText", "获取手机号成功");
- data.put("workerMobile", mobileNumber);
- data.put("workerName", ""); // 示例中为空,根据实际业务填充
- data.put("idCard", ""); // 示例中为空,根据实际业务填充
- responseJson.put("data", data);
- } else {
- responseJson.put("statusCode", "100001"); // 或 STATUS_CODE_TOKEN_EXPIRED
- responseJson.put("statusText", "token无效或已过期,未找到匹配的手机号");
- data.put("workerMobile", "");
- data.put("workerName", "");
- data.put("idCard", "");
- responseJson.put("data", data);
- }
-
- renderText(service.findMobileNumberByToken(token));
- } else {
- // token 为空
- responseJson.put("statusCode", "100001");
- responseJson.put("statusText", "token不能为空");
- data.put("workerMobile", "");
- data.put("workerName", "");
- data.put("idCard", "");
- responseJson.put("data", data);
- }
- renderJson(responseJson);
- }
- // 慧用工签约回调地址
- public void hygSign() {
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- String businessBodyEncryptedHex = requestBodyJson.getString("businessBody");
- try {
- String body = AESUtils.decryptByHex(businessBodyEncryptedHex);
- JSONObject businessBody = JSONObject.parseObject(body);
-
- String workerId = businessBody.getString("workerId");
- String agreeState = businessBody.getString("agreeState");
- String workerMobile = businessBody.getString("workerMobile");
- User user = service.findUserByMobileNumber(workerMobile);
-
- // 签约成功,则赋予用户workerId
- if (agreeState.equals("2")) {
- user.setHygWorkerId(workerId);
- }
- // 无论成功与否,签约结果都放到数据库,方便维护
- user.setHygSignRst(businessBody.toJSONString());
- // 对user进行升级
- user.update();
- System.out.println(businessBody.toJSONString());
- Map<String, Object> responseJson = new HashMap<>();
- responseJson.put("statusCode", "000000");
- responseJson.put("statusText", "回调成功");
- renderJson(responseJson);
- } catch (Exception e) {
- Map<String, Object> responseJson = new HashMap<>();
- responseJson.put("statusCode", "100000");
- responseJson.put("statusText", "回调失败,解密出现错误 " + e.getMessage());
- System.out.println("回调失败,解密出现错误 " + e.getMessage());
- renderJson(responseJson);
- }
- }
- @Before(LoginInterceptor.class)
- public void getUserInfo() {
- User user = service.findUserByMobileNumber(this.<String>getSessionAttr("mobile_number"));
- if (user == null) {
- removeSessionAttr("dl-token");
- removeSessionAttr("role");
- removeSessionAttr("mobile_number");
-
- renderJson(MyRet.fail("登录信息失效,请重新登录。").setCode(MyRet.CODE_NO_LOGIN));
- } else {
- setSessionAttr("role", user.getRole().toString());
-
- renderJson(MyRet.ok("获取成功").setData(user));
- }
- }
- public void logout() {
- removeSessionAttr("user_id");
- removeSessionAttr("mobile_number");
- removeSessionAttr("dl-token");
- removeSessionAttr("role");
- renderJson(MyRet.ok("已成功登出。"));
- }
- /**
- * 更新用户的方法,传什么更新什么,不传就不更新,id必须传
- */
- @Before(LoginInterceptor.class)
- @RequiredRoleInterface({UserController.ROLE_SUPER_ADMIN})
- @EmptyInterface({"id"})
- public void updateByAdmin() {
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- String id = requestBodyJson.getString("id");
-
- User user = service.findUserById(id);
- // 检查用户合法性
- if (user == null) {
- renderJson(MyRet.fail("用户获取不合法,该id对应的用户不存在,不要乱传参数。id: " + id));
- return;
- }
-
- // 校验昵称是否需要修改
- String nickname = requestBodyJson.getString("nickname");
- if (StrKit.notBlank(nickname)) {
- user.set("nickname", nickname);
- }
-
- // 校验手机号是否需要修改
- String mobileNumber = requestBodyJson.getString("mobile_number");
- if (StrKit.notBlank(mobileNumber)) {
- user.set("mobile_number", mobileNumber);
- }
-
- // 密码修改
- String pwdMd5 = requestBodyJson.getString("pwd_md5");
- if (StrKit.notBlank(pwdMd5)) {
- user.set("pwd_md5_md5", HashKit.md5(pwdMd5));
- }
- // 权限修改
- String roleStr = requestBodyJson.getString("role");
- if (StrKit.notBlank(roleStr)) {
- try {
- int roleInt = Integer.parseInt(roleStr); // 转换为 int 类型
-
- if (roleInt == ROLE_SUPER_ADMIN) {
- renderJson(MyRet.fail("为了安全考虑!不能在该接口设置超级管理员!请联系开发者处理!"));
- return;
- } else if (user.getInt("role") == 0) {
- renderJson(MyRet.fail("为了安全考虑!不能在该接口将超级管理员降级!请联系开发者处理!"));
- return;
- } else {
- user.set("role", roleInt);
- }
- } catch (Exception e) {
- // 处理转换失败的情况,例如记录日志,或者返回错误信息给前端
- renderJson(MyRet.fail("role 格式不正确" + e.getMessage()));
- return; // 中断后续操作
- }
- }
- // 推荐人修改
- String referrerIdStr = requestBodyJson.getString("referrer_id");
- if (StrKit.notBlank(referrerIdStr)) {
- try {
- long referrerIdLong = Long.parseLong(referrerIdStr); // 或者 int,根据数据库字段大小
- user.set("referrer_id", referrerIdLong);
- } catch (Exception e) {
- renderJson(MyRet.fail("referrer_id 格式不正确: " + e.getMessage()));
- return;
- }
- }
- // 积分修改
- String integralStr = requestBodyJson.getString("integral");
- if (StrKit.notBlank(integralStr)) {
- try {
- int integralInt = Integer.parseInt(integralStr);
- user.set("integral", integralInt);
- } catch (Exception e) {
- renderJson(MyRet.fail("integral 格式不正确: " + e.getMessage()));
- return;
- }
- }
-
- // 更新时间
- user.set("update_time", System.currentTimeMillis());
-
- // 执行更新业务
- if (user.update()) {
- renderJson(MyRet.ok("用户更新成功").setData(service.findUserByMobileNumber(user.getMobileNumber())));
- } else {
- renderJson(MyRet.fail("用户更新失败,请将此日志复制给开发者" + user));
- }
- }
- @Before(LoginInterceptor.class)
- @RequiredRoleInterface({UserController.ROLE_SUPER_ADMIN})
- public void count() {
- renderJson(MyRet.ok("查询成功").setData(service.count(null)));
- }
- @Before(LoginInterceptor.class)
- @RequiredRoleInterface({UserController.ROLE_SUPER_ADMIN})
- @EmptyInterface({"page_size", "page_number"})
- public void users() {
- JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
-
- // 页面大小
- String pageSizeStr = requestBodyJson.getString("page_size");
- int pageSizeInt;
- try {
- pageSizeInt = Integer.parseInt(pageSizeStr);
- if (pageSizeInt <= 0) {
- renderJson(MyRet.fail("页面大小(page_size)期待是正整数,你传的是: " + pageSizeStr));
- return;
- }
- } catch (Exception e) {
- renderJson(MyRet.fail("页面大小(page_size)格式不正确: " + e.getMessage()));
- return;
- }
- // 页码
- String pageNumberStr = requestBodyJson.getString("page_number");
- int pageNumberInt;
- try {
- pageNumberInt = Integer.parseInt(pageNumberStr);
-
- if (pageNumberInt <= 0) {
- renderJson(MyRet.fail("页码(page_number)期待是正整数,你传的是: " + pageNumberStr));
- return;
- }
- } catch (Exception e) {
- renderJson(MyRet.fail("页码(page_number)格式不正确: " + e.getMessage()));
- return;
- }
- // 查询条件
- String keywords = requestBodyJson.getString("keywords");
-
- // 最终结果封装
- List<User> users = service.users(pageNumberInt, pageSizeInt, keywords);
- Integer totalUsers = service.count(keywords);
- Map<String, Object> response = new HashMap<>();
- response.put("list", users);
- response.put("total_row", users.toArray().length);
- response.put("total_page", 1 + (users.toArray().length / pageSizeInt));
- response.put("page_size", pageSizeInt);
- response.put("page_number", pageNumberInt);
- response.put("total_user_count", totalUsers);
-
- renderJson(MyRet.ok("查询成功").setData(response));
- }
-
- /*
- *
- ### 验证码修改密码
- POST {{ baseUrl }}/user/updatePwd
- Content-Type: application/json
-
- {
- "mobile_number": "17781855864",
- "new_pwd_md5": "e10adc3949ba59abbe56e057f20f883e",
- "verify_code": "9119"
- }
- *
- * */
- // @EmptyInterface(keyArray = {"mobile_number", "new_pwd_md5", "verify_code"})
- // public void updatePwd() {
- // // --- 核心修改部分:从 JSON 请求体中获取参数 ---
- // JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
- //
- // // 因为 EmptyInterceptor 已经保证了这些字段不为空,这里可以直接获取
- // String mobileNumber = requestBodyJson.getString("mobile_number");
- // String pwdMd5 = requestBodyJson.getString("new_pwd_md5");
- // String verifyCode = requestBodyJson.getString("verify_code");
- // }
-
- private MyRet checkVerifyCode(String userVerifyCode) {
- // 3. 验证码校验
- String storedVerifyCode = getSessionAttr("verify_code");
- Long sendTime = getSessionAttr("last_send_verify_code_time");
- if (StrKit.isBlank(storedVerifyCode) || sendTime == null) {
- // Session中没有验证码或发送时间,可能从未发送过,或Session已失效/过期
- return MyRet.fail("请先获取验证码或验证码已失效");
- }
- // 校验有效期
- long currentTime = System.currentTimeMillis();
- if (currentTime - sendTime > VERIFY_CODE_EXPIRATION_TIME) {
- // 验证码已过期
- // 可以在这里清除Session中的验证码,防止不必要的存储
- removeSessionAttr("verify_code");
- removeSessionAttr("last_send_verify_code_time");
- return MyRet.fail("验证码已过期,请重新获取");
- }
- // 校验用户输入的验证码是否与Session中存储的一致
- if (!userVerifyCode.equals(storedVerifyCode)) {
- renderJson(MyRet.fail("验证码不正确"));
- return MyRet.fail("验证码已过期,请重新获取");
- }
- removeSessionAttr("verify_code");
-
- return MyRet.ok("验证码校验通过");
- }
- }
|