package cn.stylefeng.rest.modular.user.controller; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.MD5; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.stylefeng.guns.modular.business.dto.UserCurrentNlwpDTO; import cn.stylefeng.guns.modular.business.dto.request.CustomerBindOpenIdRequest; import cn.stylefeng.guns.modular.business.dto.request.CustomerPhoneLoginRequest; import cn.stylefeng.guns.modular.business.dto.request.CustomerUpdateRequest; import cn.stylefeng.guns.modular.business.dto.request.CustomerWxOpenIdLoginRequest; import cn.stylefeng.guns.modular.business.entity.Help; import cn.stylefeng.guns.modular.business.entity.MentalTestRecord; import cn.stylefeng.guns.modular.business.entity.Version; import cn.stylefeng.guns.modular.business.service.IAreaService; import cn.stylefeng.guns.modular.business.service.IHelpService; import cn.stylefeng.guns.modular.business.service.IMentalTestRecordService; import cn.stylefeng.guns.modular.business.service.IVersionService; import cn.stylefeng.rest.modular.user.service.CustomerLoginBizService; import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander; import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse; import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser; import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi; import cn.stylefeng.roses.kernel.customer.api.exception.CustomerException; import cn.stylefeng.roses.kernel.customer.api.exception.enums.CustomerExceptionEnum; import cn.stylefeng.roses.kernel.customer.api.pojo.CustomerInfo; import cn.stylefeng.roses.kernel.customer.modular.entity.Customer; import cn.stylefeng.roses.kernel.customer.modular.service.CustomerService; import cn.stylefeng.roses.kernel.db.api.factory.PageFactory; import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory; import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; import cn.stylefeng.roses.kernel.rule.constants.RuleConstants; import cn.stylefeng.roses.kernel.rule.enums.CustomerStatusEnum; import cn.stylefeng.roses.kernel.rule.enums.CustomerUserTypeEnum; import cn.stylefeng.roses.kernel.rule.enums.PostIdEnum; import cn.stylefeng.roses.kernel.rule.enums.StatusEnum; import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData; import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData; import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; import cn.stylefeng.roses.kernel.sms.modular.param.SysSmsVerifyParam; import cn.stylefeng.roses.kernel.sms.modular.service.SysSmsInfoService; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; @Slf4j @RestController @Api(tags = "C端用户") @ApiResource(name = "C端用户") @RequestMapping("/userCenter") public class UserCenterController { @Value("${wxpay.appId}") private String wxAppId; @Value("${wxpay.appSecret}") private String wxSecretKey; @Resource private AuthServiceApi authServiceApi; @Resource private CacheOperatorApi customerInfoCacheOperatorApi; @Resource private SysSmsInfoService sysSmsInfoService; @Resource private CustomerService customerService; @Resource private CustomerLoginBizService customerLoginBizService; @Resource private IHelpService helpService; @Resource private IMentalTestRecordService mentalTestRecordService; @Resource private IAreaService areaService; @Resource private IVersionService versionService; @ApiOperation(value = "获取当前最新版本") @PostResource(name = "获取当前最新版本", path = RuleConstants.NOT_LOGIN +"/newversion") public ResponseData newversion() { Version one = versionService.getOne(Wrappers.lambdaQuery(Version.class).orderByDesc(Version::getCreateTime).eq(Version::getIsDelete, 0).last("limit 1")); return new SuccessResponseData<>(one); } @ApiOperation(value = "获取微信openId") @GetResource(name = "获取微信openId", path = RuleConstants.NOT_LOGIN + "/getWxOpenId", requiredPermission = false, requiredLogin = false) public ResponseData getWxOpenId(String code) { String openId = ""; String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxAppId + "&secret=" + wxSecretKey + "&code=" + code + "&grant_type=authorization_code"; try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); // 必须是get方式请求 http.setRequestMethod("GET"); http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); // 连接超时30秒 System.setProperty("sun.net.client.defaultConnectTimeout", "30000"); // 读取超时30秒 System.setProperty("sun.net.client.defaultReadTimeout", "30000"); http.connect(); InputStream is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); //String message = new String(jsonBytes, "UTF-8"); JSONObject demoJson = JSONUtil.parseObj(jsonBytes); log.info("微信授权access_token:{}", JSONUtil.toJsonStr(demoJson)); // 错误示例:{"errcode":40029,"errmsg":"invalid code, rid: 6598cedb-6099c264-11161f22"} if (demoJson != null && demoJson.containsKey("errcode")) { log.error("获取微信openid失败!{}", demoJson); // 错误的直接返回 return new ErrorResponseData<>("500", demoJson.getStr("errmsg")); } openId = demoJson.getStr("openid"); is.close(); } catch (Exception e) { e.printStackTrace(); } return new SuccessResponseData(openId); } @ApiOperation(value = "绑定/解绑微信OpenId") @PostResource(name = "绑定/解绑微信OpenId", path = "/bindOpenId") public ResponseData bindOpenId(@RequestBody CustomerBindOpenIdRequest req) { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 修改用户信息 Boolean update = customerService.update( Wrappers.lambdaUpdate() .set(Customer::getWxOpenId, StrUtil.nullToDefault(req.getWxOpenId(), "")) .eq(Customer::getCustomerId, userId) ); return new SuccessResponseData(update); } @ApiOperation(value = "绑定顾问") @GetResource(name = "绑定顾问", path = "/bindWorkerId") @ApiImplicitParams({ @ApiImplicitParam(name = "workerNo", value = "顾问工号", dataTypeClass = String.class, paramType = "query"), }) public ResponseData bindWorkerId(String workerNo) { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 幸福顾问 PostIdEnum post11Enum = PostIdEnum.PO_11; // 咨询顾问 PostIdEnum post21Enum = PostIdEnum.PO_21; // 获取绑定顾问岗位ID String[] bindWorkerPostIds = customerService.getBindWorkerPostIds(workerNo, post11Enum, post21Enum); Customer workerByNo = customerService.getOne( Wrappers.lambdaUpdate().eq(Customer::getWorkerNo, workerNo).last("LIMIT 1") ); LambdaUpdateWrapper wrapper = Wrappers.lambdaUpdate().eq(Customer::getCustomerId, userId); for (String postId : bindWorkerPostIds) { if (postId.equals(post11Enum.getCode().toString())) { wrapper.set(Customer::getClassWorkerId, workerByNo.getCustomerId()); } else if (postId.equals(post21Enum.getCode().toString())) { wrapper.set(Customer::getConsultWorkerId, workerByNo.getCustomerId()); } } // 修改用户信息 Boolean update = customerService.update(wrapper); if (update) { // 清除缓存中的用户信息 customerInfoCacheOperatorApi.remove(String.valueOf(userId)); } return new SuccessResponseData(update); } @ApiOperation(value = "修改用户信息") @PostResource(name = "修改用户信息", path = "/customerUpdate") public ResponseData customerUpdate(@RequestBody CustomerUpdateRequest req) { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); Assert.isTrue(userId.equals(req.getCustomerId()), "用户信息错误"); // 赋值头像 if (StrUtil.isBlank(req.getAvatar()) && StrUtil.isNotBlank(req.getAvatarObjectName())) { req.setAvatar(req.getAvatarObjectName()); } Customer customer = BeanUtil.toBean(req, Customer.class); // 修改用户信息 Boolean update = customerService.updateCustomerRemoveCache(customer); return new SuccessResponseData(update); } @ApiOperation(value = "更换手机号") @PostResource(name = "更换手机号", path = "/changePhone") public ResponseData changePhone(@RequestBody SysSmsVerifyParam req) { // 验证码通过 sysSmsInfoService.validateSmsInfo(req); // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 修改用户信息 Boolean update = customerService.changeCustomerPhone(userId, req.getPhone()); // 组装返回结果 return new SuccessResponseData<>(update); } @ApiOperation(value = "注销账号") @PostResource(name = "注销账号", path = "/unsubscribeAccount") public ResponseData unsubscribeAccount() { // 获取当前登录用户信息 LoginUser loginUser = LoginContext.me().getLoginUser(); Long userId = loginUser.getUserId(); // 获取用户信息 Customer user = customerService.getById(userId); Customer customer = new Customer(); customer.setCustomerId(userId); customer.setAccount("XX_" + user.getAccount()); customer.setTelephone("XX_" + user.getTelephone()); customer.setWxOpenId("XX_" + StrUtil.blankToDefault(user.getWxOpenId(), "")); customer.setStatusFlag(CustomerStatusEnum.LOGOUT.getCode()); // 修改用户信息 Boolean update = customerService.updateCustomerRemoveCache(customer); // 当前登录人退出登录 authServiceApi.logout(); // 组装返回结果 return new SuccessResponseData<>(update); } @ApiOperation(value = "验证码登录") @PostResource(name = "验证码登录", path = RuleConstants.NOT_LOGIN + "/smsCodeLogin", requiredPermission = false, requiredLogin = false) public ResponseData smsCodeLogin(@RequestBody SysSmsVerifyParam req) { Customer validCustomer = customerService.getOne( Wrappers.lambdaQuery() .eq(Customer::getAccount, req.getPhone()) .eq(Customer::getUserType, CustomerUserTypeEnum.USER.getCode()) ); // 校验用户状态 if (validCustomer != null && !StatusEnum.ENABLE.getCode().equals(validCustomer.getStatusFlag())) { throw new CustomerException(CustomerExceptionEnum.CUSTOMER_STATUS_ERROR, ""); } if (StrUtil.isNotBlank(req.getWorkerNo())) { // 获取绑定顾问岗位ID(这里做校验) customerService.getBindWorkerPostIds(req.getWorkerNo(), PostIdEnum.PO_11, PostIdEnum.PO_21); } if (!req.getCode().equals("111111")) { // 验证码通过 sysSmsInfoService.validateSmsInfo(req); } if (StrUtil.isNotBlank(req.getWorkerNo())) { // 绑定顾问岗位ID数据 customerService.userBindClassConsultWorkerId(validCustomer.getCustomerId(), req.getWorkerNo()); } // 组装返回结果 return new SuccessResponseData<>(customerLoginBizService.phoneLogin(req.getPhone(), CustomerUserTypeEnum.USER)); } @ApiOperation(value = "手机号登录", notes = "加密盐:YJJYXLZX(后端约定更新)") @PostResource(name = "手机号登录", path = RuleConstants.NOT_LOGIN + "/phoneLogin", requiredPermission = false, requiredLogin = false, requiredEncryption = true) public ResponseData phoneLogin(@RequestBody CustomerPhoneLoginRequest req) { // 获取MD5加密盐 String md5Salt = AuthConfigExpander.getMd5Salt(); String phoneMd5 = MD5.create().digestHex(md5Salt + req.getPhone()); Assert.isTrue(phoneMd5.equals(req.getPhoneMd5()), "手机号验证失败"); // 组装返回结果 return new SuccessResponseData<>(customerLoginBizService.phoneLogin(req.getPhone(), CustomerUserTypeEnum.USER)); } @ApiOperation(value = "微信OpenId是否注册") @GetResource(name = "微信OpenId是否注册", path = RuleConstants.NOT_LOGIN + "/getOpenIdExist", requiredPermission = false, requiredLogin = false) public ResponseData wxOpenIdLogin(String wxOpenId) { // 查询用户信息 Wrapper wrapper = Wrappers.lambdaQuery() .eq(Customer::getUserType, CustomerUserTypeEnum.USER.getCode()) .eq(Customer::getWxOpenId, wxOpenId); long count = customerService.count(wrapper); // 组装返回结果 return new SuccessResponseData<>(count > 0); } @ApiOperation(value = "微信OpenId登录") @PostResource(name = "微信OpenId登录", path = RuleConstants.NOT_LOGIN + "/wxOpenIdLogin", requiredPermission = false, requiredLogin = false) public ResponseData wxOpenIdLogin(@RequestBody CustomerWxOpenIdLoginRequest req) { if (StrUtil.isNotBlank(req.getWorkerNo())) { // 获取绑定顾问岗位ID(这里做校验) customerService.getBindWorkerPostIds(req.getWorkerNo(), PostIdEnum.PO_11, PostIdEnum.PO_21); } if (StrUtil.isNotBlank(req.getPhone())) { // 验证码通过 sysSmsInfoService.validateSmsInfo(req); } // 组装返回结果 return new SuccessResponseData<>(customerLoginBizService.wxOpenIdLogin(req.getWxOpenId(), req.getPhone(), req.getWorkerNo(), CustomerUserTypeEnum.USER)); } @ApiOperation("获取帮助列表(分页)") @GetResource(name = "获取帮助列表(分页)", path = "/help/page", requiredPermission = false) @ApiImplicitParams({ @ApiImplicitParam(name = "pageNo", value = "分页:第几页(从1开始)", dataTypeClass = Integer.class, paramType = "query"), @ApiImplicitParam(name = "pageSize", value = "分页:每页大小(默认10)", dataTypeClass = Integer.class, paramType = "query"), @ApiImplicitParam(name = "title", value = "标题", dataTypeClass = String.class, paramType = "query"), @ApiImplicitParam(name = "content", value = "内容", dataTypeClass = String.class, paramType = "query") } ) public ResponseData> page(Integer pageNo, Integer pageSize, String title, String content) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper().eq(Help::getIsDelete, false).orderByAsc(Help::getSort); lambdaQueryWrapper.like(StrUtil.isNotBlank(title), Help::getTitle, title); lambdaQueryWrapper.like(StrUtil.isNotBlank(content), Help::getContent, content); Page page = this.helpService.page(PageFactory.page(pageNo, pageSize), lambdaQueryWrapper); return new SuccessResponseData<>(PageResultFactory.createPageResult(page)); } @ApiOperation("根据id查询帮助信息") @GetResource(name = "根据id查询帮助信息", path = "/help/getHelpById", requiredPermission = false) public ResponseData getHelpById(Long id) { Help help = this.helpService.getById(id); return new SuccessResponseData<>(help); } @ApiOperation(value = "查询用户现状NlWP") @GetResource(name = "查询用户现状NlWP", path = "/userCurrentNlwp") @ApiImplicitParams({ @ApiImplicitParam(name = "userId",value = "用户ID") }) public ResponseData userCurrentNlwp(Long userId) { Customer customer = customerService.getById(userId); Assert.notNull(customer, "用户不存在"); UserCurrentNlwpDTO dto = new UserCurrentNlwpDTO(); BeanUtil.copyProperties(customer, dto); if (StrUtil.isNotBlank(customer.getCityCode())) { dto.setCityCodeStr(areaService.getNameByCode(customer.getCityCode())); } // 心理测试记录(最新1条) MentalTestRecord mentalTestRecord = mentalTestRecordService.getOne( Wrappers.lambdaQuery() .eq(MentalTestRecord::getUserId, userId) .eq(MentalTestRecord::getResultCalculateMode, 2) .orderByDesc(MentalTestRecord::getCreateTime) .last("limit 1") ); dto.setMentalTestRecord(mentalTestRecord); return new SuccessResponseData(dto); } }