All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.javaclub.base.web.UserController Maven / Gradle / Ivy

/* Automatic generated by CrudCodeGenerator wirtten by Gerald Chen
 *
 * @(#)UserController.java	2023-09-14
 *
 * Copyright (c) 2023 - 2099. All Rights Reserved.
 *
 */

package com.github.javaclub.base.web;

import java.util.Map;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.github.javaclub.Constants.EnableStatus;
import com.github.javaclub.base.annotation.WithApiResult;
import com.github.javaclub.base.convert.WechatConvertor;
import com.github.javaclub.base.domain.AppUserDO;
import com.github.javaclub.base.domain.UserProfile;
import com.github.javaclub.base.service.AppUserProfileBuilder;
import com.github.javaclub.base.service.UserAccountService;
import com.github.javaclub.base.service.impl.TokenStoreService;
import com.github.javaclub.base.service.param.WxUserAccountParam;
import com.github.javaclub.base.utils.ConfigUtils;
import com.github.javaclub.base.utils.SecurityUtils;
import com.github.javaclub.base.utils.UserUtils;
import com.github.javaclub.ossclient.OSS;
import com.github.javaclub.ossclient.OssConstants;
import com.github.javaclub.sword.BizException;
import com.github.javaclub.sword.annotation.TestMock;
import com.github.javaclub.sword.annotation.swagger.ApiRequestObject;
import com.github.javaclub.sword.annotation.swagger.ApiRequestProperty;
import com.github.javaclub.sword.annotation.swagger.ApiResponseObject;
import com.github.javaclub.sword.annotation.swagger.ApiResponseProperty;
import com.github.javaclub.sword.core.BizObjects;
import com.github.javaclub.sword.core.Maps;
import com.github.javaclub.sword.core.Strings;
import com.github.javaclub.sword.domain.ResultDO;
import com.github.javaclub.sword.domain.enumtype.BasicMessage;
import com.github.javaclub.sword.spring.BeanCopierUtils;
import com.github.javaclub.sword.util.WebUtil;
import com.github.javaclub.toolbox.enumtype.SysAccountEnum;
import com.github.javaclub.wechat.WechatManager;
import com.github.javaclub.wechat.model.MpUserInfo;
import com.github.javaclub.wechat.param.MpUserRequestParam;
import com.github.javaclub.wechat.param.WechatMPLoginParam;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;


/**
 * UserController
 *
 * @author Gerald Chen
 * @version $Id: UserController.java 2023-09-14 13:39:11 Exp $
 */
@RestController
@RequestMapping("/app/user")
@Api(tags = "C端用户: 注册登录")
@WithApiResult
@AllArgsConstructor
public class UserController {
	
	private final UserAccountService userAccountService;
	private final TokenStoreService tokenStoreService;
	private final WechatManager wechatManager;
	
	private final AppUserProfileBuilder appUserProfileBuilder;
	
	@PostMapping(value = "/files/imageUpload")
	@ApiOperation(value = "上传图片")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "token", value = "鉴权token", paramType = "header", dataType = "string", required = true), 
		@ApiImplicitParam(name = "key", value = "指定上传用途key(可选英文字符串)", paramType = "query", dataType = "string", required = false), 
		@ApiImplicitParam(name = "file", value = "要上传的文件", paramType = "form", dataType = "__file", required = true)
	})
	@ApiResponseObject(name = "UserFileUploadResult", description = "文件上传结果", 
		properties = {
			@ApiResponseProperty(name = "url", description = "资源访问URL", type = "string"), 
			@ApiResponseProperty(name = "total", description = "文件大小(byte字节)", type = "long")
		}
	)
	public Map imageUpload(@RequestParam(name = "key", required = false) String key, 
											@RequestParam("file") MultipartFile file) throws Exception {
		Map params = Maps.createMap(
			OssConstants.FILE_FORMAT_PARAM_KEY, "jpg, jpeg, png",
			OssConstants.EXTRA_BIZ_KEY_PARAM, key, 
			"total", file.getSize()
		);
		params.put("total", file.getSize());
		
		String relativePath = "images/";
		String imageUrl = OSS.get().upload(file, relativePath, params);
		
		return Maps.createMap(
			"url", imageUrl,
			"total", file.getSize()
		);
	}
	
	@GetMapping(value = "/profile")
    @ApiOperation(value = "用户基本信息")
    @ApiImplicitParams({
		@ApiImplicitParam(name = "token", value = "鉴权token",  paramType = "header", dataType = "string", required = true)
	})
    public UserProfile userProfile() throws Exception {
		UserProfile wxUser = SecurityUtils.getAppUser();
    		BizObjects.requireTrue(null != wxUser, BasicMessage.NO_LOGIN_USERINFO);
        return wxUser;
    }
	
	
	@PostMapping(value = "/updateProfile")
    @ApiOperation(value = "修改用户信息")
    @ApiImplicitParams({
		@ApiImplicitParam(name = "token", value = "鉴权token",  paramType = "header", dataType = "string", required = true)
	})
	@ApiRequestObject(name = "UpdateUserProfileParam", description = "修改用户资料参数", 
		properties = {
			@ApiRequestProperty(name = "nickname", description = "昵称", type = "string"),
			@ApiRequestProperty(name = "name", description = "姓名", type = "string"),
			@ApiRequestProperty(name = "gender", description = "性别: [1-男 2-女]", type = "integer"),
			@ApiRequestProperty(name = "userAvatar", description = "头像图片URL", type = "string"),
		}
	)
    public Boolean updateProfile(@RequestBody Map param) throws Exception {
		UserProfile profile = SecurityUtils.getAppUserFromToken(true);
    		AppUserDO user = UserUtils.asUser(param);
		user.setId(profile.getId());
		ResultDO rd = userAccountService.update(user);
        return null != rd && rd.isSuccess();
    }
	
	
	@PostMapping(value = "/wxmpLogin")
    @ApiOperation(value = "微信小程序授权登录")
	@ApiResponseObject(name = "WxUserLoginResp", description = "后台用户登录响应", 
		properties = {
			@ApiResponseProperty(name = "token", description = "鉴权token", type = "string"),
			@ApiResponseProperty(name = "userProfile", description = "用户基本信息", type = "object", refType = "UserProfile")
		}
	)
	@TestMock(uniqKey = "biz-app-wxLogin")
    public Map wxlogin(@RequestBody MpUserRequestParam param,
    									HttpServletRequest request) throws Exception {
        BizObjects.requireNotEmpty(param.getAuthCode(), "微信授权authCode不能为空!");
        if (ConfigUtils.isWxmpLoginShouldAuthorizedMobile()) {
        		BizObjects.requireNotEmpty(param.getCode(), "登录须先授权手机号哦,授权code参数不能为空!");
        }
        WechatMPLoginParam loginRequest = WechatConvertor.INTANCE.from(param);
        MpUserInfo mpUserInfo = wechatManager.getWxmpBaseInfo(loginRequest);
        BizObjects.requireTrue(null != mpUserInfo && Strings.isNotBlank(mpUserInfo.getOpenId()), "获取微信授权信息失败,请稍后再试!");
        if (ConfigUtils.isWxmpLoginShouldAuthorizedMobile()) {
          	BizObjects.requireNotEmpty(mpUserInfo.getPhoneNumber(), "授权手机号获取失败,请稍后再试!");
        }

        AppUserDO wxUser = userAccountService.getByOpenId(mpUserInfo.getOpenId());
        if (null == wxUser) { // 尚未注册初始化的用户
            wxUser = WechatConvertor.INTANCE.copy(mpUserInfo);
            String ip = WebUtil.getIpAddr(request);
            wxUser.setLocationIp(ip);
            WxUserAccountParam accountParam = WxUserAccountParam.builder().user(wxUser)
            					.initPointsAccount(false)
            					.build();
            boolean suc = userAccountService.createAccountAndInit(accountParam);
            if (!suc) {
                throw new BizException("登录失败: 用户账号初始化异常!");
            }
        } else {
        		if (Objects.equals(EnableStatus.DISABLED, wxUser.getStatus())) {
        			throw new BizException(BasicMessage.FORBIDDEN_USER, "抱歉,您的账号已被禁用!");
        		}
        		if (Strings.isAnyNotBlank(mpUserInfo.getAvatarUrl(), mpUserInfo.getNickName())) {
        			wxUser.setNickname(mpUserInfo.getNickName());
        			wxUser.setUserAvatar(mpUserInfo.getAvatarUrl());
        			userAccountService.updateUsernickAndUserAvatar(wxUser);
        		}
        }
        
        UserProfile profile = BeanCopierUtils.copyProperties(wxUser, UserProfile.class);
        profile.setMobile(mpUserInfo.getPhoneNumber()); // 有可能小程序用户授权切换了不同的手机号
        profile.setExtraId(wxUser.getExtraId());
        profile.setExtraName(wxUser.getExtraName());
        appUserProfileBuilder.buildup(profile);
        String token = tokenStoreService.generateAuthToken(SysAccountEnum.BIZ.getValue(), wxUser.getId(), profile);
        
        return Maps.createMap("token", token, "userProfile", profile);
    }
	
	
	@GetMapping(value = "/logout")
    @ApiOperation(value = "退出系统")
    @ApiImplicitParam(value = "鉴权token", name = "token", paramType = "header", dataType = "string", required = true)
    public Boolean logout(@RequestHeader("token") String token) throws Exception {
        BizObjects.requireTrue(Strings.isNotBlank(token), BasicMessage.NO_AUTHORIZED);
        UserProfile user = checkAppUser();
        return tokenStoreService.deleteAllToken(SysAccountEnum.BIZ.getValue(), user.getId(), token);
    }
	
	@PostMapping(value = "/authorizedMobile")
    @ApiOperation(value = "小程序用户授权绑定手机号")
    @ApiImplicitParams({
		@ApiImplicitParam(name = "token", value = "鉴权token",  paramType = "header", dataType = "String", required = true)
	})
    public Boolean authorizedAndBindingMobile(@RequestBody MpUserRequestParam param) throws Exception {
    		UserProfile user = checkAppUser();
    		AppUserDO dbUser = userAccountService.selectById(user.getId());
		if (null != dbUser && Strings.isNotBlank(dbUser.getMobile())) {
			throw new BizException("已绑定过手机号,请解绑后重新授权绑定!");
		}
        BizObjects.requireNotEmpty(param.getCode(), "授权code参数不能为空!");
        String phone = wechatManager.getWxmpUserPhoneNumber(param.getCode());
        if (Strings.isNotBlank(phone)) {
            return userAccountService.bindAuthorizedMobile(phone);
        }
        throw new BizException("授权绑定手机号失败!");
    }
	
	@PostMapping(value = "/unauthorizedMobile")
    @ApiOperation(value = "取消绑定授权手机号")
    @ApiImplicitParams({
		@ApiImplicitParam(name = "token", value = "鉴权token",  paramType = "header", dataType = "String", required = true)
	})
    public Boolean unauthorizedMobile() throws Exception {
    		UserProfile user = checkAppUser();
    		AppUserDO dbUser = userAccountService.selectById(user.getId());
		if (null != dbUser && null == dbUser.getMobile()) {
			throw new BizException("手机号已取消绑定,请勿重复操作!");
		}
        return userAccountService.unauthorizedMobile(user.getId());
    }
	
	
	UserProfile checkAppUser() {
		return BizObjects.requireNotNull(SecurityUtils.getAppUser(), BasicMessage.LOGIN_INVALID);
	}
	
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy