package com.ruoyi.user.controller;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.validation.annotation.Validated;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
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.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.exception.ServiceException;
|
import com.ruoyi.common.core.web.controller.BaseController;
|
import com.ruoyi.common.core.web.page.TableDataInfo;
|
import com.ruoyi.common.security.utils.SecurityUtils;
|
import com.ruoyi.user.domain.AccountAddress;
|
import com.ruoyi.user.domain.dto.AccountAddressDto;
|
import com.ruoyi.user.domain.dto.AccountCertificationApplyDto;
|
import com.ruoyi.user.domain.dto.AccountUserAvatarDto;
|
import com.ruoyi.user.domain.dto.CompanyCertificationApplyDto;
|
import com.ruoyi.user.domain.vo.AccountAddressVo;
|
import com.ruoyi.user.domain.vo.AccountCertificationStatusVo;
|
import com.ruoyi.user.domain.vo.AccountInviteeVo;
|
import com.ruoyi.user.domain.vo.AccountReferrerVo;
|
import com.ruoyi.user.domain.vo.AccountUserInfoVo;
|
import com.ruoyi.user.domain.vo.CompanyCertificationStatusVo;
|
import com.ruoyi.user.domain.vo.InviteCodeVo;
|
import com.ruoyi.user.service.IAccountCertificationApplyService;
|
import com.ruoyi.user.service.IAccountUserService;
|
|
/**
|
* C端会员 个人中心接口
|
*
|
* 网关前缀 /miniapp/account 由 StripPrefix=2 剥掉,故此处映射为 /user,
|
* 外部实际路径为 /miniapp/account/user/**。
|
*
|
* 会员身份取自网关注入的登录态(SecurityUtils.getUserId),不接受前端传 userId,
|
* 天然防止水平越权;未登录请求由网关直接以 401 拦截,故此处不处理未登录分支。
|
*
|
* @author hugray
|
*/
|
@RestController
|
@RequestMapping("/user")
|
public class AccountProfileController extends BaseController
|
{
|
@Autowired
|
private IAccountUserService accountUserService;
|
|
@Autowired
|
private IAccountCertificationApplyService accountCertificationApplyService;
|
|
/**
|
* 查询当前登录会员的个人中心信息
|
*
|
* 返回昵称、头像、会员等级与收益汇总(今日 / 本月 / 累计,单位分)。
|
*
|
* @return 会员信息展示对象
|
*/
|
@GetMapping("/info")
|
public R<AccountUserInfoVo> info()
|
{
|
return R.ok(accountUserService.getAccountUserInfo(SecurityUtils.getUserId()));
|
}
|
|
/**
|
* 更新当前登录会员头像
|
*
|
* 头像文件由小程序直传文件服务(POST /file/upload)后,将返回的 url 通过本接口写回;
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @param dto 头像更新入参(仅含 avatar)
|
* @return 操作结果
|
*/
|
@PostMapping("/avatar")
|
public R<Void> updateAvatar(@Validated @RequestBody AccountUserAvatarDto dto)
|
{
|
accountUserService.updateAvatar(SecurityUtils.getUserId(), dto.getAvatar());
|
return R.ok();
|
}
|
|
/**
|
* 查询当前登录会员的实名认证状态
|
*
|
* 供实名认证页进入时回填:姓名、身份证号、审核状态(0待审核/1已通过/2已驳回)与驳回原因。
|
* 从未提交过申请时返回各字段为空的对象,前端按「未认证」渲染空表单。
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 认证状态(realName / idCard / auditStatus / auditRemark)
|
*/
|
@GetMapping("/certification")
|
public R<AccountCertificationStatusVo> certification()
|
{
|
return R.ok(accountCertificationApplyService.getCertificationStatus(SecurityUtils.getUserId()));
|
}
|
|
/**
|
* 提交实名认证(个人主体)
|
*
|
* 只做基础的姓名必填与身份证号格式校验(@Validated 拦下非法入参),不做三方实名核验;
|
* 提交后落一条待审核的认证申请,出现在管理后台「主体认证审核」列表。
|
* 会员身份取自登录态,不接受前端传入 userId;已有待审核申请时拒绝重复提交。
|
*
|
* @param dto 认证申请入参(仅含 realName、idCard)
|
* @return 操作结果
|
*/
|
@PostMapping("/certification")
|
public R<Void> submitCertification(@Validated @RequestBody AccountCertificationApplyDto dto)
|
{
|
accountCertificationApplyService.submitPersonalCertification(
|
SecurityUtils.getUserId(), dto.getRealName(), dto.getIdCard());
|
return R.ok();
|
}
|
|
/**
|
* 查询当前登录会员的企业/个体认证状态
|
*
|
* 供企业认证向导页进入时回填:整份企业资料 + 审核状态(0待审核/1已通过/2已驳回)与驳回原因。
|
* 从未提交过申请时返回各字段为空的对象,前端按「未认证」渲染空表单。
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 企业/个体认证状态(整份资料 + auditStatus / auditRemark)
|
*/
|
@GetMapping("/company-certification")
|
public R<CompanyCertificationStatusVo> companyCertification()
|
{
|
return R.ok(accountCertificationApplyService.getCompanyCertificationStatus(SecurityUtils.getUserId()));
|
}
|
|
/**
|
* 提交企业/个体工商户认证(主体类型 2/3)
|
*
|
* 只做最基础的必填校验(@Validated 拦下空值与非法枚举),不做格式与三方核验,真实性由后台人工审核把关;
|
* 提交后落一条待审核的认证申请,出现在管理后台「主体认证审核」列表。
|
* 会员身份取自登录态,不接受前端传入 userId;已有待审核的企业申请时拒绝重复提交。
|
*
|
* @param dto 企业认证申请入参
|
* @return 操作结果
|
*/
|
@PostMapping("/company-certification")
|
public R<Void> submitCompanyCertification(@Validated @RequestBody CompanyCertificationApplyDto dto)
|
{
|
accountCertificationApplyService.submitCompanyCertification(SecurityUtils.getUserId(), dto);
|
return R.ok();
|
}
|
|
/**
|
* 查询本人邀请码
|
*
|
* 供「我的邀请」页「邀请码」Tab 展示;会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 邀请码展示对象
|
*/
|
@GetMapping("/invite-code")
|
public R<InviteCodeVo> inviteCode()
|
{
|
return R.ok(accountUserService.getInviteCode(SecurityUtils.getUserId()));
|
}
|
|
/**
|
* 查询本人直接下级(被邀请人)列表
|
*
|
* 分页返回(pageNum 默认 1、pageSize 默认 10),按绑定时间倒序;
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 分页数据(rows 为 AccountInviteeVo 列表,total 为总数)
|
*/
|
@GetMapping("/invitees")
|
public TableDataInfo invitees()
|
{
|
startPage();
|
List<AccountInviteeVo> list = accountUserService.getInvitees(SecurityUtils.getUserId());
|
return getDataTable(list);
|
}
|
|
/**
|
* 查询本人上级(推荐人)信息
|
*
|
* 供「我的邀请」页「邀请我的」Tab 展示;无上级时返回各字段为 null 的对象;
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 上级展示对象
|
*/
|
@GetMapping("/referrer")
|
public R<AccountReferrerVo> referrer()
|
{
|
return R.ok(accountUserService.getReferrer(SecurityUtils.getUserId()));
|
}
|
|
/**
|
* 查询本人收货地址列表
|
*
|
* 默认地址排前,其余按 id 升序;地址数量少,不分页。
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @return 地址列表(无地址返回空集合)
|
*/
|
@GetMapping("/addresses")
|
public R<List<AccountAddressVo>> addressList()
|
{
|
List<AccountAddress> list = accountUserService.getAddressList(SecurityUtils.getUserId());
|
return R.ok(toAddressVoList(list));
|
}
|
|
/**
|
* 查询本人单条收货地址详情
|
*
|
* 供编辑页回填;校验归属,非本人地址抛业务异常。
|
* 会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @param id 地址ID
|
* @return 地址详情
|
*/
|
@GetMapping("/addresses/{id}")
|
public R<AccountAddressVo> addressDetail(@PathVariable("id") Long id)
|
{
|
AccountAddress address = accountUserService.getAddressDetail(SecurityUtils.getUserId(), id);
|
return R.ok(toAddressVo(address));
|
}
|
|
/**
|
* 新增本人收货地址
|
*
|
* 首条地址自动设为默认;会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @param dto 地址入参
|
* @return 操作结果
|
*/
|
@PostMapping("/addresses")
|
public R<Void> createAddress(@Validated @RequestBody AccountAddressDto dto)
|
{
|
accountUserService.insertMyAddress(buildAddress(dto, SecurityUtils.getUserId()));
|
return R.ok();
|
}
|
|
/**
|
* 编辑本人收货地址
|
*
|
* 复用后台改地址事务逻辑(含默认唯一约束);会员身份取自登录态。
|
*
|
* @param dto 地址入参(必含 id)
|
* @return 操作结果
|
*/
|
@PutMapping("/addresses")
|
public R<Void> updateAddress(@Validated @RequestBody AccountAddressDto dto)
|
{
|
if (dto.getId() == null)
|
{
|
throw new ServiceException("地址ID不能为空");
|
}
|
accountUserService.updateAccountAddress(buildAddress(dto, SecurityUtils.getUserId()));
|
return R.ok();
|
}
|
|
/**
|
* 删除本人收货地址
|
*
|
* 校验归属后逻辑删除;会员身份取自登录态,不接受前端传入 userId。
|
*
|
* @param id 地址ID
|
* @return 操作结果
|
*/
|
@DeleteMapping("/addresses/{id}")
|
public R<Void> deleteAddress(@PathVariable("id") Long id)
|
{
|
accountUserService.deleteMyAddress(SecurityUtils.getUserId(), id);
|
return R.ok();
|
}
|
|
/**
|
* DTO 转实体(userId 由登录态注入,不接受前端传值)
|
*/
|
private AccountAddress buildAddress(AccountAddressDto dto, Long userId)
|
{
|
AccountAddress address = new AccountAddress();
|
address.setId(dto.getId());
|
address.setUserId(userId);
|
address.setConsignee(dto.getConsignee());
|
address.setConsigneePhone(dto.getConsigneePhone());
|
address.setAddress(dto.getAddress());
|
address.setIsDefault(dto.getIsDefault());
|
return address;
|
}
|
|
/**
|
* 实体转出参 VO(列表)
|
*/
|
private List<AccountAddressVo> toAddressVoList(List<AccountAddress> list)
|
{
|
List<AccountAddressVo> voList = new ArrayList<>(list.size());
|
for (AccountAddress address : list)
|
{
|
voList.add(toAddressVo(address));
|
}
|
return voList;
|
}
|
|
/**
|
* 实体转出参 VO(单条)
|
*/
|
private AccountAddressVo toAddressVo(AccountAddress address)
|
{
|
AccountAddressVo vo = new AccountAddressVo();
|
vo.setId(address.getId());
|
vo.setConsignee(address.getConsignee());
|
vo.setConsigneePhone(address.getConsigneePhone());
|
vo.setAddress(address.getAddress());
|
vo.setIsDefault(address.getIsDefault());
|
return vo;
|
}
|
}
|