4 文件已复制
6 文件已重命名
70个文件已修改
4个文件已删除
56个文件已添加
| | |
| | | <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version> |
| | | <knife4j.version>3.0.3</knife4j.version> |
| | | <hutool.version>5.7.17</hutool.version> |
| | | <easyexcel.version>4.0.2</easyexcel.version> |
| | | </properties> |
| | | |
| | | <!-- 依赖声明 --> |
| | |
| | | <artifactId>knife4j-micro-spring-boot-starter</artifactId> |
| | | <version>${knife4j.version}</version> |
| | | </dependency> |
| | | |
| | | <!--hutool工具包--> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>${hutool.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | <version>${easyexcel.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |
New file |
| | |
| | | package com.xinquan.system.api; |
| | | |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.constant.ServiceNameConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import com.xinquan.system.api.factory.RemoteBannerFallbackFactory; |
| | | import java.util.List; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestHeader; |
| | | |
| | | /** |
| | | * 用户服务 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @FeignClient(contextId = "remoteBannerService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteBannerFallbackFactory.class) |
| | | public interface RemoteBannerService { |
| | | |
| | | /** |
| | | * 查询轮播图列表 |
| | | * |
| | | * @param source 请求来源 |
| | | * @return 轮播图列表 |
| | | */ |
| | | @GetMapping("/inner/system/banner/getBannerList") |
| | | R<List<BannerVO>> getBannerList( |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | } |
New file |
| | |
| | | package com.xinquan.system.api; |
| | | |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.constant.ServiceNameConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.factory.RemoteHotWordsFallbackFactory; |
| | | import java.util.List; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestHeader; |
| | | |
| | | /** |
| | | * 用户服务 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @FeignClient(contextId = "remoteHotWordsService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteHotWordsFallbackFactory.class) |
| | | public interface RemoteHotWordsService { |
| | | |
| | | /** |
| | | * 查询热词列表 |
| | | * |
| | | * @param source |
| | | * @return |
| | | */ |
| | | @GetMapping("/inner/system/hot-words/getHotWordList") |
| | | R<List<String>> getHotWordList( |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | } |
| | |
| | | package com.xinquan.system.api.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.xinquan.common.core.annotation.Excel; |
| | | import com.xinquan.common.core.annotation.Excel.ColumnType; |
| | | import com.xinquan.common.core.annotation.Excel.Type; |
| | |
| | | import com.xinquan.common.core.web.domain.BaseEntity; |
| | | import com.xinquan.common.core.xss.Xss; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.util.Date; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | import javax.validation.constraints.Email; |
| | | import javax.validation.constraints.NotBlank; |
| | |
| | | |
| | | /** 用户ID */ |
| | | @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") |
| | | @TableId("user_id") |
| | | @TableField("user_id") |
| | | private Long userId; |
| | | |
| | | /** 部门ID */ |
| | |
| | | @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField("login_date") |
| | | private Date loginDate; |
| | | private LocalDateTime loginDate; |
| | | |
| | | /** 部门对象 */ |
| | | @Excels({ |
| | |
| | | |
| | | @ApiModelProperty(value = "备注") |
| | | private String remark; |
| | | |
| | | @ApiModelProperty(value = "用户类型 00:管理后台用户 01:APP用户") |
| | | private String userType; |
| | | |
| | | public String getUserType() { |
| | | return userType; |
| | | } |
| | | |
| | | public void setUserType(String userType) { |
| | | this.userType = userType; |
| | | } |
| | | |
| | | @Override |
| | | public String getRemark() { |
| | |
| | | this.loginIp = loginIp; |
| | | } |
| | | |
| | | public Date getLoginDate() |
| | | public LocalDateTime getLoginDate() |
| | | { |
| | | return loginDate; |
| | | } |
| | | |
| | | public void setLoginDate(Date loginDate) |
| | | public void setLoginDate(LocalDateTime loginDate) |
| | | { |
| | | this.loginDate = loginDate; |
| | | } |
New file |
| | |
| | | package com.xinquan.system.api.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/7 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "轮播图视图对象") |
| | | public class BannerVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -7433787602665988956L; |
| | | |
| | | @ApiModelProperty(value = "轮播图id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "轮播图") |
| | | private String imageUrl; |
| | | |
| | | @ApiModelProperty(value = "跳转课程id") |
| | | private Integer courseId; |
| | | } |
New file |
| | |
| | | package com.xinquan.system.api.factory; |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.RemoteBannerService; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import java.util.List; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 用户服务降级处理 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class RemoteBannerFallbackFactory implements FallbackFactory<RemoteBannerService> { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(RemoteBannerFallbackFactory.class); |
| | | |
| | | @Override |
| | | public RemoteBannerService create(Throwable cause) { |
| | | return new RemoteBannerService() { |
| | | @Override |
| | | public R<List<BannerVO>> getBannerList(String source) { |
| | | return R.fail("获取轮播图失败:" + cause.getMessage()); |
| | | } |
| | | }; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.system.api.factory; |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.RemoteHotWordsService; |
| | | import java.util.List; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * 用户服务降级处理 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class RemoteHotWordsFallbackFactory implements FallbackFactory<RemoteHotWordsService> { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(RemoteHotWordsFallbackFactory.class); |
| | | |
| | | @Override |
| | | public RemoteHotWordsService create(Throwable cause) { |
| | | return new RemoteHotWordsService() { |
| | | @Override |
| | | public R<List<String>> getHotWordList(String source) { |
| | | return R.fail("获取热词列表失败"); |
| | | } |
| | | }; |
| | | } |
| | | } |
| | |
| | | |
| | | private static final long serialVersionUID = 6079425494597881288L; |
| | | |
| | | @ApiModelProperty(value = "手机号") |
| | | @ApiModelProperty(value = "手机号", required = true) |
| | | @NotBlank(message = "手机号不能为空") |
| | | private String cellPhone; |
| | | |
| | | @ApiModelProperty("验证码") |
| | | @ApiModelProperty(value = "验证码", required = true) |
| | | @NotBlank(message = "验证码不能为空") |
| | | private String captcha; |
| | | } |
File was renamed from xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/WXLoginUser.java |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "微信登录用户信息") |
| | | public class WXLoginUser implements Serializable { |
| | | @ApiModel(value = "APP登录用户信息") |
| | | public class AppLoginUser implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 用户唯一标识 |
| | | */ |
| | | @ApiModelProperty(value = "APP用户id") |
| | | private Long token; |
| | | @ApiModelProperty(value = "用户唯一标识") |
| | | private String token; |
| | | |
| | | /** |
| | | * 用户id |
| | |
| | | @ApiModelProperty(value = "登录IP地址") |
| | | private String ipaddr; |
| | | |
| | | @ApiModelProperty(value = "绑定手机号状态 1=是 2=否") |
| | | @ApiModelProperty(value = "是否需要验证手机号 1=是 2=否") |
| | | private Integer bindStatus = 2; |
| | | |
| | | @ApiModelProperty(value = "用户手机") |
| | | private String cellPhone; |
| | | |
| | | @ApiModelProperty(value = "APP用户id") |
| | | private Long appUserId; |
| | | |
| | | @ApiModelProperty(value = "token") |
| | | private String accessToken; |
| | | |
| | | @ApiModelProperty(value = "token过期时间") |
| | | private Long expireIn; |
| | | /** |
| | | * 系统用户信息 |
| | | */ |
| | | @ApiModelProperty(value = "系统用户信息") |
| | | @ApiModelProperty(value = "系统用户信息", hidden = true) |
| | | private SysUser sysUser; |
| | | |
| | | } |
| | |
| | | |
| | | private static final long serialVersionUID = -6119279151800382508L; |
| | | @NotBlank(message = "微信openid或苹果appleId不能为空") |
| | | @ApiModelProperty(value = "微信openid或苹果appleId") |
| | | @ApiModelProperty(value = "微信openid或苹果appleId", required = true) |
| | | private String wxOrAppleId; |
| | | |
| | | @NotNull(message = "登录类型不能为空") |
| | | @ApiModelProperty(value = "登录类型 1=微信 2=苹果") |
| | | @ApiModelProperty(value = "登录类型 1=微信 2=苹果", required = true) |
| | | private Integer loginType; |
| | | |
| | | } |
| | |
| | | /** |
| | | * 微信openId |
| | | */ |
| | | @ApiModelProperty(value = "微信openId") |
| | | @ApiModelProperty(value = "微信openId", required = true) |
| | | @NotBlank(message = "微信openId不能为空") |
| | | private String wxOpenId; |
| | | |
| | | /** |
| | | * 用户昵称 |
| | | */ |
| | | @ApiModelProperty(value = "用户昵称") |
| | | @ApiModelProperty(value = "用户昵称", required = true) |
| | | @NotBlank(message = "用户昵称不能为空") |
| | | private String nickname; |
| | | |
| | | /** |
| | | * 用户头像 |
| | | */ |
| | | @ApiModelProperty(value = "用户头像") |
| | | @ApiModelProperty(value = "用户头像", required = true) |
| | | @NotBlank(message = "用户头像不能为空") |
| | | private String headImgUrl; |
| | | |
| | | /** |
| | | * 用户头像 |
| | | */ |
| | | @ApiModelProperty(value = "用户性别") |
| | | @ApiModelProperty(value = "用户性别", required = true) |
| | | @NotNull(message = "用户性别不能为空") |
| | | private Integer sex; |
| | | |
| | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ApiModel(value = "苹果登录用户信息") |
| | | public class AppleLoginUser extends WXLoginUser { |
| | | public class AppleLoginUser extends AppLoginUser { |
| | | |
| | | private static final long serialVersionUID = 6891070491318038281L; |
| | | } |
| | |
| | | com.xinquan.system.api.factory.RemoteLogFallbackFactory |
| | | com.xinquan.system.api.factory.RemoteFileFallbackFactory |
| | | com.xinquan.system.api.factory.SysUserFallbackFactory |
| | | com.xinquan.system.api.factory.RemoteHotWordsFallbackFactory |
| | | com.xinquan.system.api.factory.RemoteBannerFallbackFactory |
| | |
| | | @TableField("level_setting_id") |
| | | private Integer levelSettingId; |
| | | |
| | | |
| | | @ApiModelProperty(value = "标签id,多个id使用英文逗号拼接") |
| | | @TableField("tag_id") |
| | | private String tagId; |
| | | } |
| | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * @author mitao |
| | |
| | | */ |
| | | @Data |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AppUserDTO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -3850851853092651572L; |
| | |
| | | |
| | | @ApiModelProperty(value = "用户等级id") |
| | | private Integer levelSettingId; |
| | | |
| | | @ApiModelProperty(value = "首页背景音乐id") |
| | | private Long homeBackgroundMusicId; |
| | | } |
| | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.api.feign.RemoteAppUserService; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public R<Boolean> registerAppUser(AppUserDTO appUserDTO, String source) { |
| | | public R<AppUser> registerAppUser(AppUserDTO appUserDTO, String source) { |
| | | return R.fail("APP用户注册失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<WXLoginUser> wxLogin(AppWXLoginBody body, String inner) { |
| | | public R<AppLoginUser> wxLogin(AppWXLoginBody body, String inner) { |
| | | return R.fail("APP用户微信登录失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<AppleLoginUser> appleLogin(String appleId, String source) { |
| | | public R<AppLoginUser> appleLogin(String appleId, String source) { |
| | | return R.fail("APP用户苹果登录失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<LoginUser> appCaptchaLogin(AppCaptchaBody body, String source) { |
| | | public R<AppLoginUser> appCaptchaLogin(AppCaptchaBody body, String source) { |
| | | return R.fail("APP用户验证码登录失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<WXLoginUser> verifyCellPhone(AppVerifyCellPhoneBody body, String source) { |
| | | public R<AppLoginUser> verifyCellPhone(AppVerifyCellPhoneBody body, |
| | | String source) { |
| | | return R.fail("APP用户微信苹果登录验证手机号失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<?> updateAppUser(AppUserDTO dto, String source) { |
| | | return R.fail("修改APP用户信息失败。"); |
| | | } |
| | | |
| | | @Override |
| | | public R<List<AppUser>> getAppUserList(Collection<Long> appUserIdSet, String source) { |
| | | return R.fail("获取APP用户列表失败。"); |
| | | } |
| | | }; |
| | | } |
| | | } |
| | |
| | | import com.xinquan.common.core.constant.ServiceNameConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.api.factory.RemoteAppUserFallbackFactory; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/registerAppUser") |
| | | R<Boolean> registerAppUser(@RequestBody AppUserDTO appUserDTO, |
| | | R<AppUser> registerAppUser(@RequestBody AppUserDTO appUserDTO, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/wxLogin") |
| | | R<WXLoginUser> wxLogin(@RequestBody AppWXLoginBody body, |
| | | R<AppLoginUser> wxLogin(@RequestBody AppWXLoginBody body, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/appleLogin") |
| | | R<AppleLoginUser> appleLogin(@RequestParam("appleId") String appleId, |
| | | R<AppLoginUser> appleLogin(@RequestParam("appleId") String appleId, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/captchaLogin") |
| | | R<LoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body, |
| | | R<AppLoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/verifyCellPhone") |
| | | R<WXLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body, |
| | | R<AppLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | | * 更新用户信息 |
| | | * |
| | | * @param dto |
| | | * @param source |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/updateAppUser") |
| | | R<?> updateAppUser(@RequestBody AppUserDTO dto, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | |
| | | /** |
| | | * 获取用户列表 |
| | | * |
| | | * @param appUserIdSet 用户id列表 |
| | | * @param source 请求来源 |
| | | * @return |
| | | */ |
| | | @PostMapping("/inner/app-user/getAppUserList") |
| | | R<List<AppUser>> getAppUserList(@RequestBody Collection<Long> appUserIdSet, |
| | | @RequestHeader(SecurityConstants.FROM_SOURCE) String source); |
| | | } |
| | |
| | | import com.xinquan.system.api.domain.SysUser; |
| | | import com.xinquan.system.api.feignClient.SysUserClient; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.util.Date; |
| | | import java.time.LocalDateTime; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import javax.servlet.http.HttpServletRequest; |
| | |
| | | */ |
| | | @ApiOperation(value = "注册账户",tags = {"APP端"}) |
| | | @PostMapping("/app/register") |
| | | public R<?> appRegister(@Validated @RequestBody AppRegisterBody appRegisterBody) |
| | | public R<AppLoginUser> appRegister(@Validated @RequestBody AppRegisterBody appRegisterBody) |
| | | { |
| | | // 用户注册 |
| | | sysLoginService.appRegister(appRegisterBody); |
| | | return R.ok(); |
| | | AppLoginUser appLoginUser = sysLoginService.appRegister(appRegisterBody); |
| | | return R.ok(tokenService.createToken4AppLoginUser(appLoginUser)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @ApiOperation(value = "账号密码登录", tags = {"APP端"}) |
| | | @PostMapping("/app/login") |
| | | public R<?> appLogin(@Validated @RequestBody AppLoginBody body) { |
| | | LoginUser userInfo = sysLoginService.appLogin(body); |
| | | return R.ok(tokenService.createToken(userInfo)); |
| | | public R<AppLoginUser> appLogin(@Validated @RequestBody AppLoginBody body) { |
| | | AppLoginUser appLoginUser = sysLoginService.appLogin(body); |
| | | return R.ok(tokenService.createToken4AppLoginUser(appLoginUser)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @ApiOperation(value = "验证码登录", tags = {"APP端"}) |
| | | @PostMapping("/app/captchaLogin") |
| | | public R<?> appCaptchaLogin(@Validated @RequestBody AppCaptchaBody body) { |
| | | LoginUser userInfo = sysLoginService.appCaptchaLogin(body); |
| | | return R.ok(tokenService.createToken(userInfo)); |
| | | public R<AppLoginUser> appCaptchaLogin(@Validated @RequestBody AppCaptchaBody body) { |
| | | AppLoginUser appLoginUser = sysLoginService.appCaptchaLogin(body); |
| | | return R.ok(tokenService.createToken4AppLoginUser(appLoginUser)); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @ApiOperation(value = "微信登录", tags = {"APP端"}) |
| | | @PostMapping("/app/wxLogin") |
| | | public R<?> thirdLogin(@Validated @RequestBody AppWXLoginBody body) { |
| | | WXLoginUser wxLoginUser = sysLoginService.wxLogin(body); |
| | | return R.ok(tokenService.createToken4WXLoginUser(wxLoginUser)); |
| | | public R<AppLoginUser> thirdLogin(@Validated @RequestBody AppWXLoginBody body) { |
| | | AppLoginUser appLoginUser = sysLoginService.wxLogin(body); |
| | | return R.ok(tokenService.createToken4AppLoginUser(appLoginUser)); |
| | | } |
| | | |
| | | /** |
| | |
| | | @PostMapping("/app/appleLogin") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "appleId", value = "苹果ID", required = true, dataType = "String", paramType = "query")}) |
| | | public R<?> appleLogin(@RequestParam(value = "appleId", required = true) String appleId) { |
| | | AppleLoginUser appleLoginUser = sysLoginService.appleLogin(appleId); |
| | | return R.ok(tokenService.createToken4WXLoginUser(appleLoginUser)); |
| | | public R<AppLoginUser> appleLogin( |
| | | @RequestParam(value = "appleId", required = true) String appleId) { |
| | | AppLoginUser appLoginUser = sysLoginService.appleLogin(appleId); |
| | | return R.ok(tokenService.createToken4AppLoginUser(appLoginUser)); |
| | | } |
| | | |
| | | /** |
| | |
| | | @ApiOperation(value = "微信苹果登录-验证手机号", tags = {"APP端"}) |
| | | @PostMapping("/app/verifyCellPhone") |
| | | public R<?> verifyCellPhone(@Validated @RequestBody AppVerifyCellPhoneBody body) { |
| | | return R.ok(tokenService.createToken4WXLoginUser(sysLoginService.verifyCellPhone(body))); |
| | | return R.ok(tokenService.createToken4AppLoginUser( |
| | | sysLoginService.verifyCellPhone(body))); |
| | | } |
| | | |
| | | /** |
| | |
| | | // 修改用户最后登录时间 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser.setUserId(userInfo.getSysUser().getUserId()); |
| | | sysUser.setLoginDate(new Date()); |
| | | sysUser.setLoginDate(LocalDateTime.now()); |
| | | System.out.println("修改用户登录时间"+sysUser); |
| | | userClient.updateSysUser(sysUser); |
| | | // 获取登录token |
| | |
| | | /** |
| | | * 用户密码 |
| | | */ |
| | | @ApiModelProperty(value = "密码修改秘钥") |
| | | @ApiModelProperty(value = "密码修改秘钥", required = true) |
| | | @NotBlank(message = "密码修改秘钥不能为空") |
| | | private String secret; |
| | | |
| | |
| | | /** |
| | | * 手机号 |
| | | */ |
| | | @ApiModelProperty(value = "手机号") |
| | | @ApiModelProperty(value = "手机号", required = true) |
| | | @NotBlank(message = "手机号不能为空") |
| | | private String cellPhone; |
| | | |
| | | /** |
| | | * 用户密码 |
| | | */ |
| | | @ApiModelProperty(value = "用户密码") |
| | | @ApiModelProperty(value = "用户密码", required = true) |
| | | @NotBlank(message = "密码不能为空") |
| | | private String password; |
| | | |
| | |
| | | |
| | | private static final long serialVersionUID = 438348119520198682L; |
| | | |
| | | @ApiModelProperty(value = "用户密码") |
| | | @ApiModelProperty(value = "用户密码", required = true) |
| | | @NotBlank(message = "用户密码不能为空") |
| | | private String password; |
| | | |
| | |
| | | import com.xinquan.auth.form.AppLoginBody; |
| | | import com.xinquan.auth.form.AppRegisterBody; |
| | | import com.xinquan.auth.form.VerifyResultVO; |
| | | import com.xinquan.auth.util.HuaWeiSMSUtil; |
| | | import com.xinquan.common.core.constant.CacheConstants; |
| | | import com.xinquan.common.core.constant.Constants; |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | |
| | | import com.xinquan.system.api.domain.SysUser; |
| | | import com.xinquan.system.api.feignClient.SysUserClient; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.api.feign.RemoteAppUserService; |
| | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | /** |
| | | * 登录校验方法 |
| | |
| | | /** |
| | | * 注册 |
| | | */ |
| | | public void appRegister(AppRegisterBody appRegisterBody) |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AppLoginUser appRegister(AppRegisterBody appRegisterBody) |
| | | { |
| | | String cellPhone = appRegisterBody.getCellPhone(); |
| | | String password = appRegisterBody.getPassword(); |
| | |
| | | { |
| | | throw new ServiceException("该手机号已注册"); |
| | | } |
| | | |
| | | if (password.length() < UserConstants.PASSWORD_MIN_LENGTH |
| | | || password.length() > UserConstants.PASSWORD_MAX_LENGTH) |
| | | { |
| | | throw new ServiceException("密码长度必须在5到20个字符之间"); |
| | | } |
| | | String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6); |
| | | // 注册用户信息 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser.setUserName(cellPhone); |
| | | sysUser.setUserType("01"); |
| | | sysUser.setNickName(nickname); |
| | | sysUser.setPassword(SecurityUtils.encryptPassword(password)); |
| | | R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser, SecurityConstants.INNER); |
| | |
| | | { |
| | | throw new ServiceException(registerResult.getMsg()); |
| | | } |
| | | sysUser = registerResult.getData(); |
| | | recordLogService.recordLogininfor(cellPhone, Constants.REGISTER, "注册成功"); |
| | | //TODO 默认头像待完善 |
| | | AppUserDTO appUserDTO = AppUserDTO.builder().userId(sysUser.getUserId()).cellPhone(cellPhone) |
| | |
| | | nickname).userStatus(1).sanskritFlag(2).balance(BigDecimal.ZERO) |
| | | .income(BigDecimal.ZERO).totalEnergyValue(0).registerTime( |
| | | LocalDateTime.now()).levelSettingId(1).build(); |
| | | Boolean result = remoteAppUserService.registerAppUser(appUserDTO, SecurityConstants.INNER) |
| | | .getData(); |
| | | if (!result) { |
| | | throw new ServiceException("注册失败"); |
| | | R<AppUser> result = remoteAppUserService.registerAppUser(appUserDTO, |
| | | SecurityConstants.INNER); |
| | | if (R.FAIL == result.getCode()) { |
| | | throw new ServiceException(result.getMsg()); |
| | | } |
| | | |
| | | // 构建AppLoginUser |
| | | SysUser sysUserInfo = registerResult.getData(); |
| | | AppUser appUserInfo = result.getData(); |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | appLoginUser.setUserid(sysUserInfo.getUserId()); |
| | | appLoginUser.setUsername(appUserInfo.getNickname()); |
| | | appLoginUser.setCellPhone(cellPhone); |
| | | appLoginUser.setAppUserId(appUserInfo.getId()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | return appLoginUser; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return true/false |
| | | */ |
| | | private boolean verifyCaptcha(String cellPhone, String captcha, String keyPrefix) { |
| | | |
| | | if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(captcha)) { |
| | | String key = keyPrefix + cellPhone; |
| | | String code = redisService.getCacheObject(key); |
| | | if (StringUtils.isNotBlank(code) && code.equals(captcha)) { |
| | | // 万能验证码 |
| | | if (captcha.equals("123456") || (StringUtils.isNotBlank(code) && code.equals( |
| | | captcha))) { |
| | | redisService.deleteObject(key); |
| | | return true; |
| | | } |
| | |
| | | */ |
| | | public void sendCaptchaCode(String cellPhone, Integer type) { |
| | | String key = getCaptchaCodeByTypePrefix(type); |
| | | Boolean result = redisService.hasKey(key + cellPhone); |
| | | if (result) { |
| | | throw new ServiceException("请勿重复发送验证码"); |
| | | } |
| | | String code = RandomUtil.randomNumbers(6); |
| | | try { |
| | | // 将验证码放入redis |
| | | redisService.setCacheObject(key + cellPhone, code, 5L, |
| | | TimeUnit.MINUTES); |
| | | log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone, code); |
| | | // TODO 修改sender参数及templateId |
| | | HuaWeiSMSUtil.sendSms("[\"" + code + "\"]", cellPhone, "8823121426646", |
| | | "cf1707ec44694627b1b483b0277e12fd"); |
| | | // HuaWeiSMSUtil.sendSms("[\"" + code + "\"]", cellPhone, "8823121426646", |
| | | // "cf1707ec44694627b1b483b0277e12fd"); |
| | | } catch (Exception e) { |
| | | log.error("发送短信失败", e); |
| | | throw new ServiceException("验证码发送失败"); |
| | | } |
| | | //将验证码放入redis |
| | | redisService.setCacheObject(key + cellPhone, code, 5L, |
| | | TimeUnit.MINUTES); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | public LoginUser appLogin(AppLoginBody body) { |
| | | public AppLoginUser appLogin(AppLoginBody body) { |
| | | |
| | | // IP黑名单校验 |
| | | String blackStr = Convert.toStr( |
| | |
| | | } |
| | | // 校验账号密码 |
| | | passwordService.validate(sysUser, body.getPassword()); |
| | | LoginUser userInfo = new LoginUser(); |
| | | userInfo.setSysUser(sysUser); |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | appLoginUser.setAppUserId(appUser.getUserId()); |
| | | appLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | appLoginUser.setUsername(sysUser.getNickName()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, |
| | | "登录成功"); |
| | | return userInfo; |
| | | return appLoginUser; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | public WXLoginUser wxLogin(AppWXLoginBody body) { |
| | | public AppLoginUser wxLogin(AppWXLoginBody body) { |
| | | // 通过wxOpenId查询APP用户信息 |
| | | R<WXLoginUser> userResult = remoteAppUserService.wxLogin(body, SecurityConstants.INNER); |
| | | R<AppLoginUser> userResult = remoteAppUserService.wxLogin(body, |
| | | SecurityConstants.INNER); |
| | | AppLoginUser data = userResult.getData(); |
| | | SysUser sysUser = data.getSysUser(); |
| | | if (R.FAIL == userResult.getCode()) { |
| | | recordLogService.recordLogininfor(body.getNickname(), Constants.LOGIN_FAIL, |
| | | userResult.getMsg()); |
| | | throw new ServiceException(userResult.getMsg()); |
| | | } |
| | | if (StringUtils.isNull(sysUser)) { |
| | | recordLogService.recordLogininfor(data.getCellPhone(), Constants.LOGIN_FAIL, |
| | | "登录用户不存在"); |
| | | throw new ServiceException("登录用户:" + data.getCellPhone() + " 不存在"); |
| | | } |
| | | // IP黑名单校验 |
| | | String blackStr = Convert.toStr( |
| | | redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); |
| | | if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { |
| | | recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, |
| | | "很遗憾,访问IP已被列入系统黑名单"); |
| | | throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); |
| | | } |
| | | |
| | | return userResult.getData(); |
| | | recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, |
| | | "登录成功"); |
| | | return data; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param appleId 苹果id |
| | | * @return |
| | | */ |
| | | public AppleLoginUser appleLogin(String appleId) { |
| | | R<AppleLoginUser> userResult = remoteAppUserService.appleLogin(appleId, |
| | | public AppLoginUser appleLogin(String appleId) { |
| | | R<AppLoginUser> userResult = remoteAppUserService.appleLogin(appleId, |
| | | SecurityConstants.INNER); |
| | | if (R.FAIL == userResult.getCode()) { |
| | | throw new ServiceException(userResult.getMsg()); |
| | | } |
| | | return userResult.getData(); |
| | | AppLoginUser data = userResult.getData(); |
| | | SysUser sysUser = data.getSysUser(); |
| | | if (StringUtils.isNull(sysUser)) { |
| | | recordLogService.recordLogininfor(data.getCellPhone(), Constants.LOGIN_FAIL, |
| | | "登录用户不存在"); |
| | | throw new ServiceException("登录用户:" + data.getCellPhone() + " 不存在"); |
| | | } |
| | | // IP黑名单校验 |
| | | String blackStr = Convert.toStr( |
| | | redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); |
| | | if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { |
| | | recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, |
| | | "很遗憾,访问IP已被列入系统黑名单"); |
| | | throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); |
| | | } |
| | | recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, |
| | | "登录成功"); |
| | | return data; |
| | | } |
| | | |
| | | /** |
| | |
| | | if (!body.getSecret().equals(baseSecret.toString())) { |
| | | throw new ServiceException("密码修改秘钥不正确"); |
| | | } |
| | | // 校验密码,密码至少8个字符,不能全是字母或者数字 |
| | | String regex = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$\n"; |
| | | Pattern pattern = Pattern.compile(regex); |
| | | Matcher matcher = pattern.matcher(body.getPassword()); |
| | | if (!matcher.matches()) { |
| | | throw new ServiceException("密码至少8个字符,不能全是字母或者数字"); |
| | | } |
| | | // 根据手机号查询用户 |
| | | AppUser appUser = remoteAppUserService.getUserByCondition( |
| | | AppUserDTO.builder().cellPhone(body.getCellPhone()).build(), |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | public LoginUser appCaptchaLogin(AppCaptchaBody body) { |
| | | public AppLoginUser appCaptchaLogin(AppCaptchaBody body) { |
| | | // 校验验证码 |
| | | if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), |
| | | CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) { |
| | | throw new ServiceException("验证码不正确"); |
| | | } |
| | | R<LoginUser> loginUserR = remoteAppUserService.appCaptchaLogin(body, |
| | | R<AppLoginUser> loginUserR = remoteAppUserService.appCaptchaLogin(body, |
| | | SecurityConstants.INNER); |
| | | if (R.FAIL == loginUserR.getCode()) { |
| | | throw new ServiceException(loginUserR.getMsg()); |
| | |
| | | return loginUserR.getData(); |
| | | } |
| | | |
| | | public WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { |
| | | String captcha = redisService.getCacheObject( |
| | | public AppLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { |
| | | Boolean res = redisService.hasKey( |
| | | CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone()); |
| | | if (Objects.isNull(captcha)) { |
| | | if (!res) { |
| | | throw new ServiceException("验证码已失效,请重新获取"); |
| | | } |
| | | // 校验验证码 |
| | | if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(), |
| | | CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) { |
| | | CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX)) { |
| | | throw new ServiceException("验证码不正确"); |
| | | } |
| | | // 更新用户系统用户信息 |
| | | R<WXLoginUser> result = remoteAppUserService.verifyCellPhone(body, SecurityConstants.INNER); |
| | | R<AppLoginUser> result = remoteAppUserService.verifyCellPhone(body, |
| | | SecurityConstants.INNER); |
| | | if (R.FAIL == result.getCode()) { |
| | | throw new ServiceException(result.getMsg()); |
| | | } |
| | |
| | | <version>2.8.0</version> |
| | | </dependency> |
| | | |
| | | <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | |
| | | * 权限缓存前缀 |
| | | */ |
| | | public final static String LOGIN_TOKEN_KEY = "login_tokens:"; |
| | | /** |
| | | * APP用户登录token缓存前缀 |
| | | */ |
| | | public final static String APP_USER_LOGIN_TOKEN_KEY = "app_login_tokens:"; |
| | | |
| | | /** |
| | | * 验证码 redis key |
| | |
| | | package com.xinquan.common.core.domain; |
| | | |
| | | import java.io.Serializable; |
| | | import com.xinquan.common.core.constant.Constants; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 响应信息主体 |
| | |
| | | /** 失败 */ |
| | | public static final int FAIL = Constants.FAIL; |
| | | |
| | | @ApiModelProperty(value = "业务状态码,200-成功,其它-失败") |
| | | private int code; |
| | | |
| | | @ApiModelProperty(value = "响应消息", example = "操作成功") |
| | | private String msg; |
| | | |
| | | |
| | | @ApiModelProperty(value = "响应数据") |
| | | private T data; |
| | | |
| | | public static <T> R<T> ok() |
New file |
| | |
| | | package com.xinquan.common.core.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum AnswerEnum { |
| | | YES("1", "是"), |
| | | NO("2", "否"), |
| | | SOMETIMES("3", "偶尔有"); |
| | | |
| | | private final String code; |
| | | private final String desc; |
| | | |
| | | public static AnswerEnum getEnumByCode(String code) { |
| | | for (AnswerEnum e : AnswerEnum.values()) { |
| | | if (e.code.equals(code)) { |
| | | return e; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.common.core.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum AnswerTagEnum { |
| | | |
| | | QUESTION_ONE(1, 1L, "您是否内心纠结敏感多疑?"), |
| | | QUESTION_TWO(2, 2L, "您是否辗转反侧彻夜难眠?"), |
| | | QUESTION_THREE(3, 3L, "您是否情绪失控暴躁易怒?"), |
| | | QUESTION_FOUR(4, 4L, "您是否沉迷情感倍受伤害?"), |
| | | QUESTION_FIVE(5, 5L, "您是否人生迷茫踌躇彷徨?"); |
| | | |
| | | private final Integer code; |
| | | private final Long tagId; |
| | | private final String desc; |
| | | |
| | | public static AnswerTagEnum getEnumByCode(Integer code) { |
| | | for (AnswerTagEnum e : AnswerTagEnum.values()) { |
| | | if (e.getCode().equals(code)) { |
| | | return e; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.common.core.enums; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum ReportStatusEnum { |
| | | NOT_REPORTED(1, "未被举报"), |
| | | REPORTED(2, "已被举报"); |
| | | |
| | | private final Integer code; |
| | | private final String desc; |
| | | |
| | | public static ReportStatusEnum getEnumByCode(Integer code) { |
| | | for (ReportStatusEnum e : ReportStatusEnum.values()) { |
| | | if (e.code.equals(code)) { |
| | | return e; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.common.core.utils; |
| | | |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.OutputStream; |
| | | |
| | | public class Base64DES { |
| | | |
| | | private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); |
| | | |
| | | public static String encode(byte[] data) { |
| | | |
| | | int start = 0; |
| | | int len = data.length; |
| | | StringBuffer buf = new StringBuffer(data.length * 3 / 2); |
| | | int end = len - 3; |
| | | int i = start; |
| | | int n = 0; |
| | | while (i <= end) { |
| | | int d = ((((int) data[i]) & 0x0ff) << 16) |
| | | | ((((int) data[i + 1]) & 0x0ff) << 8) |
| | | | (((int) data[i + 2]) & 0x0ff); |
| | | |
| | | buf.append(legalChars[(d >> 18) & 63]); |
| | | buf.append(legalChars[(d >> 12) & 63]); |
| | | buf.append(legalChars[(d >> 6) & 63]); |
| | | buf.append(legalChars[d & 63]); |
| | | i += 3; |
| | | if (n++ >= 14) { |
| | | n = 0; |
| | | buf.append(" "); |
| | | } |
| | | } |
| | | if (i == start + len - 2) { |
| | | int d = ((((int) data[i]) & 0x0ff) << 16) |
| | | | ((((int) data[i + 1]) & 255) << 8); |
| | | |
| | | buf.append(legalChars[(d >> 18) & 63]); |
| | | buf.append(legalChars[(d >> 12) & 63]); |
| | | buf.append(legalChars[(d >> 6) & 63]); |
| | | buf.append("="); |
| | | |
| | | } else if (i == start + len - 1) { |
| | | int d = (((int) data[i]) & 0x0ff) << 16; |
| | | buf.append(legalChars[(d >> 18) & 63]); |
| | | buf.append(legalChars[(d >> 12) & 63]); |
| | | buf.append("=="); |
| | | } |
| | | return buf.toString(); |
| | | } |
| | | |
| | | public static byte[] decode(String s) { |
| | | |
| | | ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| | | |
| | | try { |
| | | |
| | | decode(s, bos); |
| | | |
| | | } catch (IOException e) { |
| | | |
| | | throw new RuntimeException(); |
| | | |
| | | } |
| | | |
| | | byte[] decodedBytes = bos.toByteArray(); |
| | | |
| | | try { |
| | | |
| | | bos.close(); |
| | | |
| | | // bos = null; |
| | | |
| | | } catch (IOException ex) { |
| | | |
| | | System.err.println("Error while decoding BASE64: " + ex.toString()); |
| | | |
| | | } |
| | | |
| | | return decodedBytes; |
| | | |
| | | } |
| | | |
| | | private static void decode(String s, OutputStream os) throws IOException { |
| | | |
| | | int i = 0; |
| | | |
| | | int len = s.length(); |
| | | |
| | | while (true) { |
| | | |
| | | while (i < len && s.charAt(i) <= ' ') { |
| | | i++; |
| | | } |
| | | if (i == len) { |
| | | break; |
| | | } |
| | | |
| | | int tri = (decode(s.charAt(i)) << 18) |
| | | + (decode(s.charAt(i + 1)) << 12) |
| | | |
| | | + (decode(s.charAt(i + 2)) << 6) |
| | | |
| | | + (decode(s.charAt(i + 3))); |
| | | |
| | | os.write((tri >> 16) & 255); |
| | | |
| | | if (s.charAt(i + 2) == '=') { |
| | | break; |
| | | } |
| | | |
| | | os.write((tri >> 8) & 255); |
| | | |
| | | if (s.charAt(i + 3) == '=') { |
| | | break; |
| | | } |
| | | os.write(tri & 255); |
| | | i += 4; |
| | | } |
| | | } |
| | | |
| | | private static int decode(char c) { |
| | | |
| | | if (c >= 'A' && c <= 'Z') { |
| | | return ((int) c) - 65; |
| | | } else if (c >= 'a' && c <= 'z') { |
| | | return ((int) c) - 97 + 26; |
| | | } else if (c >= '0' && c <= '9') { |
| | | return ((int) c) - 48 + 26 + 26; |
| | | } else { |
| | | switch (c) { |
| | | |
| | | case '+': |
| | | |
| | | return 62; |
| | | |
| | | case '/': |
| | | |
| | | return 63; |
| | | |
| | | case '=': |
| | | |
| | | return 0; |
| | | |
| | | default: |
| | | |
| | | throw new RuntimeException("unexpected code: " + c); |
| | | |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.common.core.utils; |
| | | |
| | | import java.net.URLDecoder; |
| | | import java.net.URLEncoder; |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.spec.IvParameterSpec; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | |
| | | public class DES { |
| | | |
| | | /* |
| | | * 不要写成:Cipher cipher = Cipher.getInstance("DES"); |
| | | * 或:Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding"); |
| | | * 原因是Cipher cipher = Cipher.getInstance("DES"); |
| | | * 与Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); |
| | | * 等同,填充方式错误,加密的时候会得到16长度的字节数组。 |
| | | * 应该写成 |
| | | * Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding"); |
| | | */ |
| | | |
| | | |
| | | private static final String KEY = "hfh7L4nUzKcnK6JtJ5z27ygad5p9EanZn5wCT6Zw9KvctK5hs7Z8FsjDEpShmC5W"; |
| | | |
| | | private static byte[] iv = {25, 24, 40, 41, 60, 68, 70, 97}; |
| | | |
| | | |
| | | /** |
| | | * 指定密钥加密 |
| | | * |
| | | * @param encryptString 原文 |
| | | * @param encryptKey 密钥 |
| | | * @return 密文 |
| | | * @throws Exception |
| | | */ |
| | | public static String encryptDES(String encryptString, String encryptKey) |
| | | throws Exception { |
| | | |
| | | IvParameterSpec zeroIv = new IvParameterSpec(iv); |
| | | |
| | | SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | |
| | | cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); |
| | | |
| | | byte[] encryptedData = cipher.doFinal(encryptString.getBytes()); |
| | | |
| | | return Base64DES.encode(encryptedData); |
| | | } |
| | | |
| | | /** |
| | | * 指定密钥进行解密 |
| | | * |
| | | * @param decryptString 密文 |
| | | * @param decryptKey 密钥 |
| | | * @return 原文 |
| | | * @throws Exception |
| | | */ |
| | | public static String decryptDES(String decryptString, String decryptKey) |
| | | throws Exception { |
| | | |
| | | byte[] byteMi = Base64DES.decode(decryptString); |
| | | |
| | | IvParameterSpec zeroIv = new IvParameterSpec(iv); |
| | | |
| | | SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | |
| | | cipher.init(Cipher.DECRYPT_MODE, key, zeroIv); |
| | | |
| | | byte decryptedData[] = cipher.doFinal(byteMi); |
| | | |
| | | return new String(decryptedData); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 默认密钥加密 |
| | | * |
| | | * @param encryptString 原文 |
| | | * @return 密文 |
| | | * @throws Exception |
| | | */ |
| | | public static String encryptDES(String encryptString) |
| | | throws Exception { |
| | | |
| | | IvParameterSpec zeroIv = new IvParameterSpec(iv); |
| | | |
| | | SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "DES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | |
| | | cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); |
| | | |
| | | byte[] encryptedData = cipher.doFinal(encryptString.getBytes()); |
| | | |
| | | return Base64DES.encode(encryptedData); |
| | | } |
| | | |
| | | /** |
| | | * 默认密钥解密 |
| | | * |
| | | * @param decryptString 密文 |
| | | * @return 解密得到的原文 |
| | | * @throws Exception |
| | | */ |
| | | public static String decryptDES(String decryptString) |
| | | throws Exception { |
| | | |
| | | byte[] byteMi = Base64DES.decode(decryptString); |
| | | |
| | | IvParameterSpec zeroIv = new IvParameterSpec(iv); |
| | | |
| | | SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "DES"); |
| | | |
| | | Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); |
| | | |
| | | cipher.init(Cipher.DECRYPT_MODE, key, zeroIv); |
| | | |
| | | byte decryptedData[] = cipher.doFinal(byteMi); |
| | | |
| | | return new String(decryptedData, "UTF-8"); |
| | | |
| | | } |
| | | |
| | | public static String parseByte2HexStr(byte buf[]) { |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (int i = 0; i < buf.length; i++) { |
| | | String hex = Integer.toHexString(buf[i] & 0xFF); |
| | | if (hex.length() == 1) { |
| | | hex = '0' + hex; |
| | | } |
| | | sb.append(hex.toUpperCase()); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | String plaintext = "server=/app/public/getAllRegionList"; |
| | | try { |
| | | System.out.println("明文:" + plaintext); |
| | | System.out.println("密钥:" + KEY); |
| | | System.out.println("DES密文:" + DES.encryptDES(plaintext)); |
| | | System.out.println("DES解密:" + DES.decryptDES(DES.encryptDES(plaintext))); |
| | | |
| | | System.out.println( |
| | | "URLEncoder加密:" + URLEncoder.encode(DES.encryptDES(plaintext), "UTF-8")); |
| | | System.out.println("URLEncoder解密:" + URLDecoder.decode( |
| | | URLEncoder.encode(DES.encryptDES(plaintext), "UTF-8"), "UTF-8")); |
| | | System.out.println("长度:" |
| | | + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".length()); |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.xinquan.common.core.web.domain; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import com.xinquan.common.core.annotation.Excel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Entity基类 |
| | |
| | | /** 创建时间 */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField("create_time") |
| | | private Date createTime; |
| | | private LocalDateTime createTime; |
| | | |
| | | /** 更新者 */ |
| | | @ApiModelProperty(value = "记录修改人,前端忽略") |
| | |
| | | /** 更新时间 */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField("update_time") |
| | | private Date updateTime; |
| | | private LocalDateTime updateTime; |
| | | |
| | | /** 是否删除 1未删除 0已删除 */ |
| | | @TableLogic |
| | |
| | | this.createBy = createBy; |
| | | } |
| | | |
| | | public Date getCreateTime() |
| | | { |
| | | return createTime; |
| | | } |
| | | |
| | | public void setCreateTime(Date createTime) |
| | | { |
| | | this.createTime = createTime; |
| | | } |
| | | |
| | | public String getUpdateBy() |
| | | { |
| | | return updateBy; |
| | |
| | | this.updateBy = updateBy; |
| | | } |
| | | |
| | | public Date getUpdateTime() |
| | | { |
| | | public LocalDateTime getCreateTime() { |
| | | return createTime; |
| | | } |
| | | |
| | | public void setCreateTime(LocalDateTime createTime) { |
| | | this.createTime = createTime; |
| | | } |
| | | |
| | | public LocalDateTime getUpdateTime() { |
| | | return updateTime; |
| | | } |
| | | |
| | | public void setUpdateTime(Date updateTime) |
| | | { |
| | | public void setUpdateTime(LocalDateTime updateTime) { |
| | | this.updateTime = updateTime; |
| | | } |
| | | |
| | |
| | | import com.xinquan.common.core.utils.uuid.IdUtils; |
| | | import com.xinquan.common.redis.service.RedisService; |
| | | import com.xinquan.common.security.utils.SecurityUtils; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | |
| | | private final static long expireTime = CacheConstants.EXPIRATION; |
| | | |
| | | private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY; |
| | | private final static String APP_USER_ACCESS_TOKEN = CacheConstants.APP_USER_LOGIN_TOKEN_KEY; |
| | | |
| | | private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE; |
| | | |
| | |
| | | redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); |
| | | } |
| | | |
| | | private void refreshToken4AppLoginUser(AppLoginUser appLoginUser) { |
| | | appLoginUser.setLoginTime(System.currentTimeMillis()); |
| | | appLoginUser.setExpireTime(appLoginUser.getLoginTime() + expireTime * MILLIS_MINUTE); |
| | | // 根据uuid将loginUser缓存 |
| | | String userKey = getTokenKeyByAppLoginUser(appLoginUser.getToken()); |
| | | redisService.setCacheObject(userKey, appLoginUser, expireTime, TimeUnit.MINUTES); |
| | | } |
| | | |
| | | private String getTokenKeyByAppLoginUser(String token) { |
| | | return APP_USER_ACCESS_TOKEN + token; |
| | | } |
| | | |
| | | private String getTokenKey(String token) |
| | | { |
| | | return ACCESS_TOKEN + token; |
| | | } |
| | | |
| | | public Map<String, Object> createToken4WXLoginUser(WXLoginUser wxLoginUser) { |
| | | LoginUser loginUser = new LoginUser(); |
| | | /** |
| | | * app用户创建token |
| | | * |
| | | * @param appLoginUser |
| | | * @return |
| | | */ |
| | | public AppLoginUser createToken4AppLoginUser(AppLoginUser appLoginUser) { |
| | | // Jwt存储信息 |
| | | Map<String, Object> claimsMap = new HashMap<String, Object>(); |
| | | // 接口返回信息 |
| | | Map<String, Object> rspMap = new HashMap<String, Object>(); |
| | | // 用户为空只返回openid |
| | | rspMap.put("cellPhone", ""); |
| | | rspMap.put("access_token", ""); |
| | | if (wxLoginUser.getSysUser() != null) { |
| | | loginUser.setSysUser(wxLoginUser.getSysUser()); |
| | | String token = IdUtils.fastUUID(); |
| | | Long userId = loginUser.getSysUser().getUserId(); |
| | | String userName = loginUser.getSysUser().getUserName(); |
| | | loginUser.setToken(token); |
| | | loginUser.setUserid(userId); |
| | | loginUser.setIpaddr(IpUtils.getIpAddr()); |
| | | refreshToken(loginUser); |
| | | claimsMap.put(SecurityConstants.USER_KEY, token); |
| | | claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); |
| | | claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); |
| | | if (StringUtils.isNotBlank(wxLoginUser.getCellPhone())) { |
| | | rspMap.put("cellPhone", wxLoginUser.getCellPhone()); |
| | | } else { |
| | | rspMap.put("cellPhone", ""); |
| | | } |
| | | rspMap.put("access_token", JwtUtils.createToken(claimsMap)); |
| | | rspMap.put("expires_in", expireTime); |
| | | } |
| | | return rspMap; |
| | | String token = IdUtils.fastUUID(); |
| | | Long userId = appLoginUser.getAppUserId(); |
| | | String userName = appLoginUser.getSysUser().getNickName(); |
| | | appLoginUser.setToken(token); |
| | | appLoginUser.setUserid(userId); |
| | | appLoginUser.setIpaddr(IpUtils.getIpAddr()); |
| | | LoginUser loginUser = new LoginUser(); |
| | | loginUser.setSysUser(appLoginUser.getSysUser()); |
| | | loginUser.setToken(token); |
| | | loginUser.setUserid(userId); |
| | | loginUser.setUsername(userName); |
| | | loginUser.setIpaddr(IpUtils.getIpAddr()); |
| | | refreshToken(loginUser); |
| | | // refreshToken4AppLoginUser(appLoginUser); |
| | | claimsMap.put(SecurityConstants.USER_KEY, token); |
| | | claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); |
| | | claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); |
| | | appLoginUser.setAccessToken(JwtUtils.createToken(claimsMap)); |
| | | appLoginUser.setExpireIn(expireTime); |
| | | return appLoginUser; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | package com.xinquan.gateway.filter; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
| | | import org.springframework.cloud.gateway.filter.GlobalFilter; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.http.server.reactive.ServerHttpRequest; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.server.ServerWebExchange; |
| | | import com.xinquan.common.core.constant.CacheConstants; |
| | | import com.xinquan.common.core.constant.HttpStatus; |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | |
| | | import com.xinquan.common.redis.service.RedisService; |
| | | import com.xinquan.gateway.config.properties.IgnoreWhiteProperties; |
| | | import io.jsonwebtoken.Claims; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
| | | import org.springframework.cloud.gateway.filter.GlobalFilter; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.http.server.reactive.ServerHttpRequest; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.server.ServerWebExchange; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | /** |
| | |
| | | return chain.filter(exchange.mutate().request(mutate.build()).build()); |
| | | } |
| | | |
| | | private String getAppUserTokenKey(String userkey) { |
| | | return CacheConstants.APP_USER_LOGIN_TOKEN_KEY + userkey; |
| | | } |
| | | |
| | | private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) |
| | | { |
| | | if (value == null) |
| | |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>cn.afterturn</groupId> |
| | | <artifactId>easypoi-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>guava</artifactId> |
| | | <groupId>com.google.guava</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | package com.xinquan.course.controller.client; |
| | | |
| | | |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.course.domain.vo.ClientCourseCategoryVO; |
| | | import com.xinquan.course.domain.vo.ClientCourseVO; |
| | | import com.xinquan.course.service.CourseCategoryService; |
| | | import com.xinquan.course.service.CourseService; |
| | | import com.xinquan.system.api.RemoteBannerService; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Api(tags = {"用户端-课程相关接口"}) |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/client/course/course") |
| | | public class ClientCourseController { |
| | | |
| | | private final CourseCategoryService courseCategoryService; |
| | | private final CourseService courseService; |
| | | private final RemoteBannerService remoteBannerService; |
| | | |
| | | /** |
| | | * 获取轮播图列表 |
| | | * |
| | | * @return 轮播图列表 |
| | | */ |
| | | @GetMapping("/getBannerList") |
| | | @ApiOperation(value = "获取轮播图列表") |
| | | public R<List<BannerVO>> getBannerList() { |
| | | return remoteBannerService.getBannerList(SecurityConstants.INNER); |
| | | } |
| | | |
| | | /** |
| | | * 获取课程分类列表 |
| | | * |
| | | * @return 课程分类列表 |
| | | */ |
| | | @GetMapping("/getCourseCategoryList") |
| | | @ApiOperation(value = "获取课程分类列表") |
| | | public R<List<ClientCourseCategoryVO>> getCourseCategoryList() { |
| | | return R.ok(courseCategoryService.getCourseCategoryList()); |
| | | } |
| | | |
| | | /** |
| | | * 获取课程列表-分页 |
| | | * |
| | | * @param courseTitle 课程标题 |
| | | * @param cateId 分类id |
| | | * @param pageCurr 分页参数,当前页码 |
| | | * @param pageSize 分页参数,每页数量 |
| | | * @return 课程分页列表 |
| | | */ |
| | | @PostMapping("/getCoursePageList") |
| | | @ApiOperation(value = "获取课程列表-分页") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "课程标题", name = "courseTitle", required = false, dataType = "String"), |
| | | @ApiImplicitParam(value = "课程分类id", name = "cateId", required = false, dataType = "Long"), |
| | | @ApiImplicitParam(value = "分页参数,当前页码", name = "pageCurr", required = true, dataType = "Integer"), |
| | | @ApiImplicitParam(value = "分页参数,每页数量", name = "pageSize", required = true, dataType = "Integer") |
| | | }) |
| | | public R<PageDTO<ClientCourseVO>> getCourseList( |
| | | @RequestParam(defaultValue = "", value = "courseTitle", required = false) String courseTitle, |
| | | @RequestParam(required = false) Long cateId, |
| | | @RequestParam(value = "pageCurr", defaultValue = "1") Integer pageCurr, |
| | | @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { |
| | | return R.ok(courseService.getCoursePageList(courseTitle, cateId, pageCurr, pageSize)); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.course.controller.inner; |
| | | |
| | | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户学习记录 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/inner/course/course-learning-record") |
| | | public class InnerCourseLearningRecordController { |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.course.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户学习记录 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("t_course_learning_record") |
| | | @ApiModel(value = "CourseLearningRecord对象", description = "用户学习记录") |
| | | public class CourseLearningRecord extends BaseModel { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "用户树苗id") |
| | | @TableId("id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "用户id") |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | @ApiModelProperty(value = "课程id ") |
| | | @TableField("course_id") |
| | | private Long courseId; |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.course.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/7 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "课程分类视图对象") |
| | | public class ClientCourseCategoryVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 6293214581320328382L; |
| | | |
| | | @ApiModelProperty(value = "id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "分类名称") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "分类图片") |
| | | private String imageUrl; |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.course.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/7 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "课程视图对象") |
| | | public class ClientCourseVO { |
| | | |
| | | @ApiModelProperty(value = "课程id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "课程类型 1=线上课程 2=线下课程") |
| | | private Integer courseType; |
| | | |
| | | @ApiModelProperty(value = "课程分类id") |
| | | private Long cateId; |
| | | |
| | | @ApiModelProperty(value = "课程标题") |
| | | private String courseTitle; |
| | | |
| | | @ApiModelProperty(value = "课程描述") |
| | | private String description; |
| | | |
| | | @ApiModelProperty(value = "上架状态 1=上架 2=下架") |
| | | private Integer listingStatus; |
| | | |
| | | @ApiModelProperty(value = "推荐课程 1=推荐 2=不推荐") |
| | | private Integer recommend; |
| | | |
| | | @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费") |
| | | private Integer chargeType; |
| | | |
| | | @ApiModelProperty(value = "排序权重") |
| | | private Integer sortNum; |
| | | |
| | | @ApiModelProperty(value = "导师") |
| | | private String tutor; |
| | | |
| | | @ApiModelProperty(value = "列表封面图") |
| | | private String coverUrl; |
| | | |
| | | @ApiModelProperty(value = "详情页封面图|详情页视频") |
| | | private String detailUrl; |
| | | |
| | | @ApiModelProperty(value = "课程简介") |
| | | private String briefIntroduction; |
| | | |
| | | @ApiModelProperty(value = "微信二维码") |
| | | private String wxQrCode; |
| | | |
| | | @ApiModelProperty(value = "课程地址") |
| | | private String address; |
| | | |
| | | @ApiModelProperty(value = "详细地址") |
| | | private String addressDetail; |
| | | |
| | | @ApiModelProperty(value = "课程地址经度") |
| | | private Double longitude; |
| | | |
| | | @ApiModelProperty(value = "课程地址纬度") |
| | | private Double latitude; |
| | | } |
New file |
| | |
| | | package com.xinquan.course.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xinquan.course.domain.CourseLearningRecord; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户学习记录 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface CourseLearningRecordMapper extends BaseMapper<CourseLearningRecord> { |
| | | |
| | | } |
| | |
| | | package com.xinquan.course.service; |
| | | |
| | | import com.xinquan.course.domain.CourseCategory; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.course.domain.CourseCategory; |
| | | import com.xinquan.course.domain.vo.ClientCourseCategoryVO; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface CourseCategoryService extends IService<CourseCategory> { |
| | | |
| | | /** |
| | | * 获取课程分类列表 |
| | | * |
| | | * @return 课程分类列表 |
| | | */ |
| | | List<ClientCourseCategoryVO> getCourseCategoryList(); |
| | | } |
New file |
| | |
| | | package com.xinquan.course.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.course.domain.CourseLearningRecord; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户学习记录 服务类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface CourseLearningRecordService extends IService<CourseLearningRecord> { |
| | | |
| | | } |
| | |
| | | package com.xinquan.course.service; |
| | | |
| | | import com.xinquan.course.domain.Course; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.course.domain.Course; |
| | | import com.xinquan.course.domain.vo.ClientCourseVO; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface CourseService extends IService<Course> { |
| | | |
| | | /** |
| | | * 获取课程列表-分页 |
| | | * |
| | | * @param courseTitle 课程标题 |
| | | * @param cateId 分类id |
| | | * @param pageCurr 分页参数,当前页码 |
| | | * @param pageSize 分页参数,每页数量 |
| | | * @return 课程分页列表 |
| | | */ |
| | | PageDTO<ClientCourseVO> getCoursePageList(String courseTitle, Long cateId, Integer pageCurr, |
| | | Integer pageSize); |
| | | } |
| | |
| | | package com.xinquan.course.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.enums.DisabledEnum; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.course.domain.CourseCategory; |
| | | import com.xinquan.course.domain.vo.ClientCourseCategoryVO; |
| | | import com.xinquan.course.mapper.CourseCategoryMapper; |
| | | import com.xinquan.course.service.CourseCategoryService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import java.util.List; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class CourseCategoryServiceImpl extends ServiceImpl<CourseCategoryMapper, CourseCategory> implements CourseCategoryService { |
| | | |
| | | /** |
| | | * 获取课程分类列表 |
| | | * |
| | | * @return 课程分类列表 |
| | | */ |
| | | @Override |
| | | public List<ClientCourseCategoryVO> getCourseCategoryList() { |
| | | List<CourseCategory> list = this.lambdaQuery() |
| | | .eq(CourseCategory::getShowOnCourseHomepage, DisabledEnum.YES.getCode()) |
| | | .list(); |
| | | return BeanUtils.copyList(list, ClientCourseCategoryVO.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.course.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.course.domain.CourseLearningRecord; |
| | | import com.xinquan.course.mapper.CourseLearningRecordMapper; |
| | | import com.xinquan.course.service.CourseLearningRecordService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户学习记录 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Service |
| | | public class CourseLearningRecordServiceImpl extends |
| | | ServiceImpl<CourseLearningRecordMapper, CourseLearningRecord> implements |
| | | CourseLearningRecordService { |
| | | |
| | | } |
| | |
| | | package com.xinquan.course.service.impl; |
| | | |
| | | import com.alibaba.nacos.common.utils.StringUtils; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.utils.page.CollUtils; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.course.domain.Course; |
| | | import com.xinquan.course.domain.vo.ClientCourseVO; |
| | | import com.xinquan.course.mapper.CourseMapper; |
| | | import com.xinquan.course.service.CourseService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import java.util.Objects; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService { |
| | | |
| | | /** |
| | | * 获取课程列表-分页 |
| | | * |
| | | * @param courseTitle 课程标题 |
| | | * @param cateId 分类id |
| | | * @param pageCurr 分页参数,当前页码 |
| | | * @param pageSize 分页参数,每页数量 |
| | | * @return 课程分页列表 |
| | | */ |
| | | @Override |
| | | public PageDTO<ClientCourseVO> getCoursePageList(String courseTitle, Long cateId, |
| | | Integer pageCurr, Integer pageSize) { |
| | | Page<Course> page = this.lambdaQuery() |
| | | .like(StringUtils.isNotBlank(courseTitle), Course::getCourseTitle, courseTitle) |
| | | .eq(Objects.nonNull(cateId), Course::getCateId, cateId) |
| | | .orderByDesc(Course::getSortNum) |
| | | .page(new Page<>(pageCurr, pageSize)); |
| | | if (CollUtils.isEmpty(page.getRecords())) { |
| | | return PageDTO.empty(page); |
| | | } |
| | | return PageDTO.of(page, ClientCourseVO.class); |
| | | } |
| | | } |
copy from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml
copy to xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseCategoryMapper.xml
File was copied from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserOperationMapper"> |
| | | <mapper namespace="com.xinquan.course.mapper.CourseCategoryMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserOperation"> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.CourseCategory"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="like" property="like" /> |
| | | <result column="favorite" property="favorite" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="name" property="name" /> |
| | | <result column="image_url" property="imageUrl" /> |
| | | <result column="sort_num" property="sortNum" /> |
| | | <result column="show_on_course_homepage" property="showOnCourseHomepage" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, like, favorite, meditation_id, app_user_id |
| | | id, name, image_url, sort_num, show_on_course_homepage |
| | | </sql> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.course.mapper.CourseChapterMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.CourseChapter"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="course_id" property="courseId" /> |
| | | <result column="chapter_title" property="chapterTitle" /> |
| | | <result column="sort_num" property="sortNum" /> |
| | | <result column="video_url" property="videoUrl" /> |
| | | <result column="real_learned_num" property="realLearnedNum" /> |
| | | <result column="virtual_learned_num" property="virtualLearnedNum" /> |
| | | <result column="duration" property="duration" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | del_flag, |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, course_id, chapter_title, sort_num, video_url, real_learned_num, virtual_learned_num, duration |
| | | </sql> |
| | | |
| | | </mapper> |
copy from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml
copy to xinquan-modules/xinquan-course/src/main/resources/mapper/course/CourseLearningRecordMapper.xml
File was copied from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserOperationMapper"> |
| | | <mapper namespace="com.xinquan.course.mapper.CourseLearningRecordMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserOperation"> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.CourseLearningRecord"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="like" property="like" /> |
| | | <result column="favorite" property="favorite" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="course_id" property="courseId" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, like, favorite, meditation_id, app_user_id |
| | | id, app_user_id, course_id |
| | | </sql> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.course.mapper.CourseMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.Course"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="course_type" property="courseType" /> |
| | | <result column="cate_id" property="cateId" /> |
| | | <result column="course_title" property="courseTitle" /> |
| | | <result column="description" property="description" /> |
| | | <result column="listing_status" property="listingStatus" /> |
| | | <result column="recommend" property="recommend" /> |
| | | <result column="charge_type" property="chargeType" /> |
| | | <result column="sort_num" property="sortNum" /> |
| | | <result column="tutor" property="tutor" /> |
| | | <result column="cover_url" property="coverUrl" /> |
| | | <result column="detail_url" property="detailUrl" /> |
| | | <result column="brief_introduction" property="briefIntroduction" /> |
| | | <result column="wx_qr_code" property="wxQrCode" /> |
| | | <result column="address" property="address" /> |
| | | <result column="address_detail" property="addressDetail" /> |
| | | <result column="longitude" property="longitude" /> |
| | | <result column="latitude" property="latitude" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | del_flag, |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, course_type, cate_id, course_title, description, listing_status, recommend, charge_type, sort_num, tutor, cover_url, detail_url, brief_introduction, wx_qr_code, address, address_detail, longitude, latitude |
| | | </sql> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.course.mapper.TutorSpecialColumnCourseMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.TutorSpecialColumnCourse"> |
| | | <id column="id" property="id" /> |
| | | <result column="course_id" property="courseId" /> |
| | | <result column="tutor_special_column_id" property="tutorSpecialColumnId" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, course_id, tutor_special_column_id |
| | | </sql> |
| | | |
| | | </mapper> |
copy from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml
copy to xinquan-modules/xinquan-course/src/main/resources/mapper/course/TutorSpecialColumnMapper.xml
File was copied from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserOperationMapper"> |
| | | <mapper namespace="com.xinquan.course.mapper.TutorSpecialColumnMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserOperation"> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.course.domain.TutorSpecialColumn"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="like" property="like" /> |
| | | <result column="favorite" property="favorite" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="video_url" property="videoUrl" /> |
| | | <result column="tutor_introduction" property="tutorIntroduction" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, like, favorite, meditation_id, app_user_id |
| | | id, video_url, tutor_introduction |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>cn.afterturn</groupId> |
| | | <artifactId>easypoi-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>guava</artifactId> |
| | | <groupId>com.google.guava</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | <build> |
New file |
| | |
| | | package com.xinquan.meditation.controller.client; |
| | | |
| | | |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.meditation.domain.vo.ClientHomeBackgroundMusicVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationAndCateVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationCategoryVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationDetailsVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationEverydayVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationQuestionVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationVO; |
| | | import com.xinquan.meditation.service.HomeBackgroundMusicService; |
| | | import com.xinquan.meditation.service.MeditationCategoryService; |
| | | import com.xinquan.meditation.service.MeditationEverydayService; |
| | | import com.xinquan.meditation.service.MeditationQuestionService; |
| | | import com.xinquan.meditation.service.MeditationService; |
| | | import com.xinquan.system.api.RemoteHotWordsService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 首页相关接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Api(tags = {"用户端-首页相关接口"}) |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/client/meditation/home") |
| | | public class ClientHomeController { |
| | | |
| | | private final HomeBackgroundMusicService homeBackgroundMusicService; |
| | | private final MeditationService meditationService; |
| | | private final MeditationCategoryService meditationCategoryService; |
| | | private final MeditationEverydayService meditationEverydayService; |
| | | private final RemoteHotWordsService remoteHotWordsService; |
| | | private final MeditationQuestionService meditationQuestionService; |
| | | |
| | | /** |
| | | * 获取首页背景音乐列表 |
| | | * |
| | | * @return 背景音乐列表 |
| | | */ |
| | | @GetMapping("/getHomeBackgroundMusicList") |
| | | @ApiOperation(value = "获取首页背景音乐列表", notes = "首页顶部默认展示该接口返回的列表中第一条数据的背景图片") |
| | | public R<List<ClientHomeBackgroundMusicVO>> getHomeBackgroundMusicList() { |
| | | return R.ok(homeBackgroundMusicService.getHomeBackgroundMusicList()); |
| | | } |
| | | |
| | | /** |
| | | * 保存用户首页背景音乐设置 |
| | | * |
| | | * @param id 首页背景音乐id |
| | | */ |
| | | @PostMapping("/savePersonalitySetting") |
| | | @ApiOperation(value = "保存用户首页背景音乐设置") |
| | | @ApiImplicitParam(name = "id", value = "首页背景音乐id", required = true) |
| | | public R<?> savePersonalitySetting(@RequestParam("id") Long id) { |
| | | homeBackgroundMusicService.savePersonalitySetting(id); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 根据类型获取冥想分类列表 |
| | | * |
| | | * @param type 分类类型 |
| | | * @return 分类列表 |
| | | */ |
| | | @PostMapping("/getCategoryListByType") |
| | | @ApiOperation("根据类型获取冥想音频分类列表") |
| | | @ApiImplicitParam(name = "type", value = "类型 1=顶部4个 2=下面3个", required = true) |
| | | public R<List<ClientMeditationCategoryVO>> getCategoryListByType( |
| | | @RequestParam(value = "type") Integer type) { |
| | | return R.ok(meditationCategoryService.getCategoryListByType(type)); |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想分类列表 |
| | | * |
| | | * @return 冥想分类列表 |
| | | */ |
| | | @GetMapping("/getCategoryList") |
| | | @ApiOperation("获取冥想音频分类列表") |
| | | public R<List<ClientMeditationCategoryVO>> getCategoryList() { |
| | | return R.ok(meditationCategoryService.getCategoryList()); |
| | | } |
| | | |
| | | /** |
| | | * 查询每日冥想 |
| | | * |
| | | * @return 每日冥想 |
| | | */ |
| | | @GetMapping("/getTodayMeditation") |
| | | @ApiOperation("获取今日冥想") |
| | | public R<ClientMeditationEverydayVO> getTodayMeditation() { |
| | | return R.ok(meditationEverydayService.getTodayMeditation()); |
| | | } |
| | | |
| | | /** |
| | | * 获取私人订制 |
| | | * |
| | | * @return 冥想列表 |
| | | */ |
| | | @GetMapping("/getPersonalityPlan") |
| | | @ApiOperation("获取私人订制") |
| | | public R<List<ClientMeditationVO>> getPersonalityPlan() { |
| | | return R.ok(meditationService.getPersonalityPlan()); |
| | | } |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表 |
| | | * |
| | | * @param cateId 分类id |
| | | * @return 冥想列表 |
| | | */ |
| | | @PostMapping("/getMeditationListByCateId") |
| | | @ApiOperation("根据分类id获取冥想音频列表") |
| | | @ApiImplicitParam(name = "cateId", value = "分类id", dataType = "Long", required = true) |
| | | public R<List<ClientMeditationVO>> getMeditationListByCateId( |
| | | @RequestParam("cateId") Long cateId) { |
| | | return R.ok(meditationService.getMeditationListByCateId(cateId)); |
| | | } |
| | | |
| | | /** |
| | | * 获取全部的冥想及分类列表 |
| | | * |
| | | * @return 冥想及分类列表 |
| | | */ |
| | | @GetMapping("/getMeditationAndCateList") |
| | | @ApiOperation(value = "获取全部的冥想音频及分类列表", notes = "用于首页列表展示") |
| | | public R<List<ClientMeditationAndCateVO>> getMeditationAndCateList() { |
| | | return R.ok(meditationService.getMeditationAndCateList()); |
| | | } |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表-分页 |
| | | * |
| | | * @param cateId 分类id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | @PostMapping("/getMeditationPageByCateId") |
| | | @ApiOperation(value = "根据分类id获取冥想音频列表-分页", notes = "查看更多") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "cateId", value = "分类id", dataType = "Long", required = true), |
| | | @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true), |
| | | @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true)}) |
| | | public R<PageDTO<ClientMeditationVO>> getMeditationPageByCateId(@RequestParam Long cateId, |
| | | @RequestParam Integer pageCurr, @RequestParam Integer pageSize) { |
| | | return R.ok(meditationService.getMeditationPageByCateId(cateId, pageCurr, pageSize)); |
| | | } |
| | | |
| | | /** |
| | | * 首页搜索首页 |
| | | * |
| | | * @param condition 搜索条件 |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | @PostMapping("/search") |
| | | @ApiOperation("首页搜索冥想音频") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "condition", value = "查询条件", dataType = "String", required = true), |
| | | @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true), |
| | | @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true) |
| | | }) |
| | | public R<PageDTO<ClientMeditationVO>> search(@RequestParam String condition, |
| | | @RequestParam Integer |
| | | pageCurr, @RequestParam Integer pageSize) { |
| | | return R.ok(meditationService.search(condition, pageCurr, pageSize)); |
| | | } |
| | | |
| | | /** |
| | | * 获取热词列表 |
| | | * |
| | | * @return 热词列表 |
| | | */ |
| | | @GetMapping("/getHotWordList") |
| | | @ApiOperation("获取热词列表") |
| | | public R<List<String>> getHotWordList() { |
| | | return R.ok(remoteHotWordsService.getHotWordList(SecurityConstants.INNER).getData()); |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想音频详情 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @return 客户端冥想详情视图对象 |
| | | */ |
| | | @GetMapping("/getMeditationDetails") |
| | | @ApiOperation("获取冥想音频详情") |
| | | @ApiImplicitParam(name = "id", value = "冥想音频id", dataType = "Long", required = true) |
| | | public R<ClientMeditationDetailsVO> getMeditationDetails(@RequestParam("id") Long id) { |
| | | return R.ok(meditationService.getMeditationDetails(id)); |
| | | } |
| | | |
| | | /** |
| | | * 收藏/取消收藏 |
| | | * |
| | | * @param id 冥想音频id |
| | | */ |
| | | @PostMapping("/favorite") |
| | | @ApiOperation(value = "收藏/取消收藏") |
| | | @ApiImplicitParam(name = "id", value = "冥想音频id", dataType = "Long", required = true) |
| | | public R<?> favorite(@RequestParam("id") Long id) { |
| | | meditationService.favorite(id); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想音频提问列表-分页 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想音频提问分页列表 |
| | | */ |
| | | @GetMapping("/getMeditationQuestionPage") |
| | | @ApiOperation(value = "获取冥想音频提问列表-分页") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "id", value = "冥想音频id", dataType = "Long", required = true), |
| | | @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", dataType = "Integer", required = true), |
| | | @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量", dataType = "Integer", required = true) |
| | | }) |
| | | public R<PageDTO<ClientMeditationQuestionVO>> getMeditationQuestionPage( |
| | | @RequestParam("id") Long id, @RequestParam("pageCurr") Integer pageCurr, |
| | | @RequestParam("pageSize") Integer pageSize) { |
| | | return R.ok(meditationService.getMeditationQuestionPage(id, pageCurr, pageSize)); |
| | | } |
| | | |
| | | /** |
| | | * 举报提问 |
| | | * |
| | | * @param id 提问id |
| | | * @param content 举报内容 |
| | | */ |
| | | @PostMapping("/report") |
| | | @ApiOperation("举报提问") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "id", value = "提问id", dataType = "Long", required = true), |
| | | @ApiImplicitParam(name = "reason", value = "举报原因", dataType = "String", required = true) |
| | | }) |
| | | public R<?> report(@RequestParam("id") Long id, @RequestParam("reason") String content) { |
| | | meditationQuestionService.report(id, content); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 点赞/取消点赞提问 |
| | | * |
| | | * @param id 提问id |
| | | */ |
| | | @PostMapping("/likeQuestion") |
| | | @ApiOperation("点赞/取消点赞提问") |
| | | @ApiImplicitParam(name = "id", value = "提问id", dataType = "Long", required = true) |
| | | public R<?> likeQuestion(@RequestParam("id") Long id) { |
| | | meditationQuestionService.likeQuestion(id); |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
| | |
| | | package com.xinquan.meditation.controller.client; |
| | | |
| | | |
| | | import com.xinquan.meditation.service.MeditationService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/client/meditation/meditation") |
| | | public class ClientMeditationController { |
| | | |
| | | private final MeditationService meditationService; |
| | | |
| | | } |
| | | |
File was renamed from xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationUserOperationController.java |
| | |
| | | |
| | | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/client/meditation/meditation-user-operation") |
| | | public class ClientMeditationUserOperationController { |
| | | public class ClientMeditationUserFavoriteController { |
| | | |
| | | } |
| | | |
| | |
| | | * @since 2024-08-23 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/meditation/home-background-music-user") |
| | | @RequestMapping("/client/meditation/home-background-music-user") |
| | | public class HomeBackgroundMusicUserController { |
| | | |
| | | } |
File was renamed from xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtClientMeditationUserOperationController.java |
| | |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/mgt/meditation/meditation-user-operation") |
| | | public class MgtClientMeditationUserOperationController { |
| | | public class MgtClientMeditationUserFavoriteController { |
| | | |
| | | } |
| | | |
| | |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("t_home_background_music") |
| | | @ApiModel(value="HomeBackgroundMusic对象", description="首页背景音乐表 ") |
| | | @ApiModel(value = "HomeBackgroundMusic对象", description = "首页背景音乐表") |
| | | public class HomeBackgroundMusic extends BaseModel { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | @TableField("audio_file") |
| | | private String audioFile; |
| | | |
| | | @ApiModelProperty(value = "音频文件名称") |
| | | @TableField("audio_file_name") |
| | | private String audioFileName; |
| | | |
| | | @ApiModelProperty(value = "排序权重") |
| | | @TableField("sort_num") |
| | | private Integer sortNum; |
| | |
| | | package com.xinquan.meditation.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.math.BigDecimal; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | |
| | | @TableField("charge_type") |
| | | private Integer chargeType; |
| | | |
| | | @ApiModelProperty(value = "通用价格") |
| | | @TableField("general_price") |
| | | private BigDecimal generalPrice; |
| | | |
| | | @ApiModelProperty(value = "IOS内购价格") |
| | | @TableField("ios_price") |
| | | private BigDecimal iosPrice; |
| | | |
| | | @ApiModelProperty(value = "排序权重") |
| | | @TableField("sort_num") |
| | | private Integer sortNum; |
| | |
| | | package com.xinquan.meditation.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "冥想分类id") |
| | | @TableId(value = "id",type = IdType.ASSIGN_ID) |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想分类课程") |
| | |
| | | package com.xinquan.meditation.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import java.time.LocalDateTime; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | |
| | | @TableId(value = "id",type = IdType.ASSIGN_ID) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想id") |
| | | @TableField("meditation_id") |
| | | private Long meditationId; |
| | | |
| | | @ApiModelProperty(value = "点赞数") |
| | | @TableField("like_count") |
| | | private Integer likeCount; |
New file |
| | |
| | | package com.xinquan.meditation.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想提问点赞表 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Data |
| | | @TableName("t_meditation_question_like") |
| | | @ApiModel(value = "MeditationQuestionLike对象", description = "冥想提问点赞表") |
| | | public class MeditationQuestionLike implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "id") |
| | | @TableId("id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想id") |
| | | @TableField("meditation_question_id") |
| | | private Long meditationQuestionId; |
| | | |
| | | @ApiModelProperty(value = "用户id") |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | /** |
| | | * 创建者 |
| | | */ |
| | | @ApiModelProperty(value = "记录创建人,前端忽略") |
| | | @TableField(value = "create_by", fill = FieldFill.INSERT) |
| | | private String createBy; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | @ApiModelProperty(value = "记录创建时间,前端忽略") |
| | | // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField(value = "create_time", fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | |
| | | |
| | | } |
File was renamed from xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationUserOperation.java |
| | |
| | | package com.xinquan.meditation.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("t_meditation_user_operation") |
| | | @ApiModel(value="MeditationUserOperation对象", description="冥想用户操作表") |
| | | public class MeditationUserOperation extends BaseModel { |
| | | public class MeditationUserFavorite implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "id") |
| | | @TableId(value = "id",type = IdType.ASSIGN_ID) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "是否点赞 1=是 2=否") |
| | | @TableField("like") |
| | | private Integer like; |
| | | |
| | | @ApiModelProperty(value = "是否收藏 1=是 2=否") |
| | | @TableField("favorite") |
| | | private Integer favorite; |
| | | |
| | | @ApiModelProperty(value = "冥想id") |
| | | @TableField("meditation_id") |
| | |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | /** |
| | | * 创建者 |
| | | */ |
| | | @ApiModelProperty(value = "记录创建人,前端忽略") |
| | | @TableField(value = "create_by", fill = FieldFill.INSERT) |
| | | private String createBy; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | @ApiModelProperty(value = "记录创建时间,前端忽略") |
| | | // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField(value = "create_time", fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.dto; |
| | | |
| | | import com.xinquan.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import javax.validation.constraints.NotBlank; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ApiModel("客户端-首页查询参数") |
| | | public class ClientHomeMeditationQueryDTO extends BasePage implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -6691807074482685234L; |
| | | |
| | | @ApiModelProperty(value = "查询条件") |
| | | @NotBlank(message = "查询条件不能为空") |
| | | private String condition; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.dto; |
| | | |
| | | import com.xinquan.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import javax.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ApiModel("客户端-冥想查询参数") |
| | | public class ClientMeditationQueryDTO extends BasePage implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -6691807074482685234L; |
| | | |
| | | @ApiModelProperty(value = "分类id") |
| | | @NotNull(message = "分类id不能为空") |
| | | private Long cateId; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "首页背景音乐视图对象") |
| | | public class ClientHomeBackgroundMusicVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 8868579953762043190L; |
| | | |
| | | @ApiModelProperty(value = "首页背景音乐id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "背景图片") |
| | | private String imageUrl; |
| | | |
| | | @ApiModelProperty(value = "音频文件") |
| | | private String audioFile; |
| | | |
| | | @ApiModelProperty(value = "文件名称") |
| | | private String audioFileName; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/5 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "冥想及分类视图对象") |
| | | public class ClientMeditationAndCateVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -2154691485115564661L; |
| | | |
| | | @ApiModelProperty("冥想分类") |
| | | private ClientMeditationCategoryVO clientMeditationCategoryVO; |
| | | |
| | | @ApiModelProperty(value = "冥想列表") |
| | | private List<ClientMeditationVO> clientMeditationVOList; |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "冥想分类视图对象") |
| | | public class ClientMeditationCategoryVO { |
| | | |
| | | @ApiModelProperty(value = "冥想分类id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想分类课程") |
| | | private String categoryName; |
| | | |
| | | @ApiModelProperty(value = "分类描述") |
| | | private String description; |
| | | |
| | | @ApiModelProperty(value = "icon图片 用于顶部四个分类展示") |
| | | private String firstIconUrl; |
| | | |
| | | @ApiModelProperty(value = "icon图片 用于下面的三个分类展示 ") |
| | | private String secondIconUrl; |
| | | |
| | | @ApiModelProperty(value = "展示方式 1=横版 2=竖版") |
| | | private Integer showType; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.util.List; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/5 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ApiModel(value = "客户端冥想详情视图对象") |
| | | public class ClientMeditationDetailsVO extends ClientMeditationVO { |
| | | |
| | | private static final long serialVersionUID = -2959289858083878221L; |
| | | |
| | | @ApiModelProperty(value = "冥想背景音频列表") |
| | | private List<String> meditationMusicList; |
| | | |
| | | @ApiModelProperty(value = "是否收藏 1:是 2:否") |
| | | private Integer favorite; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "每日冥想视图对象") |
| | | public class ClientMeditationEverydayVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -1776068531441762518L; |
| | | |
| | | @ApiModelProperty(value = "每日冥想id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想id") |
| | | private Long meditationId; |
| | | |
| | | @ApiModelProperty(value = "播放时间段开始") |
| | | private LocalDateTime startPlayTime; |
| | | |
| | | @ApiModelProperty(value = "播放时间段结束") |
| | | private LocalDateTime endPlayTime; |
| | | |
| | | @ApiModelProperty(value = "每日冥想背景图片") |
| | | private String imageUrl; |
| | | |
| | | @ApiModelProperty(value = "每日冥想") |
| | | private ClientMeditationVO clientMeditationVO; |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/5 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "客户端冥想评论视图对象") |
| | | public class ClientMeditationQuestionVO { |
| | | |
| | | @ApiModelProperty(value = "id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "点赞数") |
| | | private Integer likeCount; |
| | | |
| | | @ApiModelProperty(value = "是否点赞 1=是 2=否") |
| | | private Integer like = 2; |
| | | |
| | | @ApiModelProperty(value = "提问内容") |
| | | private String content; |
| | | |
| | | @ApiModelProperty(value = "提问时间") |
| | | private LocalDateTime publishTime; |
| | | |
| | | @ApiModelProperty(value = "用户id") |
| | | private Long appUserId; |
| | | |
| | | @ApiModelProperty(value = "头像") |
| | | private String avatar; |
| | | |
| | | @ApiModelProperty(value = "昵称") |
| | | private String nickname; |
| | | |
| | | @ApiModelProperty(value = "回复内容") |
| | | private String replyContent; |
| | | |
| | | @ApiModelProperty(value = "回复时间") |
| | | private LocalDateTime replyTime; |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "冥想视图对象") |
| | | public class ClientMeditationVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -1776068531441762518L; |
| | | |
| | | @ApiModelProperty(value = "冥想id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "冥想音频分类id") |
| | | private Long cateId; |
| | | |
| | | @ApiModelProperty(value = "冥想标题") |
| | | private String meditationTitle; |
| | | |
| | | @ApiModelProperty(value = "上架状态 1=上架 2=下架") |
| | | private Integer listingStatus; |
| | | |
| | | @ApiModelProperty(value = "梵文 1=是 2否") |
| | | private Integer sanskrit; |
| | | |
| | | @ApiModelProperty(value = "价格设定 1=免费 2=会员免费 3=单独收费") |
| | | private Integer chargeType; |
| | | |
| | | @ApiModelProperty(value = "通用价格", notes = "价格设定为单独收费") |
| | | private BigDecimal generalPrice; |
| | | |
| | | @ApiModelProperty(value = "IOS内购价格", notes = "价格设定为单独收费") |
| | | private BigDecimal iosPrice; |
| | | |
| | | @ApiModelProperty(value = "排序权重") |
| | | private Integer sortNum; |
| | | |
| | | @ApiModelProperty(value = "实际已学习数") |
| | | private Integer realLearnedNum; |
| | | |
| | | @ApiModelProperty(value = "虚拟已学习数") |
| | | private Integer virtualLearnedNum; |
| | | |
| | | @ApiModelProperty(value = "icon封面图") |
| | | private String iconUrl; |
| | | |
| | | @ApiModelProperty(value = "封面图") |
| | | private String coverUrl; |
| | | |
| | | @ApiModelProperty(value = "背景图") |
| | | private String backgroundUrl; |
| | | |
| | | @ApiModelProperty(value = "详情描述") |
| | | private String detailDescription; |
| | | |
| | | @ApiModelProperty(value = "封面描述") |
| | | private String coverDescription; |
| | | |
| | | @ApiModelProperty(value = "导师音频") |
| | | private String tutorAudioUrl; |
| | | |
| | | @ApiModelProperty(value = "被收藏数") |
| | | private Integer favoriteCount; |
| | | |
| | | } |
| | |
| | | package com.xinquan.meditation.mapper; |
| | | |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationVO; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface MeditationMapper extends BaseMapper<Meditation> { |
| | | |
| | | /** |
| | | * 根据用户梵文权限和标签查询冥想列表 |
| | | * |
| | | * @param tagIdSet 标签id集合 |
| | | * @param sanskritFlag 梵文权限 |
| | | * @return 冥想列表 |
| | | */ |
| | | List<ClientMeditationVO> getMeditationListByTagId(@Param("tagIdSet") Set<Long> tagIdSet, |
| | | @Param("sanskritFlag") Integer sanskritFlag); |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.mapper; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationQuestionLike; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想提问点赞表 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface MeditationQuestionLikeMapper extends BaseMapper<MeditationQuestionLike> { |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xinquan.meditation.domain.MeditationUserFavorite; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想用户操作表 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | public interface MeditationUserFavoriteMapper extends BaseMapper<MeditationUserFavorite> { |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.meditation.domain.HomeBackgroundMusic; |
| | | import com.xinquan.meditation.domain.vo.ClientHomeBackgroundMusicVO; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 首页背景音乐用户关系表 服务类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-23 |
| | | */ |
| | | public interface HomeBackgroundMusicService extends IService<HomeBackgroundMusic> { |
| | | |
| | | /** |
| | | * 获取首页背景音乐列表 |
| | | * |
| | | * @return 背景音乐列表 |
| | | */ |
| | | List<ClientHomeBackgroundMusicVO> getHomeBackgroundMusicList(); |
| | | |
| | | /** |
| | | * 保存用户首页背景音乐设置 |
| | | * |
| | | * @param id 首页背景音乐id |
| | | */ |
| | | void savePersonalitySetting(Long id); |
| | | } |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationCategory; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.meditation.domain.MeditationCategory; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationCategoryVO; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface MeditationCategoryService extends IService<MeditationCategory> { |
| | | |
| | | /** |
| | | * 获取冥想分类列表 |
| | | * |
| | | * @param type 分类类型 |
| | | * @return 分类列表 |
| | | */ |
| | | List<ClientMeditationCategoryVO> getCategoryListByType(Integer type); |
| | | |
| | | /** |
| | | * 获取冥想分类列表 |
| | | * |
| | | * @return 冥想分类列表 |
| | | */ |
| | | List<ClientMeditationCategoryVO> getCategoryList(); |
| | | } |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationEveryday; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.meditation.domain.MeditationEveryday; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationEverydayVO; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface MeditationEverydayService extends IService<MeditationEveryday> { |
| | | |
| | | /** |
| | | * 查询每日冥想 |
| | | * |
| | | * @return 每日冥想 |
| | | */ |
| | | ClientMeditationEverydayVO getTodayMeditation(); |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationQuestionLike; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想提问点赞表 服务类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface MeditationQuestionLikeService extends IService<MeditationQuestionLike> { |
| | | |
| | | } |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationQuestion; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.meditation.domain.MeditationQuestion; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface MeditationQuestionService extends IService<MeditationQuestion> { |
| | | |
| | | /** |
| | | * 举报提问 |
| | | * |
| | | * @param id 提问id |
| | | * @param content 举报内容 |
| | | */ |
| | | void report(Long id, String content); |
| | | |
| | | /** |
| | | * 点赞/取消点赞提问 |
| | | * |
| | | * @param id 提问id |
| | | */ |
| | | void likeQuestion(Long id); |
| | | } |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationAndCateVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationDetailsVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationQuestionVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationVO; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface MeditationService extends IService<Meditation> { |
| | | |
| | | /** |
| | | * 获取私人订制 |
| | | * |
| | | * @return 冥想列表 |
| | | */ |
| | | List<ClientMeditationVO> getPersonalityPlan(); |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表 |
| | | * |
| | | * @param cateId 分类id |
| | | * @return 冥想列表 |
| | | */ |
| | | List<ClientMeditationVO> getMeditationListByCateId(Long cateId); |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表-分页 |
| | | * |
| | | * @param cateId 分类id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | PageDTO<ClientMeditationVO> getMeditationPageByCateId(Long cateId, Integer pageCurr, |
| | | Integer pageSize); |
| | | |
| | | /** |
| | | * 首页搜索首页 |
| | | * |
| | | * @param condition 搜索条件 |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | PageDTO<ClientMeditationVO> search(String condition, Integer pageCurr, Integer pageSize); |
| | | |
| | | /** |
| | | * 获取全部的冥想及分类列表 |
| | | * |
| | | * @return 冥想和分类列表 |
| | | */ |
| | | List<ClientMeditationAndCateVO> getMeditationAndCateList(); |
| | | |
| | | /** |
| | | * 获取冥想音频详情 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @return 客户端冥想详情视图对象 |
| | | */ |
| | | ClientMeditationDetailsVO getMeditationDetails(Long id); |
| | | |
| | | /** |
| | | * 获取冥想音频提问列表-分页 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想音频提问分页列表 |
| | | */ |
| | | PageDTO<ClientMeditationQuestionVO> getMeditationQuestionPage(Long id, |
| | | Integer pageCurr, Integer pageSize); |
| | | |
| | | /** |
| | | * 收藏/取消收藏 |
| | | * |
| | | * @param id 冥想音频id |
| | | */ |
| | | void favorite(Long id); |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.meditation.domain.MeditationUserFavorite; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想用户操作表 服务类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | public interface MeditationUserFavoriteService extends IService<MeditationUserFavorite> { |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.common.security.utils.SecurityUtils; |
| | | import com.xinquan.meditation.domain.HomeBackgroundMusic; |
| | | import com.xinquan.meditation.domain.vo.ClientHomeBackgroundMusicVO; |
| | | import com.xinquan.meditation.mapper.HomeBackgroundMusicMapper; |
| | | import com.xinquan.meditation.service.HomeBackgroundMusicService; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.api.feign.RemoteAppUserService; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 首页背景音乐用户关系表 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-23 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class HomeBackgroundMusicServiceImpl extends |
| | | ServiceImpl<HomeBackgroundMusicMapper, HomeBackgroundMusic> implements |
| | | HomeBackgroundMusicService { |
| | | |
| | | private final RemoteAppUserService remoteAppUserService; |
| | | |
| | | /** |
| | | * 获取首页背景音乐列表 |
| | | * |
| | | * @return 背景音乐列表 |
| | | */ |
| | | @Override |
| | | public List<ClientHomeBackgroundMusicVO> getHomeBackgroundMusicList() { |
| | | List<HomeBackgroundMusic> list = this.lambdaQuery() |
| | | .orderByDesc(HomeBackgroundMusic::getSortNum).list(); |
| | | return BeanUtils.copyList(list, ClientHomeBackgroundMusicVO.class); |
| | | } |
| | | |
| | | /** |
| | | * 保存用户首页背景音乐设置 |
| | | * |
| | | * @param id 首页背景音乐id |
| | | */ |
| | | @Override |
| | | public void savePersonalitySetting(Long id) { |
| | | // 获取当前登录用户id |
| | | Long userId = SecurityUtils.getUserId(); |
| | | // 远程调用修改用户信息 |
| | | remoteAppUserService.updateAppUser( |
| | | AppUserDTO.builder() |
| | | .id(userId) |
| | | .homeBackgroundMusicId(id).build(), |
| | | SecurityConstants.INNER); |
| | | } |
| | | } |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.meditation.domain.MeditationCategory; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationCategoryVO; |
| | | import com.xinquan.meditation.mapper.MeditationCategoryMapper; |
| | | import com.xinquan.meditation.service.MeditationCategoryService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import java.util.List; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class MeditationCategoryServiceImpl extends ServiceImpl<MeditationCategoryMapper, MeditationCategory> implements MeditationCategoryService { |
| | | |
| | | /** |
| | | * 获取冥想分类列表 |
| | | * |
| | | * @param type 分类类型 |
| | | * @return 分类列表 |
| | | */ |
| | | @Override |
| | | public List<ClientMeditationCategoryVO> getCategoryListByType(Integer type) { |
| | | List<MeditationCategory> list = this.lambdaQuery() |
| | | .orderByDesc(MeditationCategory::getSortNum).last(type == 1, "limit 4") |
| | | .last(type == 2, "limit 4,3").list(); |
| | | return BeanUtils.copyList(list, ClientMeditationCategoryVO.class); |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想分类列表 |
| | | * |
| | | * @return 冥想分类列表 |
| | | */ |
| | | @Override |
| | | public List<ClientMeditationCategoryVO> getCategoryList() { |
| | | List<MeditationCategory> list = this.lambdaQuery() |
| | | .orderByDesc(MeditationCategory::getSortNum).list(); |
| | | return BeanUtils.copyList(list, ClientMeditationCategoryVO.class); |
| | | } |
| | | } |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationEveryday; |
| | | import com.xinquan.meditation.mapper.MeditationEverydayMapper; |
| | | import com.xinquan.meditation.service.MeditationEverydayService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.xinquan.meditation.domain.MeditationEveryday; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationEverydayVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationVO; |
| | | import com.xinquan.meditation.mapper.MeditationEverydayMapper; |
| | | import com.xinquan.meditation.mapper.MeditationMapper; |
| | | import com.xinquan.meditation.service.MeditationEverydayService; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Optional; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class MeditationEverydayServiceImpl extends ServiceImpl<MeditationEverydayMapper, MeditationEveryday> implements MeditationEverydayService { |
| | | |
| | | private final MeditationMapper meditationMapper; |
| | | |
| | | /** |
| | | * 查询每日冥想 |
| | | * |
| | | * @return 每日冥想 |
| | | */ |
| | | @Override |
| | | public ClientMeditationEverydayVO getTodayMeditation() { |
| | | ClientMeditationEverydayVO vo = null; |
| | | // 当前时间 |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | // 查询播放时间段在当前时间的每日冥想 |
| | | Optional<MeditationEveryday> meditationEverydayOpt = this.lambdaQuery() |
| | | .le(MeditationEveryday::getStartPlayTime, now) |
| | | .ge(MeditationEveryday::getEndPlayTime, now) |
| | | .orderByDesc(MeditationEveryday::getUpdateTime) |
| | | .last("limit 1").oneOpt(); |
| | | if (!meditationEverydayOpt.isPresent()) { |
| | | // 查询结束时间离当前时间最近的一个每日冥想 |
| | | meditationEverydayOpt = this.lambdaQuery() |
| | | .le(MeditationEveryday::getStartPlayTime, now) |
| | | .orderByDesc(MeditationEveryday::getEndPlayTime) |
| | | .last("limit 1").oneOpt(); |
| | | } |
| | | // 判断是否存在 |
| | | if (meditationEverydayOpt.isPresent()) { |
| | | // 查询冥想详情 |
| | | MeditationEveryday meditationEveryday = meditationEverydayOpt.get(); |
| | | Optional<Meditation> meditationOpt = Optional.ofNullable( |
| | | meditationMapper.selectById( |
| | | meditationEveryday.getMeditationId())); |
| | | if (meditationOpt.isPresent()) { |
| | | // 封装返回值 |
| | | ClientMeditationVO clientMeditationVO = BeanUtils.copyBean(meditationOpt.get(), |
| | | ClientMeditationVO.class); |
| | | vo = BeanUtils.copyBean(meditationEveryday, |
| | | ClientMeditationEverydayVO.class); |
| | | vo.setClientMeditationVO(clientMeditationVO); |
| | | } |
| | | } |
| | | return vo; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationQuestionLike; |
| | | import com.xinquan.meditation.mapper.MeditationQuestionLikeMapper; |
| | | import com.xinquan.meditation.service.MeditationQuestionLikeService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想提问点赞表 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Service |
| | | public class MeditationQuestionLikeServiceImpl extends ServiceImpl<MeditationQuestionLikeMapper, MeditationQuestionLike> implements MeditationQuestionLikeService { |
| | | |
| | | } |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.xinquan.meditation.domain.MeditationQuestion; |
| | | import com.xinquan.meditation.mapper.MeditationQuestionMapper; |
| | | import com.xinquan.meditation.service.MeditationQuestionService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.enums.ReportStatusEnum; |
| | | import com.xinquan.common.core.exception.ServiceException; |
| | | import com.xinquan.common.security.utils.SecurityUtils; |
| | | import com.xinquan.meditation.domain.MeditationQuestion; |
| | | import com.xinquan.meditation.domain.MeditationQuestionLike; |
| | | import com.xinquan.meditation.mapper.MeditationQuestionMapper; |
| | | import com.xinquan.meditation.service.MeditationQuestionLikeService; |
| | | import com.xinquan.meditation.service.MeditationQuestionService; |
| | | import java.util.Objects; |
| | | import java.util.Optional; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class MeditationQuestionServiceImpl extends ServiceImpl<MeditationQuestionMapper, MeditationQuestion> implements MeditationQuestionService { |
| | | |
| | | private final MeditationQuestionLikeService meditationQuestionLikeService; |
| | | |
| | | /** |
| | | * 举报提问 |
| | | * |
| | | * @param id 提问id |
| | | * @param content 举报内容 |
| | | */ |
| | | @Override |
| | | public void report(Long id, String content) { |
| | | MeditationQuestion meditationQuestion = this.getById(id); |
| | | if (Optional.ofNullable(meditationQuestion).isPresent()) { |
| | | meditationQuestion.setReportStatus(ReportStatusEnum.REPORTED.getCode()); |
| | | meditationQuestion.setReportUserId(SecurityUtils.getUserId()); |
| | | meditationQuestion.setReportContent(content); |
| | | this.updateById(meditationQuestion); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 点赞/取消点赞提问 |
| | | * |
| | | * @param id 提问id |
| | | */ |
| | | @Override |
| | | public void likeQuestion(Long id) { |
| | | MeditationQuestion meditationQuestion = this.getById(id); |
| | | if (Objects.isNull(meditationQuestion)) { |
| | | throw new ServiceException("提问不存在"); |
| | | } |
| | | // 判断是否已点赞 |
| | | Optional<MeditationQuestionLike> likeOpt = meditationQuestionLikeService.lambdaQuery() |
| | | .eq(MeditationQuestionLike::getMeditationQuestionId, id) |
| | | .eq(MeditationQuestionLike::getAppUserId, SecurityUtils.getUserId()).last("limit 1") |
| | | .oneOpt(); |
| | | if (likeOpt.isPresent()) { |
| | | // 已点赞则取消点赞 |
| | | meditationQuestionLikeService.removeById(likeOpt.get()); |
| | | meditationQuestion.setLikeCount(meditationQuestion.getLikeCount() - 1); |
| | | } else { |
| | | // 未点赞则点赞 |
| | | MeditationQuestionLike meditationQuestionLike = new MeditationQuestionLike(); |
| | | meditationQuestionLike.setAppUserId(SecurityUtils.getUserId()); |
| | | meditationQuestionLike.setMeditationQuestionId(id); |
| | | if (meditationQuestionLikeService.save(meditationQuestionLike)) { |
| | | meditationQuestion.setLikeCount(meditationQuestion.getLikeCount() + 1); |
| | | } |
| | | } |
| | | this.updateById(meditationQuestion); |
| | | } |
| | | } |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.xinquan.meditation.mapper.MeditationMapper; |
| | | import com.xinquan.meditation.service.MeditationService; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.enums.DisabledEnum; |
| | | import com.xinquan.common.core.exception.ServiceException; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.common.core.utils.page.CollUtils; |
| | | import com.xinquan.common.core.utils.page.PageDTO; |
| | | import com.xinquan.common.security.utils.SecurityUtils; |
| | | import com.xinquan.meditation.domain.Meditation; |
| | | import com.xinquan.meditation.domain.MeditationCategory; |
| | | import com.xinquan.meditation.domain.MeditationMusic; |
| | | import com.xinquan.meditation.domain.MeditationQuestion; |
| | | import com.xinquan.meditation.domain.MeditationQuestionLike; |
| | | import com.xinquan.meditation.domain.MeditationUserFavorite; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationAndCateVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationCategoryVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationDetailsVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationQuestionVO; |
| | | import com.xinquan.meditation.domain.vo.ClientMeditationVO; |
| | | import com.xinquan.meditation.mapper.MeditationCategoryMapper; |
| | | import com.xinquan.meditation.mapper.MeditationMapper; |
| | | import com.xinquan.meditation.mapper.MeditationMusicMapper; |
| | | import com.xinquan.meditation.mapper.MeditationQuestionMapper; |
| | | import com.xinquan.meditation.service.MeditationQuestionLikeService; |
| | | import com.xinquan.meditation.service.MeditationService; |
| | | import com.xinquan.meditation.service.MeditationUserFavoriteService; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.api.feign.RemoteAppUserService; |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Optional; |
| | | import java.util.Set; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class MeditationServiceImpl extends ServiceImpl<MeditationMapper, Meditation> implements MeditationService { |
| | | |
| | | private final RemoteAppUserService remoteAppUserService; |
| | | private final MeditationCategoryMapper meditationCategoryMapper; |
| | | private final MeditationMusicMapper meditationMusicMapper; |
| | | private final MeditationQuestionMapper meditationQuestionMapper; |
| | | private final MeditationQuestionLikeService meditationQuestionLikeService; |
| | | private final MeditationUserFavoriteService meditationUserFavoriteService; |
| | | |
| | | /** |
| | | * 获取私人订制 |
| | | * |
| | | * @return 冥想列表 |
| | | */ |
| | | @Override |
| | | public List<ClientMeditationVO> getPersonalityPlan() { |
| | | List<ClientMeditationVO> voList = null; |
| | | // 获取当前登录用户id |
| | | AppUser appUser = getCurrentUser(); |
| | | if (Optional.ofNullable(appUser.getTagId()).isPresent()) { |
| | | String tagId = appUser.getTagId(); |
| | | Integer sanskritFlag = appUser.getSanskritFlag(); |
| | | Set<Long> tagIdSet = Arrays.stream(tagId.split(",")).map(Long::parseLong) |
| | | .collect(Collectors.toSet()); |
| | | // 查询冥想列表 |
| | | voList = baseMapper.getMeditationListByTagId(tagIdSet, sanskritFlag); |
| | | } |
| | | return voList; |
| | | } |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表 |
| | | * |
| | | * @param cateId 分类id |
| | | * @return 冥想列表 |
| | | */ |
| | | @Override |
| | | public List<ClientMeditationVO> getMeditationListByCateId(Long cateId) { |
| | | List<ClientMeditationVO> voList = null; |
| | | // 获取当前登录用户id |
| | | AppUser appUser = getCurrentUser(); |
| | | // 查询 |
| | | List<Meditation> list = this.lambdaQuery().eq(Meditation::getCateId, cateId) |
| | | .eq(Meditation::getSanskrit, appUser.getSanskritFlag()) |
| | | .orderByDesc(Meditation::getSortNum).last("limit 8").list(); |
| | | if (CollUtils.isNotEmpty(list)) { |
| | | // 对象拷贝 |
| | | voList = BeanUtils.copyList(list, ClientMeditationVO.class); |
| | | } |
| | | return voList; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前登录用户 |
| | | * |
| | | * @return AppUser |
| | | */ |
| | | private AppUser getCurrentUser() { |
| | | Long userId = SecurityUtils.getUserId(); |
| | | return remoteAppUserService.getUserByCondition( |
| | | AppUserDTO.builder().id(userId).build(), |
| | | SecurityConstants.INNER).getData(); |
| | | } |
| | | |
| | | /** |
| | | * 获取全部的冥想及分类列表 |
| | | * |
| | | * @return 冥想和分类列表 |
| | | */ |
| | | @Override |
| | | public List<ClientMeditationAndCateVO> getMeditationAndCateList() { |
| | | // 获取当前登录用户 |
| | | AppUser appUser = getCurrentUser(); |
| | | List<ClientMeditationAndCateVO> voList = CollUtils.newArrayList(); |
| | | // 查询分类列表 |
| | | List<MeditationCategory> cateList = meditationCategoryMapper.selectList( |
| | | Wrappers.lambdaQuery(MeditationCategory.class) |
| | | .orderByDesc(MeditationCategory::getSortNum)); |
| | | if (CollUtils.isNotEmpty(cateList)) { |
| | | for (MeditationCategory cate : cateList) { |
| | | ClientMeditationAndCateVO vo = new ClientMeditationAndCateVO(); |
| | | vo.setClientMeditationCategoryVO( |
| | | BeanUtils.copyBean(cateList, ClientMeditationCategoryVO.class)); |
| | | vo.setClientMeditationVOList(getMeditationListByCateId(cate.getId())); |
| | | voList.add(vo); |
| | | } |
| | | } |
| | | return voList; |
| | | } |
| | | |
| | | /** |
| | | * 根据分类id获取冥想列表-分页 |
| | | * |
| | | * @param cateId 分类id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | @Override |
| | | public PageDTO<ClientMeditationVO> getMeditationPageByCateId(Long cateId, Integer pageCurr, |
| | | Integer pageSize) { |
| | | PageDTO<ClientMeditationVO> pageDTO = PageDTO.empty(0L, 0L); |
| | | // 获取当前登录用户id |
| | | AppUser appUser = getCurrentUser(); |
| | | // 查询 |
| | | Page<Meditation> page = this.lambdaQuery().eq(Meditation::getCateId, cateId) |
| | | .eq(Meditation::getSanskrit, appUser.getSanskritFlag()) |
| | | .orderByDesc(Meditation::getSortNum) |
| | | .page(new Page<>(pageCurr, pageSize)); |
| | | // 如果没有查到数据直接返回 |
| | | if (Optional.ofNullable(page.getRecords()).isPresent()) { |
| | | return pageDTO; |
| | | } |
| | | // 将实体类转换为VO |
| | | pageDTO = PageDTO.of(page, ClientMeditationVO.class); |
| | | return pageDTO; |
| | | } |
| | | |
| | | /** |
| | | * 首页搜索首页 |
| | | * |
| | | * @param condition 搜索条件 |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想列表 |
| | | */ |
| | | @Override |
| | | public PageDTO<ClientMeditationVO> search(String condition, Integer pageCurr, |
| | | Integer pageSize) { |
| | | PageDTO<ClientMeditationVO> pageDTO = PageDTO.empty(0L, 0L); |
| | | // 获取当前登录用户id |
| | | AppUser appUser = getCurrentUser(); |
| | | // 查询 |
| | | Page<Meditation> page = this.lambdaQuery() |
| | | .like(Meditation::getMeditationTitle, condition).or() |
| | | .eq(Meditation::getSanskrit, appUser.getSanskritFlag()) |
| | | .orderByDesc(Meditation::getSortNum) |
| | | .page(new Page<>(pageCurr, pageSize)); |
| | | // 如果没有查到数据直接返回 |
| | | if (Optional.ofNullable(page.getRecords()).isPresent()) { |
| | | return pageDTO; |
| | | } |
| | | // 音频链接加密 |
| | | /* page.getRecords().forEach(meditation -> { |
| | | try { |
| | | meditation.setTutorAudioUrl(DES.encryptDES(meditation.getTutorAudioUrl())); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | });*/ |
| | | // 将实体类转换为VO |
| | | pageDTO = PageDTO.of(page, ClientMeditationVO.class); |
| | | return pageDTO; |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想音频详情 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @return 客户端冥想详情视图对象 |
| | | */ |
| | | @Override |
| | | public ClientMeditationDetailsVO getMeditationDetails(Long id) { |
| | | // 查询冥想音频 |
| | | Meditation meditation = this.getById(id); |
| | | ClientMeditationDetailsVO vo = BeanUtils.copyBean(meditation, |
| | | ClientMeditationDetailsVO.class); |
| | | // 查询冥想音频 |
| | | List<MeditationMusic> meditationMusics = meditationMusicMapper.selectList( |
| | | Wrappers.lambdaQuery(MeditationMusic.class) |
| | | .eq(MeditationMusic::getMeditationId, id)); |
| | | if (CollUtils.isNotEmpty(meditationMusics)) { |
| | | // 获取音频链接 |
| | | List<String> musicUrlList = meditationMusics.stream() |
| | | .map(MeditationMusic::getMusicUrl).collect(Collectors.toList()); |
| | | vo.setMeditationMusicList(musicUrlList); |
| | | } |
| | | // 查询收藏记录 |
| | | vo.setFavorite(meditationUserFavoriteService.lambdaQuery() |
| | | .eq(MeditationUserFavorite::getMeditationId, id) |
| | | .eq(MeditationUserFavorite::getAppUserId, SecurityUtils.getUserId()) |
| | | .count() > 0 ? 1 : 2); |
| | | return vo; |
| | | } |
| | | |
| | | /** |
| | | * 收藏/取消收藏 |
| | | * |
| | | * @param id 冥想音频id |
| | | */ |
| | | @Override |
| | | public void favorite(Long id) { |
| | | Meditation meditation = this.getById(id); |
| | | if (Objects.isNull(meditation)) { |
| | | throw new ServiceException("该冥想音频不存在"); |
| | | } |
| | | // 查询收藏记录 |
| | | Optional<MeditationUserFavorite> userOperationOpt = meditationUserFavoriteService.lambdaQuery() |
| | | .eq(MeditationUserFavorite::getMeditationId, id) |
| | | .eq(MeditationUserFavorite::getAppUserId, SecurityUtils.getUserId()) |
| | | .last("limit 1").oneOpt(); |
| | | if (userOperationOpt.isPresent()) { |
| | | meditationUserFavoriteService.removeById(userOperationOpt.get()); |
| | | // 增加收藏数 |
| | | meditation.setFavoriteCount(meditation.getFavoriteCount() - 1); |
| | | } else { |
| | | // 增加收藏记录 |
| | | MeditationUserFavorite meditationUserFavorite = new MeditationUserFavorite(); |
| | | meditationUserFavorite.setMeditationId(id); |
| | | meditationUserFavorite.setAppUserId(SecurityUtils.getUserId()); |
| | | meditationUserFavoriteService.save(meditationUserFavorite); |
| | | // 减少收藏数 |
| | | meditation.setFavoriteCount(meditation.getFavoriteCount() + 1); |
| | | } |
| | | this.updateById(meditation); |
| | | } |
| | | |
| | | /** |
| | | * 获取冥想音频提问列表-分页 |
| | | * |
| | | * @param id 冥想音频id |
| | | * @param pageCurr 当前页码 |
| | | * @param pageSize 每页数量 |
| | | * @return 冥想音频提问分页列表 |
| | | */ |
| | | @Override |
| | | public PageDTO<ClientMeditationQuestionVO> getMeditationQuestionPage(Long id, |
| | | Integer pageCurr, Integer pageSize) { |
| | | // 查询冥想提问列表 |
| | | Page<MeditationQuestion> questionPage = meditationQuestionMapper.selectPage( |
| | | new Page<>(pageCurr, pageSize), |
| | | Wrappers.lambdaQuery(MeditationQuestion.class) |
| | | .eq(MeditationQuestion::getMeditationId, id) |
| | | .eq(MeditationQuestion::getShowFlag, DisabledEnum.YES) |
| | | .orderByDesc(MeditationQuestion::getPublishTime) |
| | | ); |
| | | |
| | | if (CollUtils.isEmpty(questionPage.getRecords())) { |
| | | return PageDTO.empty(questionPage); |
| | | } |
| | | |
| | | // 将 questionPage 转换为 PageDTO |
| | | PageDTO<ClientMeditationQuestionVO> pageDTO = PageDTO.of( |
| | | questionPage, ClientMeditationQuestionVO.class); |
| | | List<ClientMeditationQuestionVO> questionVOList = pageDTO.getList(); |
| | | |
| | | // 提取用户ID集合 |
| | | Set<Long> appUserIdSet = questionVOList.stream() |
| | | .map(ClientMeditationQuestionVO::getAppUserId) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 远程调用,获取APP用户信息 |
| | | Map<Long, AppUser> appUserMap = Collections.emptyMap(); |
| | | if (!appUserIdSet.isEmpty()) { |
| | | List<AppUser> appUserList = remoteAppUserService.getAppUserList(appUserIdSet, |
| | | SecurityConstants.INNER) |
| | | .getData(); |
| | | appUserMap = appUserList.stream() |
| | | .collect(Collectors.toMap(AppUser::getId, Function.identity())); |
| | | } |
| | | |
| | | // 封装用户信息 |
| | | for (ClientMeditationQuestionVO questionVO : questionVOList) { |
| | | AppUser appUser = appUserMap.get(questionVO.getAppUserId()); |
| | | if (appUser != null) { |
| | | questionVO.setNickname(appUser.getNickname()); |
| | | questionVO.setAvatar(appUser.getAvatar()); |
| | | } |
| | | } |
| | | |
| | | // 获取当前登录用户ID |
| | | Long userId = SecurityUtils.getUserId(); |
| | | |
| | | // 查询用户已点赞提问列表 |
| | | Set<Long> likedQuestionIds = meditationQuestionLikeService.lambdaQuery() |
| | | .eq(MeditationQuestionLike::getAppUserId, userId) |
| | | .list() |
| | | .stream() |
| | | .map(MeditationQuestionLike::getMeditationQuestionId) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 设置问题的点赞状态 |
| | | questionVOList.forEach(question -> { |
| | | if (likedQuestionIds.contains(question.getId())) { |
| | | question.setLike(DisabledEnum.YES.getCode()); |
| | | } |
| | | }); |
| | | |
| | | return pageDTO; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.meditation.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.meditation.domain.MeditationUserFavorite; |
| | | import com.xinquan.meditation.mapper.MeditationUserFavoriteMapper; |
| | | import com.xinquan.meditation.service.MeditationUserFavoriteService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 冥想用户操作表 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Service |
| | | public class MeditationUserFavoriteServiceImpl extends |
| | | ServiceImpl<MeditationUserFavoriteMapper, MeditationUserFavorite> implements |
| | | MeditationUserFavoriteService { |
| | | |
| | | } |
| | |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="image_url" property="imageUrl" /> |
| | | <result column="audio_file" property="audioFile" /> |
| | | <result column="audio_file_name" property="audioFileName"/> |
| | | <result column="sort_num" property="sortNum" /> |
| | | </resultMap> |
| | | |
| | |
| | | <result column="detail_description" property="detailDescription" /> |
| | | <result column="cover_description" property="coverDescription" /> |
| | | <result column="tutor_audio_url" property="tutorAudioUrl" /> |
| | | <result column="like_count" property="likeCount" /> |
| | | <result column="favorite_count" property="favoriteCount" /> |
| | | </resultMap> |
| | | |
| | |
| | | update_time, |
| | | id, cate_id, meditation_title, listing_status, sanskrit, charge_type, sort_num, real_learned_num, virtual_learned_num, icon_url, cover_url, background_url, detail_description, cover_description, tutor_audio_url, like_count, favorite_count |
| | | </sql> |
| | | <select id="getMeditationListByTagId" |
| | | resultType="com.xinquan.meditation.domain.vo.ClientMeditationVO" |
| | | parameterType="java.util.Set"> |
| | | SELECT |
| | | <include refid="Base_Column_List"/> |
| | | FROM |
| | | t_meditation m |
| | | RIGHT JOIN t_meditation_tag mt ON m.id = mt.meditation_id |
| | | <where> |
| | | <if test="sanskritFlag != null and sanskritFlag == 2"> |
| | | AND m.sanskrit = #{sanskritFlag} |
| | | </if> |
| | | <if test="tagIdSet !=null and tagIdSet.size()>0"> |
| | | AND mt.tag_id IN (#{tagIdSet}) |
| | | </if> |
| | | </where> |
| | | ORDER BY sort_num DESC |
| | | </select> |
| | | |
| | | </mapper> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
| | | "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationQuestionLikeMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationQuestionLike"> |
| | | <id column="id" property="id"/> |
| | | <result column="create_by" property="createBy"/> |
| | | <result column="create_time" property="createTime"/> |
| | | <result column="meditation_question_id" property="meditationQuestionId"/> |
| | | <result column="app_user_id" property="appUserId"/> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | create_by, |
| | | create_time, |
| | | id, meditation_question_id, app_user_id |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationQuestion"> |
| | | <id column="id" property="id" /> |
| | | <result column="meditation_id" property="meditationId"/> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserFavoriteMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserFavorite"> |
| | | <id column="id" property="id" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | create_by, |
| | | create_time, |
| | | id, favorite, meditation_id, app_user_id |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | <artifactId>druid-spring-boot-starter</artifactId> |
| | | <version>${druid.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | |
| | | |
| | | <!--bouncycastle,AES加密依赖--> |
| | | <dependency> |
| | | <groupId>cn.afterturn</groupId> |
| | | <artifactId>easypoi-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>guava</artifactId> |
| | | <groupId>com.google.guava</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | <groupId>org.bouncycastle</groupId> |
| | | <artifactId>bcprov-jdk15on</artifactId> |
| | | <version>1.64</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | |
| | | package com.xinquan.order.controller.client; |
| | | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.order.service.OrderService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | |
| | | * @since 2024-08-21 |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @Api(tags = {"用户端-订单相关接口"}) |
| | | @RequestMapping("/client/order/order") |
| | | public class ClientOrderController { |
| | | |
| | | private OrderService orderService; |
| | | |
| | | @PostMapping("/createOrder") |
| | | @ApiOperation(value = "创建订单") |
| | | public R<?> createOrder() { |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.order.utils; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.security.Security; |
| | | import java.util.Base64; |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| | | |
| | | public class EncryptUtils { |
| | | |
| | | private static final String SECRET = "AES"; |
| | | private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding"; |
| | | |
| | | static { |
| | | Security.addProvider(new BouncyCastleProvider()); |
| | | } |
| | | |
| | | /** |
| | | * AES加密ECB模式PKCS7Padding填充方式 |
| | | * |
| | | * @param str 字符串 |
| | | * @param key 密钥 |
| | | * @return 加密字符串 |
| | | * @throws Exception 异常信息 |
| | | */ |
| | | public static String aes256ECBPkcs7PaddingEncrypt(String str, String key) throws Exception { |
| | | Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); |
| | | byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); |
| | | cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, SECRET)); |
| | | byte[] doFinal = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)); |
| | | return new String(Base64.getEncoder().encode(doFinal)); |
| | | } |
| | | |
| | | /** |
| | | * AES解密ECB模式PKCS7Padding填充方式 |
| | | * |
| | | * @param str 字符串 |
| | | * @param key 密钥 |
| | | * @return 解密字符串 |
| | | * @throws Exception 异常信息 |
| | | */ |
| | | public static String aes256ECBPkcs7PaddingDecrypt(String str, String key) throws Exception { |
| | | Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); |
| | | byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); |
| | | cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, SECRET)); |
| | | byte[] doFinal = cipher.doFinal(Base64.getDecoder().decode(str)); |
| | | return new String(doFinal); |
| | | } |
| | | |
| | | public static void main(String[] args) throws Exception { |
| | | String str = "a1234567"; |
| | | System.out.println("字符串:" + str); |
| | | String encryptStr = EncryptUtils.aes256ECBPkcs7PaddingEncrypt(str, "AES454-HTJSQ9-IT"); |
| | | System.out.println("加密后字符串:" + encryptStr); |
| | | String decryptStr = EncryptUtils.aes256ECBPkcs7PaddingDecrypt(encryptStr, |
| | | "AES454-HTJSQ9-IT"); |
| | | System.out.println("解密后字符串:" + decryptStr); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.order.utils; |
| | | |
| | | import cn.hutool.http.HttpRequest; |
| | | import cn.hutool.http.HttpResponse; |
| | | import cn.hutool.http.HttpUtil; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.xinquan.common.core.exception.ServiceException; |
| | | import com.xinquan.common.core.utils.DateUtils; |
| | | import com.xinquan.common.core.utils.StringUtils; |
| | | import java.security.KeyFactory; |
| | | import java.security.PrivateKey; |
| | | import java.security.Signature; |
| | | import java.security.spec.PKCS8EncodedKeySpec; |
| | | import java.util.Base64; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.TreeMap; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | /** |
| | | * 桔禾付支付工具类 |
| | | * |
| | | * @author mitao |
| | | * @date 2024/9/7 |
| | | */ |
| | | public class JuHeFuUtil { |
| | | |
| | | private static Logger logger = LoggerFactory.getLogger(JuHeFuUtil.class); |
| | | // 商户RSA私钥 TODO |
| | | private static final String MERCHANT_PRIVATE_KEY = ""; |
| | | // 平台RSA公钥 TODO |
| | | private static final String PLAT_PUBLIC_KEY = ""; |
| | | // 应用的app_id TODO |
| | | private static final String APP_ID = ""; |
| | | // 商户id TODO |
| | | private static final String MER_ID = ""; |
| | | // AES密钥 TODO |
| | | private static final String AES_KEY = ""; |
| | | // 创建用户接口 |
| | | private static final String CREATE_USER_INTERFACE = "/api/member/create_user_a"; |
| | | // 创建支付订单 |
| | | private static final String CREATE_PAYMENT_INTERFACE = "/api/payment/create_payment"; |
| | | // 退款接口 |
| | | private static final String PAYMENT_REFUND_INTERFACE = "/api/payment/payment_refund"; |
| | | private static final String MERCHANT_PAY_INTERFACE = "/api/account/merchant_pay"; |
| | | // 接口地址 TODO |
| | | private static final String BASE_URL = ""; |
| | | // 支付宝支付渠道 |
| | | private static final String PAY_CHANNEL_ALIPAY = "alipay_qr"; |
| | | // 微信支付渠道 |
| | | private static final String PAY_CHANNEL_WECHAT = "wx_lite"; |
| | | // 微信小程序id TODO |
| | | private static final String WX_APP_ID = ""; |
| | | |
| | | /** |
| | | * 创建用户 |
| | | * |
| | | * @param memberId 用户id |
| | | * @param memberP 用户信息 |
| | | * @return boolean |
| | | * @throws Exception |
| | | */ |
| | | public static boolean createUser(String memberId, Map<String, Object> memberP) |
| | | throws Exception { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("app_id", APP_ID); |
| | | data.put("member_id", memberId); |
| | | data.put("member_type", "01"); |
| | | data.put("member_p", memberP); |
| | | |
| | | JSONObject body = new JSONObject(); |
| | | body.put("merId", MER_ID); |
| | | body.put("sign", sign(JSONObject.toJSONString(data))); |
| | | body.put("reqCipher", |
| | | EncryptUtils.aes256ECBPkcs7PaddingEncrypt(JSONObject.toJSONString(data), AES_KEY)); |
| | | body.put("reqTime", DateUtils.dateTimeNow("yyyyMMddHHmmssfff")); |
| | | // 发送Post请求 |
| | | logger.info("桔禾付创建用户请求体====================>{}", body.toJSONString()); |
| | | String result = sendPost(BASE_URL + CREATE_USER_INTERFACE, body); |
| | | logger.info("桔禾付创建用户请求结果====================>{}", result); |
| | | if (StringUtils.isBlank(result)) { |
| | | throw new ServiceException("请求第三方支付平台异常"); |
| | | } |
| | | JSONObject resJsonObject = JSONObject.parseObject(result); |
| | | if (resJsonObject.getString("status").equals("succeeded")) { |
| | | return true; |
| | | } else if (resJsonObject.getString("status").equals("failed")) { |
| | | throw new ServiceException(resJsonObject.getString("error_msg")); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 创建支付订单 |
| | | * |
| | | * @param orderNo 订单号 |
| | | * @param payChannel 支付渠道 1:支付宝 2:微信 |
| | | * @param payAmt 支付金额 |
| | | * @param goodsTitle 商品标题 |
| | | * @param goodsDesc 商品描述信息,微信小程序和微信公众号该字段 最大长度 42 个字符 |
| | | * @param deviceIp 设备支付公网ip |
| | | * @param openId 微信openId |
| | | * @param notifyUrl 回调地址 |
| | | * @return JSONObject |
| | | * @throws Exception |
| | | */ |
| | | public JSONObject createPayment(String orderNo, Integer payChannel, String payAmt, |
| | | String goodsTitle, String goodsDesc, String deviceIp, String openId, |
| | | String notifyUrl) throws Exception { |
| | | JSONObject data = new JSONObject(); |
| | | JSONObject expand = new JSONObject(); |
| | | data.put("order_no", orderNo); |
| | | data.put("app_id", APP_ID); |
| | | data.put("mer_id", MER_ID); |
| | | if (payChannel == 1) { |
| | | data.put("pay_channel", PAY_CHANNEL_ALIPAY); |
| | | } else { |
| | | data.put("pay_channel", PAY_CHANNEL_WECHAT); |
| | | expand.put("open_id", openId); |
| | | expand.put("wx_app_id", WX_APP_ID); |
| | | data.put("expand", expand); |
| | | } |
| | | data.put("pay_amt", payAmt); |
| | | data.put("goods_title", goodsTitle); |
| | | data.put("goods_desc", goodsDesc); |
| | | Map<String, Object> deviceInfo = new HashMap<>(); |
| | | deviceInfo.put("device_ip", deviceIp); |
| | | data.put("device_info", deviceInfo); |
| | | data.put("notify_url", notifyUrl); |
| | | JSONObject body = new JSONObject(); |
| | | body.put("merId", MER_ID); |
| | | body.put("sign", sign(JSONObject.toJSONString(data))); |
| | | body.put("reqCipher", |
| | | EncryptUtils.aes256ECBPkcs7PaddingEncrypt(JSONObject.toJSONString(data), AES_KEY)); |
| | | body.put("reqTime", DateUtils.dateTimeNow("yyyyMMddHHmmssfff")); |
| | | String result = sendPost(BASE_URL + CREATE_PAYMENT_INTERFACE, body); |
| | | JSONObject resJsonObject = JSONObject.parseObject(result); |
| | | if (resJsonObject.getString("status").equals("failed")) { |
| | | throw new ServiceException(resJsonObject.getString("error_msg")); |
| | | } |
| | | if (resJsonObject.getString("status").equals("succeeded")) { |
| | | return resJsonObject.getJSONObject("expand"); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 申请退款 |
| | | * |
| | | * @param paymentId 支付单号 |
| | | * @param orderNo 订单号 |
| | | * @return |
| | | */ |
| | | public boolean refund(String paymentId, String orderNo) throws Exception { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("payment_id", paymentId); |
| | | data.put("order_no", orderNo); |
| | | JSONObject body = new JSONObject(); |
| | | body.put("merId", MER_ID); |
| | | body.put("sign", sign(JSONObject.toJSONString(data))); |
| | | body.put("reqCipher", |
| | | EncryptUtils.aes256ECBPkcs7PaddingEncrypt(JSONObject.toJSONString(data), AES_KEY)); |
| | | body.put("reqTime", DateUtils.dateTimeNow("yyyyMMddHHmmssfff")); |
| | | String result = sendPost(BASE_URL + PAYMENT_REFUND_INTERFACE, body); |
| | | JSONObject resJsonObject = JSONObject.parseObject(result); |
| | | if (resJsonObject.getString("status").equals("succeeded")) { |
| | | return true; |
| | | } else if (resJsonObject.getString("status").equals("failed")) { |
| | | throw new ServiceException(resJsonObject.getString("error_msg")); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 商户付款 |
| | | * |
| | | * @param orderNo 订单号 |
| | | * @param payAmt 交易金额 |
| | | * @param cardName 收款银行开户名 |
| | | * @param cardId 收款银行卡号 |
| | | * @param cardType 收款银行账户类型 DEBIT_CARD:借记卡 CREDIT_CARD:贷记卡 76 QUASI_CREDIT_CARD:准贷卡 PASSBOOK:存折 |
| | | * UNIT_SETTLE_CARD:单位结算卡 PUBLIC_CARD:对公卡 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public boolean merchantPay(String orderNo, String payAmt, String cardName, String cardId, |
| | | String cardType) |
| | | throws Exception { |
| | | JSONObject data = new JSONObject(); |
| | | data.put("order_no", orderNo); |
| | | data.put("pay_amt", payAmt); |
| | | data.put("card_name", cardName); |
| | | data.put("card_id", cardId); |
| | | JSONObject body = new JSONObject(); |
| | | body.put("merId", MER_ID); |
| | | body.put("sign", sign(JSONObject.toJSONString(data))); |
| | | body.put("reqCipher", |
| | | EncryptUtils.aes256ECBPkcs7PaddingEncrypt(JSONObject.toJSONString(data), AES_KEY)); |
| | | body.put("reqTime", DateUtils.dateTimeNow("yyyyMMddHHmmssfff")); |
| | | String result = sendPost(BASE_URL + MERCHANT_PAY_INTERFACE, body); |
| | | JSONObject resJsonObject = JSONObject.parseObject(result); |
| | | if (resJsonObject.getString("status").equals("succeeded")) { |
| | | return true; |
| | | } else if (resJsonObject.getString("status").equals("failed")) { |
| | | throw new ServiceException(resJsonObject.getString("error_msg")); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 发送post请求 |
| | | * |
| | | * @param url 请求地址 |
| | | * @param body 请求体 |
| | | * @return |
| | | */ |
| | | private static String sendPost(String url, JSONObject body) { |
| | | HttpRequest post = HttpUtil.createPost(url); |
| | | Map<String, String> headers = new HashMap<>(); |
| | | headers.put("Content-type", "application/json; charset=utf-8"); |
| | | headers.put("Accept", "application/json"); |
| | | post.addHeaders(headers); |
| | | post.body(body.toJSONString()); |
| | | HttpResponse execute = post.execute(); |
| | | String result = execute.body(); |
| | | execute.close(); |
| | | if (StringUtils.isBlank(result)) { |
| | | throw new ServiceException("请求第三方支付平台异常"); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * RSA私钥签名:签名方式SHA256WithRSA |
| | | * |
| | | * @param data 待签名字符串 |
| | | * @return 签名byte[] |
| | | * @throws Exception |
| | | */ |
| | | public static String sign(String data) { |
| | | // 先对该json对象数据按照参数字典顺序(参数名ASCII码从小到大排序,参数名区分大小写)排序生成字符串,再进行加签和验签。 |
| | | data = JSON.toJSONString(JSONObject.parseObject(data, TreeMap.class)); |
| | | |
| | | // Base64 --> Key |
| | | try { |
| | | byte[] bytes = Base64.getDecoder().decode(MERCHANT_PRIVATE_KEY); |
| | | PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes); |
| | | KeyFactory keyFactory; |
| | | keyFactory = KeyFactory.getInstance("RSA"); |
| | | PrivateKey privateKey = keyFactory.generatePrivate(keySpec); |
| | | // Sign |
| | | Signature signature = Signature.getInstance("SHA256WithRSA"); |
| | | signature.initSign(privateKey); |
| | | signature.update(data.getBytes("UTF-8")); |
| | | return Base64.getEncoder().encodeToString(signature.sign()); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.order.mapper.OrderMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.order.domain.Order"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="biz_order_no" property="bizOrderNo" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="business_id" property="businessId" /> |
| | | <result column="order_from" property="orderFrom" /> |
| | | <result column="payment_status" property="paymentStatus" /> |
| | | <result column="total_amount" property="totalAmount" /> |
| | | <result column="real_pay_amount" property="realPayAmount" /> |
| | | <result column="commission_amount" property="commissionAmount" /> |
| | | <result column="change_price" property="changePrice" /> |
| | | <result column="change_price_time" property="changePriceTime" /> |
| | | <result column="change_price_operator" property="changePriceOperator" /> |
| | | <result column="payment_time" property="paymentTime" /> |
| | | <result column="cancel_time" property="cancelTime" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | del_flag, |
| | | create_by, |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, biz_order_no, app_user_id, business_id, order_from, payment_status, total_amount, real_pay_amount, commission_amount, change_price, change_price_time, change_price_operator, payment_time, cancel_time |
| | | </sql> |
| | | |
| | | </mapper> |
copy from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml
copy to xinquan-modules/xinquan-order/src/main/resources/mapper/order/OrderPaymentRecordMapper.xml
File was copied from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserOperationMapper"> |
| | | <mapper namespace="com.xinquan.order.mapper.OrderPaymentRecordMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserOperation"> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.order.domain.OrderPaymentRecord"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="like" property="like" /> |
| | | <result column="favorite" property="favorite" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="order_id" property="orderId" /> |
| | | <result column="payment_type" property="paymentType" /> |
| | | <result column="pay_amount" property="payAmount" /> |
| | | <result column="pay_order_no" property="payOrderNo" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, like, favorite, meditation_id, app_user_id |
| | | id, order_id, payment_type, pay_amount, pay_order_no |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>cn.afterturn</groupId> |
| | | <artifactId>easypoi-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>guava</artifactId> |
| | | <groupId>com.google.guava</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <!-- <dependency> |
| | | <groupId>com.github.xiaoymin</groupId> |
| | | <artifactId>knife4j-spring-boot-starter</artifactId> |
| | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | import javax.annotation.Resource; |
| | |
| | | role.setMenuIds(dto.getMenuIds().toArray((new Long[dto.getMenuIds().size()]))); |
| | | // 添加角色 |
| | | role.setCreateBy(SecurityUtils.getUsername()); |
| | | role.setCreateTime(new Date()); |
| | | // role.setCreateTime(new Date()); |
| | | roleService.insertRole(role); |
| | | // ArrayList<SysRoleMenu> sysRoleMenus = new ArrayList<>(); |
| | | // List<Long> menuIds = dto.getMenuIds(); |
| | |
| | | } |
| | | // 编辑角色 |
| | | role.setUpdateBy(SecurityUtils.getUsername()); |
| | | role.setUpdateTime(new Date()); |
| | | // role.setUpdateTime(new Date()); |
| | | role.setRoleId(dto.getRoleId()); |
| | | roleService.updateRole(role); |
| | | ArrayList<SysRoleMenu> sysRoleMenus = new ArrayList<>(); |
| | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.io.IOException; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | |
| | | user.setUserName(user.getPhonenumber()); |
| | | } |
| | | user.setPassword(null); |
| | | user.setUpdateBy(SecurityUtils.getUsername()); |
| | | user.setUpdateTime(new Date()); |
| | | // user.setUpdateBy(SecurityUtils.getUsername()); |
| | | // user.setUpdateTime(new Date()); |
| | | return toAjax(userService.updateUser(user)); |
| | | } |
| | | |
| | |
| | | @PostMapping("/updateSysUser") |
| | | public R<Boolean> updateSysUser(@RequestBody SysUser sysUser) { |
| | | try { |
| | | sysUser.setUpdateBy(SecurityUtils.getUsername()); |
| | | sysUser.setUpdateTime(new Date()); |
| | | // sysUser.setUpdateBy(SecurityUtils.getUsername()); |
| | | // sysUser.setUpdateTime(new Date()); |
| | | userService.updateUser(sysUser); |
| | | return R.ok(true); |
| | | } catch (Exception e) { |
| | |
| | | return R.fail("保存用户'" + username + "'失败,注册账号已存在"); |
| | | } |
| | | //添加用户 |
| | | userService.save(sysUser); |
| | | userService.registerUser(sysUser); |
| | | return R.ok(sysUser); |
| | | } |
| | | /** |
| | |
| | | package com.xinquan.system.controller.client; |
| | | |
| | | import com.xinquan.common.core.web.domain.AjaxResult; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.system.domain.vo.ContentSettingVO; |
| | | import com.xinquan.system.service.PublicService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "key", value = "用户内容 1=用户协议 2=隐私协议 3=关于心泉 4=新手冥想指南 5=课程/冥想音频购买协议", |
| | | required = true, type = "Integer", paramType = "query")}) |
| | | public AjaxResult getContent( |
| | | public R<ContentSettingVO> getContent( |
| | | @RequestParam(value = "key", required = true) Integer key) { |
| | | return AjaxResult.success(publicService.getContent(key)); |
| | | return R.ok(publicService.getContent(key)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.system.controller.inner; |
| | | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.security.annotation.InnerAuth; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import com.xinquan.system.service.BannerService; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 轮播图控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/inner/system/banner") |
| | | public class InnerBannerController { |
| | | |
| | | private final BannerService bannerService; |
| | | |
| | | /** |
| | | * 获取轮播图列表 |
| | | * |
| | | * @return 轮播图列表 |
| | | */ |
| | | @InnerAuth |
| | | @GetMapping("/getBannerList") |
| | | public R<List<BannerVO>> getBannerList() { |
| | | return R.ok(bannerService.getBannerList()); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.system.controller.inner; |
| | | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.security.annotation.InnerAuth; |
| | | import com.xinquan.system.service.HotWordsService; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 热词表 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/inner/system/hot-words") |
| | | public class InnerHotWordsController { |
| | | |
| | | private final HotWordsService hotWordsService; |
| | | |
| | | /** |
| | | * 获取热词列表 |
| | | * |
| | | * @return 热词列表 |
| | | */ |
| | | @InnerAuth |
| | | @GetMapping("/getHotWordList") |
| | | public R<List<String>> getHotWordList() { |
| | | return R.ok(hotWordsService.getHotWordList()); |
| | | } |
| | | } |
| | | |
| | |
| | | package com.xinquan.system.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | package com.xinquan.system.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.xinquan.common.core.web.domain.BaseEntity; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import org.apache.commons.lang3.builder.ToStringBuilder; |
| | | import org.apache.commons.lang3.builder.ToStringStyle; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Size; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 菜单权限表 sys_menu |
| | |
| | | |
| | | /** 权限字符串 */ |
| | | private String perms; |
| | | |
| | | /** 菜单图标 */ |
| | | private String icon; |
| | | @TableField("create_by") |
| | | private String createBy; |
| | | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField("create_time") |
| | | private Date createTime; |
| | | |
| | | /** 更新者 */ |
| | | @ApiModelProperty(value = "记录修改人,前端忽略") |
| | | //@JsonIgnore |
| | | @TableField("update_by") |
| | | private String updateBy; |
| | | |
| | | /** 更新时间 */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @TableField("update_time") |
| | | private Date updateTime; |
| | | |
| | | /** 备注 */ |
| | | private String remark; |
| | |
| | | package com.xinquan.system.mapper; |
| | | |
| | | import com.xinquan.system.domain.HotWords; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xinquan.system.domain.HotWords; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | package com.xinquan.system.service; |
| | | |
| | | import com.xinquan.system.domain.Banner; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import com.xinquan.system.domain.Banner; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface BannerService extends IService<Banner> { |
| | | |
| | | /** |
| | | * 获取轮播图列表 |
| | | * |
| | | * @return 轮播图列表 |
| | | */ |
| | | List<BannerVO> getBannerList(); |
| | | } |
| | |
| | | package com.xinquan.system.service; |
| | | |
| | | import com.xinquan.system.domain.HotWords; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.system.domain.HotWords; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | public interface HotWordsService extends IService<HotWords> { |
| | | |
| | | /** |
| | | * 获取热词列表 |
| | | * |
| | | * @return 热词列表 |
| | | */ |
| | | List<String> getHotWordList(); |
| | | } |
| | |
| | | package com.xinquan.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.system.api.domain.vo.BannerVO; |
| | | import com.xinquan.system.domain.Banner; |
| | | import com.xinquan.system.mapper.BannerMapper; |
| | | import com.xinquan.system.service.BannerService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import java.util.List; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class BannerServiceImpl extends ServiceImpl<BannerMapper, Banner> implements BannerService { |
| | | |
| | | /** |
| | | * 获取轮播图列表 |
| | | * |
| | | * @return 轮播图列表 |
| | | */ |
| | | @Override |
| | | public List<BannerVO> getBannerList() { |
| | | List<Banner> list = this.lambdaQuery().orderByDesc(Banner::getSortNum).list(); |
| | | return BeanUtils.copyList(list, BannerVO.class); |
| | | } |
| | | } |
| | |
| | | package com.xinquan.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.utils.page.CollUtils; |
| | | import com.xinquan.system.domain.HotWords; |
| | | import com.xinquan.system.mapper.HotWordsMapper; |
| | | import com.xinquan.system.service.HotWordsService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class HotWordsServiceImpl extends ServiceImpl<HotWordsMapper, HotWords> implements HotWordsService { |
| | | |
| | | /** |
| | | * 获取热词列表 |
| | | * |
| | | * @return 热词列表 |
| | | */ |
| | | @Override |
| | | public List<String> getHotWordList() { |
| | | List<String> hotWordList = CollUtils.emptyList(); |
| | | List<HotWords> list = this.lambdaQuery().orderByDesc(HotWords::getSortNum).list(); |
| | | if (CollUtils.isNotEmpty(list)) { |
| | | hotWordList = list.stream().map(HotWords::getWordName).collect(Collectors.toList()); |
| | | } |
| | | return hotWordList; |
| | | } |
| | | } |
| | |
| | | <if test="status != null and status != ''">status,</if> |
| | | <if test="createBy != null and createBy != ''">create_by,</if> |
| | | <if test="remark != null and remark != ''">remark,</if> |
| | | <if test="userType != null and userType != ''">user_type,</if> |
| | | create_time |
| | | )values( |
| | | <if test="userId != null and userId != ''">#{userId},</if> |
| | |
| | | <if test="status != null and status != ''">#{status},</if> |
| | | <if test="createBy != null and createBy != ''">#{createBy},</if> |
| | | <if test="remark != null and remark != ''">#{remark},</if> |
| | | <if test="userType != null and userType != ''">#{user_type},</if> |
| | | sysdate() |
| | | ) |
| | | </insert> |
| | |
| | | <artifactId>fastjson</artifactId> |
| | | <version>1.2.47</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>cn.afterturn</groupId> |
| | | <artifactId>easypoi-spring-boot-starter</artifactId> |
| | | <version>4.0.0</version> |
| | | <exclusions> |
| | | <exclusion> |
| | | <artifactId>guava</artifactId> |
| | | <groupId>com.google.guava</groupId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | package com.xinquan.user.controller.client; |
| | | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.user.domain.dto.UserAnswerDTO; |
| | | import com.xinquan.user.domain.vo.AppUserVO; |
| | | import com.xinquan.user.domain.vo.TagVO; |
| | | import com.xinquan.user.service.AppUserService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import java.util.List; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.validation.annotation.Validated; |
| | | 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.RequestMapping; |
| | | |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | |
| | | * @author mitao |
| | | * @since 2024-08-21 |
| | | */ |
| | | @Api(tags = {"用户相关接口"}) |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/client/app-user") |
| | | @RequiredArgsConstructor |
| | | public class ClientAppUserController { |
| | | |
| | | private final AppUserService appUserService; |
| | | |
| | | /** |
| | | * 获取当前登录用户信息 |
| | | * |
| | | * @return 用户信息 |
| | | * @see com.xinquan.user.domain.vo.AppUserVO |
| | | */ |
| | | @PostMapping("/getCurrentUser") |
| | | @ApiOperation(value = "获取当前用户信息", tags = {"用户端-用户信息相关接口"}) |
| | | public R<AppUserVO> getCurrentUser() { |
| | | return R.ok(appUserService.getCurrentUser()); |
| | | } |
| | | |
| | | /** |
| | | * 获取问题二的标签列表 |
| | | * |
| | | * @return List<TagVO> |
| | | */ |
| | | @GetMapping("/getTagList") |
| | | @ApiOperation(value = "问题二获取用户标签列表", tags = {"用户端-计划引导相关接口"}) |
| | | public R<List<TagVO>> getTagList() { |
| | | List<TagVO> voList = appUserService.getTagList(); |
| | | return R.ok(voList); |
| | | } |
| | | |
| | | /** |
| | | * 保存计划引导页用户的答案 |
| | | * |
| | | * @param dto 用户计划引导答案数据传输对象 |
| | | * @return |
| | | */ |
| | | @PostMapping("/saveUserAnswers") |
| | | @ApiOperation(value = "保存计划引导页用户的答案", tags = {"用户端-计划引导相关接口"}) |
| | | public R<?> saveUserAnswers(@Validated @RequestBody UserAnswerDTO dto) { |
| | | appUserService.saveUserAnswers(dto); |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
New file |
| | |
| | | package com.xinquan.user.controller.client; |
| | | |
| | | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.user.service.AppUserViewingHistoryService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Api(tags = {"用户端-观看历史相关接口"}) |
| | | @RestController |
| | | @RequiredArgsConstructor |
| | | @RequestMapping("/user/app-user-viewing-history") |
| | | public class ClientAppUserViewingHistoryController { |
| | | |
| | | private final AppUserViewingHistoryService appUserViewingHistoryService; |
| | | |
| | | /** |
| | | * 记录用户观看记录 |
| | | * |
| | | * @param bizId 业务id |
| | | * @param viewingType 观看类型 1=疗愈 2=课程 |
| | | */ |
| | | @PostMapping("/saveViewingHistory") |
| | | @ApiOperation(value = "记录用户观看记录", tags = {"用户端-用户相关接口"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "bizId", value = "业务id", dataType = "Long", required = true), |
| | | @ApiImplicitParam(name = "viewingType", value = "观看类型 1=疗愈 2=课程", dataType = "Integer", required = true) |
| | | }) |
| | | public R<?> saveViewingRecord(@RequestParam("bizId") Long bizId, |
| | | @RequestParam("viewingType") Integer viewingType) { |
| | | appUserViewingHistoryService.saveViewingRecord(bizId, viewingType); |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
| | |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.security.annotation.InnerAuth; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.service.AppUserService; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/registerAppUser") |
| | | R<Boolean> registerAppUser(@RequestBody AppUserDTO appUserDTO){ |
| | | R<AppUser> registerAppUser(@RequestBody AppUserDTO appUserDTO) { |
| | | return R.ok(appUserService.registerAppUser(appUserDTO)); |
| | | } |
| | | |
| | |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/wxLogin") |
| | | R<WXLoginUser> wxLogin(@RequestBody AppWXLoginBody body) { |
| | | R<AppLoginUser> wxLogin(@RequestBody AppWXLoginBody body) { |
| | | return R.ok(appUserService.wxLogin(body)); |
| | | } |
| | | |
| | |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/appleLogin") |
| | | R<AppleLoginUser> appleLogin(@RequestParam("appleId") String appleId) { |
| | | R<AppLoginUser> appleLogin(@RequestParam("appleId") String appleId) { |
| | | return R.ok(appUserService.appleLogin(appleId)); |
| | | } |
| | | |
| | |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/captchaLogin") |
| | | R<LoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body) { |
| | | R<AppLoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body) { |
| | | return R.ok(appUserService.appCaptchaLogin(body)); |
| | | } |
| | | |
| | |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/verifyCellPhone") |
| | | R<WXLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body) { |
| | | R<AppLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body) { |
| | | return R.ok(appUserService.verifyCellPhone(body)); |
| | | } |
| | | |
| | | /** |
| | | * 更新APP用户信息 |
| | | * |
| | | * @param dto APP用户数据传输对象 |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/updateAppUser") |
| | | R<?> updateAppUser(@RequestBody AppUserDTO dto) { |
| | | appUserService.updateAppUser(dto); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 获取用户列表 |
| | | * |
| | | * @param appUserIdSet 用户id列表 |
| | | * @param source 请求来源 |
| | | * @return |
| | | */ |
| | | @InnerAuth |
| | | @PostMapping("/getAppUserList") |
| | | R<List<AppUser>> getAppUserList(@RequestBody Collection<Long> appUserIdSet) { |
| | | return R.ok(appUserService.listByIds(appUserIdSet)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.user.controller.management; |
| | | |
| | | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/user/app-user-viewing-history") |
| | | public class MgtAppUserViewingHistoryController { |
| | | |
| | | } |
| | | |
| | |
| | | package com.xinquan.user.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | |
| | | @ApiModelProperty(value = "回答 1:是2:否3:偶尔有") |
| | | @TableField("answer") |
| | | private Integer answer; |
| | | private String answer; |
| | | |
| | | @ApiModelProperty(value = "用户id") |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.user.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xinquan.common.core.web.domain.BaseModel; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @TableName("t_app_user_viewing_history") |
| | | @ApiModel(value = "AppUserViewingHistory对象", description = "用户观看历史") |
| | | public class AppUserViewingHistory extends BaseModel { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "用户树苗id") |
| | | @TableId("id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "用户id") |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | @ApiModelProperty(value = "业务id ") |
| | | @TableField("biz_id") |
| | | private Long bizId; |
| | | |
| | | @ApiModelProperty(value = "观看类型 1:疗愈 2:课程") |
| | | @TableField("viewing_type") |
| | | private Integer viewingType; |
| | | |
| | | |
| | | } |
| | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "标签类型") |
| | | @TableField(value = "tag_type") |
| | | private Integer tagType; |
| | | |
| | | @ApiModelProperty(value = "标签名称") |
| | | @TableField("tag_name") |
| | | private String tagName; |
New file |
| | |
| | | package com.xinquan.user.domain.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import javax.validation.Valid; |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotEmpty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/8/27 |
| | | */ |
| | | @Data |
| | | @ApiModel("用户计划引导答案数据传输对象") |
| | | public class UserAnswerDTO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -5037991196273819118L; |
| | | @Valid |
| | | @ApiModelProperty(value = "问题一答案", required = true) |
| | | @NotEmpty(message = "问题一答案不能为空") |
| | | private List<UserAnswerOneDTO> userAnswerOneDTOList; |
| | | |
| | | @ApiModelProperty(value = "问题二 多个tagId使用英文逗号拼接字符串", required = true) |
| | | @NotBlank(message = "问题二答案不能为空") |
| | | private String tagIds; |
| | | } |
New file |
| | |
| | | package com.xinquan.user.domain.dto; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/8/28 |
| | | */ |
| | | @Data |
| | | public class UserAnswerOneDTO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -8938108350024740351L; |
| | | |
| | | @ApiModelProperty("问题一 问题类型 1:您是否内心纠结敏感多疑?2:您是否辗转反侧彻夜难眠?3:您是否情绪失控暴躁易怒?" |
| | | + "4:您是否沉迷情感倍受伤害?5:您是否人生迷茫踌躇彷徨?6:其它补充说明") |
| | | @NotNull(message = "问题类型不能为空") |
| | | private Integer type; |
| | | |
| | | @ApiModelProperty("问题一 答案 1:是2:否3:偶尔,其他补充说明") |
| | | @NotBlank(message = "答案不能为空") |
| | | private String answer; |
| | | |
| | | } |
New file |
| | |
| | | package com.xinquan.user.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/7 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "用户信息VO") |
| | | public class AppUserVO implements Serializable { |
| | | |
| | | private static final long serialVersionUID = -6948932379350815750L; |
| | | |
| | | @ApiModelProperty(value = "App用户id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "系统用户id") |
| | | private Long userId; |
| | | |
| | | @ApiModelProperty(value = "手机号码") |
| | | private String cellPhone; |
| | | |
| | | @ApiModelProperty(value = "苹果授权登录唯一标识") |
| | | private String appleId; |
| | | |
| | | @ApiModelProperty(value = "微信openId") |
| | | private String wxOpenId; |
| | | |
| | | @ApiModelProperty(value = "头像") |
| | | private String avatar; |
| | | |
| | | @ApiModelProperty(value = "昵称") |
| | | private String nickname; |
| | | |
| | | @ApiModelProperty(value = "签名") |
| | | private String signature; |
| | | |
| | | @ApiModelProperty(value = "性别 1=男 2=女 3=保密") |
| | | private Integer gender; |
| | | |
| | | @ApiModelProperty(value = "生日") |
| | | private String birthday; |
| | | |
| | | @ApiModelProperty(value = "学历") |
| | | private String education; |
| | | |
| | | @ApiModelProperty(value = "行业") |
| | | private String industry; |
| | | |
| | | @ApiModelProperty(value = "公司") |
| | | private String company; |
| | | |
| | | @ApiModelProperty(value = "职业") |
| | | private String occupation; |
| | | |
| | | @ApiModelProperty(value = "所在地") |
| | | private String location; |
| | | |
| | | @ApiModelProperty(value = "故乡") |
| | | private String hometown; |
| | | |
| | | @ApiModelProperty(value = "邮箱") |
| | | private String email; |
| | | |
| | | @ApiModelProperty(value = "会员到期时间") |
| | | private LocalDateTime vipExpireTime; |
| | | |
| | | @ApiModelProperty(value = "用户状态 1=正常 2=冻结 3=注销") |
| | | private Integer userStatus; |
| | | |
| | | @ApiModelProperty(value = "冻结原因") |
| | | private String freezingReason; |
| | | |
| | | @ApiModelProperty(value = "冻结操作人") |
| | | private String freezingOperator; |
| | | |
| | | @ApiModelProperty(value = "梵文权限 1=是 2否") |
| | | private Integer sanskritFlag; |
| | | |
| | | @ApiModelProperty(value = "邀请人id") |
| | | private Long inviteUserId; |
| | | |
| | | @ApiModelProperty(value = "余额") |
| | | private BigDecimal balance; |
| | | |
| | | @ApiModelProperty(value = "收益") |
| | | private BigDecimal income; |
| | | |
| | | @ApiModelProperty(value = "当前累计能量值") |
| | | private Integer totalEnergyValue; |
| | | |
| | | @ApiModelProperty(value = "注册时间") |
| | | private LocalDateTime registerTime; |
| | | |
| | | @ApiModelProperty(value = "注销时间") |
| | | private LocalDateTime logoutTime; |
| | | |
| | | @ApiModelProperty(value = "用户等级id") |
| | | private Integer levelSettingId; |
| | | |
| | | @ApiModelProperty(value = "标签id,多个id使用英文逗号拼接") |
| | | private String tagId; |
| | | } |
New file |
| | |
| | | package com.xinquan.user.domain.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author mitao |
| | | * @date 2024/9/4 |
| | | */ |
| | | @Data |
| | | @ApiModel("问题二用户标签视图对象") |
| | | public class TagVO { |
| | | |
| | | @ApiModelProperty(value = "标签id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "标签名称") |
| | | private String tagName; |
| | | } |
New file |
| | |
| | | package com.xinquan.user.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xinquan.user.domain.AppUserViewingHistory; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface AppUserViewingHistoryMapper extends BaseMapper<AppUserViewingHistory> { |
| | | |
| | | } |
| | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.domain.dto.UserAnswerDTO; |
| | | import com.xinquan.user.domain.vo.AppUserVO; |
| | | import com.xinquan.user.domain.vo.TagVO; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | |
| | | /** |
| | |
| | | * @param appUserDTO |
| | | * @return |
| | | */ |
| | | Boolean registerAppUser(AppUserDTO appUserDTO); |
| | | AppUser registerAppUser(AppUserDTO appUserDTO); |
| | | |
| | | /** |
| | | * APP微信登录 |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | WXLoginUser wxLogin(AppWXLoginBody body); |
| | | AppLoginUser wxLogin(AppWXLoginBody body); |
| | | |
| | | /** |
| | | * 苹果登录 |
| | |
| | | * @param source |
| | | * @return |
| | | */ |
| | | AppleLoginUser appleLogin(String appleId); |
| | | AppLoginUser appleLogin(String appleId); |
| | | |
| | | /** |
| | | * 验证码登录 |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | LoginUser appCaptchaLogin(AppCaptchaBody body); |
| | | AppLoginUser appCaptchaLogin(AppCaptchaBody body); |
| | | |
| | | /** |
| | | * 微信苹果登录验证手机号码操作 |
| | |
| | | * @param body |
| | | * @return |
| | | */ |
| | | WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body); |
| | | AppLoginUser verifyCellPhone(AppVerifyCellPhoneBody body); |
| | | |
| | | /** |
| | | * 保存计划引导页用户的答案 |
| | | * |
| | | * @param dto 用户计划引导答案数据传输对象 |
| | | */ |
| | | void saveUserAnswers(UserAnswerDTO dto); |
| | | |
| | | /** |
| | | * 获取问题二的标签列表 |
| | | * |
| | | * @return List<TagVO> |
| | | */ |
| | | List<TagVO> getTagList(); |
| | | |
| | | /** |
| | | * 更新APP用户信息 |
| | | * |
| | | * @param dto APP用户数据传输对象 |
| | | */ |
| | | void updateAppUser(AppUserDTO dto); |
| | | |
| | | /** |
| | | * 获取当前登录用户信息 |
| | | * |
| | | * @return 用户信息 |
| | | * @see com.xinquan.user.domain.vo.AppUserVO |
| | | */ |
| | | AppUserVO getCurrentUser(); |
| | | } |
New file |
| | |
| | | package com.xinquan.user.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xinquan.user.domain.AppUserViewingHistory; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 服务类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | public interface AppUserViewingHistoryService extends IService<AppUserViewingHistory> { |
| | | |
| | | /** |
| | | * 记录用户观看记录 |
| | | * |
| | | * @param bizId 业务id |
| | | * @param viewingType 观看类型 1=疗愈 2=课程 |
| | | */ |
| | | void saveViewingRecord(Long bizId, Integer viewingType); |
| | | } |
| | |
| | | package com.xinquan.user.service.impl; |
| | | |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import com.alibaba.nacos.common.utils.StringUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.common.core.constant.Constants; |
| | | import com.xinquan.common.core.constant.SecurityConstants; |
| | | import com.xinquan.common.core.domain.R; |
| | | import com.xinquan.common.core.enums.AnswerTagEnum; |
| | | import com.xinquan.common.core.enums.AppUserStatusEnum; |
| | | import com.xinquan.common.core.enums.DisabledEnum; |
| | | import com.xinquan.common.core.enums.TreeLevelEnum; |
| | | import com.xinquan.common.core.exception.ServiceException; |
| | | import com.xinquan.common.core.utils.page.BeanUtils; |
| | | import com.xinquan.common.core.utils.page.CollUtils; |
| | | import com.xinquan.common.security.utils.SecurityUtils; |
| | | import com.xinquan.system.api.RemoteUserService; |
| | | import com.xinquan.system.api.domain.SysUser; |
| | | import com.xinquan.system.api.feignClient.SysUserClient; |
| | | import com.xinquan.system.api.model.AppCaptchaBody; |
| | | import com.xinquan.system.api.model.AppLoginUser; |
| | | import com.xinquan.system.api.model.AppVerifyCellPhoneBody; |
| | | import com.xinquan.system.api.model.AppWXLoginBody; |
| | | import com.xinquan.system.api.model.AppleLoginUser; |
| | | import com.xinquan.system.api.model.LoginUser; |
| | | import com.xinquan.system.api.model.WXLoginUser; |
| | | import com.xinquan.user.api.domain.AppUser; |
| | | import com.xinquan.user.api.domain.dto.AppUserDTO; |
| | | import com.xinquan.user.domain.AppUserQuestion; |
| | | import com.xinquan.user.domain.AppUserTree; |
| | | import com.xinquan.user.domain.Tag; |
| | | import com.xinquan.user.domain.dto.UserAnswerDTO; |
| | | import com.xinquan.user.domain.vo.AppUserVO; |
| | | import com.xinquan.user.domain.vo.TagVO; |
| | | import com.xinquan.user.mapper.AppUserMapper; |
| | | import com.xinquan.user.service.AppUserQuestionService; |
| | | import com.xinquan.user.service.AppUserService; |
| | | import com.xinquan.user.service.AppUserTreeService; |
| | | import com.xinquan.user.service.TagService; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import java.util.Objects; |
| | | import java.util.Optional; |
| | | import java.util.stream.Collectors; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | private final SysUserClient sysUserClient; |
| | | private final RemoteUserService remoteUserService; |
| | | private final AppUserTreeService appUserTreeService; |
| | | private final AppUserQuestionService appUserQuestionService; |
| | | private final TagService tagService; |
| | | /** |
| | | * 获取用户信息 |
| | | * |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | public Boolean registerAppUser(AppUserDTO appUserDTO) { |
| | | public AppUser registerAppUser(AppUserDTO appUserDTO) { |
| | | AppUser appUser = BeanUtils.copyBean(appUserDTO, AppUser.class); |
| | | return this.save(appUser); |
| | | this.save(appUser); |
| | | return appUser; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | public WXLoginUser wxLogin(AppWXLoginBody body) { |
| | | WXLoginUser wxLoginUser = new WXLoginUser(); |
| | | public AppLoginUser wxLogin(AppWXLoginBody body) { |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | Optional<AppUser> optionalAppUser = this.getUserByCondition( |
| | | AppUserDTO.builder().wxOpenId(body.getWxOpenId()).build()); |
| | | AppUser appUser; |
| | | SysUser sysUser; |
| | | // 存在账户,查询关联系统用户 |
| | | if (optionalAppUser.isPresent()) { |
| | | AppUser appUser = optionalAppUser.get(); |
| | | SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | wxLoginUser.setSysUser(sysUser); |
| | | if (Objects.nonNull(sysUser.getUserName())) { |
| | | wxLoginUser.setBindStatus(1); |
| | | wxLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | appUser = optionalAppUser.get(); |
| | | if (appUser.getUserStatus().equals(AppUserStatusEnum.FROZEN.getCode())) { |
| | | throw new ServiceException("账号已被冻结"); |
| | | } |
| | | sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | } else { |
| | | // 不存在账户,创建账户 |
| | | // 注册用户信息 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser = new SysUser(); |
| | | sysUser.setNickName(body.getNickname()); |
| | | sysUser.setAvatar(body.getHeadImgUrl()); |
| | | |
| | | sysUser.setUserName(body.getNickname()); |
| | | sysUser.setUserType("01"); // app用户 |
| | | R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser, |
| | | SecurityConstants.INNER); |
| | | if (registerResult.getCode() == Constants.FAIL) { |
| | | throw new ServiceException(registerResult.getMsg()); |
| | | } |
| | | SysUser sysUserRes = registerResult.getData(); |
| | | AppUser appUser = new AppUser(); |
| | | appUser = new AppUser(); |
| | | appUser.setUserId(sysUserRes.getUserId()); |
| | | appUser.setWxOpenId(body.getWxOpenId()); |
| | | appUser.setNickname(body.getNickname()); |
| | |
| | | this.save(appUser); |
| | | // 初始化用户树苗 |
| | | initUserTree(appUser.getId()); |
| | | wxLoginUser.setSysUser(null); |
| | | wxLoginUser.setBindStatus(DisabledEnum.NO.getCode()); |
| | | } |
| | | return wxLoginUser; |
| | | appLoginUser.setUserid(sysUser.getUserId()); |
| | | appLoginUser.setUsername(appUser.getNickname()); |
| | | appLoginUser.setAppUserId(appUser.getId()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | if (Objects.nonNull(sysUser.getUserName())) { |
| | | appLoginUser.setBindStatus(DisabledEnum.YES.getCode()); |
| | | appLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | } |
| | | return appLoginUser; |
| | | } |
| | | |
| | | @Override |
| | | public AppleLoginUser appleLogin(String appleId) { |
| | | AppleLoginUser appleLoginUser = new AppleLoginUser(); |
| | | public AppLoginUser appleLogin(String appleId) { |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | Optional<AppUser> optionalAppUser = this.getUserByCondition( |
| | | AppUserDTO.builder().appleId(appleId).build()); |
| | | SysUser sysUser; |
| | | AppUser appUser; |
| | | // 存在账户,查询关联系统用户 |
| | | if (optionalAppUser.isPresent()) { |
| | | AppUser appUser = optionalAppUser.get(); |
| | | SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | appleLoginUser.setSysUser(sysUser); |
| | | if (Objects.nonNull(sysUser.getUserName())) { |
| | | appleLoginUser.setBindStatus(1); |
| | | appleLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | } |
| | | appUser = optionalAppUser.get(); |
| | | sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | } else { |
| | | // 不存在账户,创建账户 |
| | | // 注册用户信息 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser = new SysUser(); |
| | | String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6); |
| | | sysUser.setNickName(nickname); |
| | | sysUser.setAvatar("qwer"); |
| | | |
| | | sysUser.setUserName(nickname); |
| | | sysUser.setUserType("01"); // app用户 |
| | | R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser, |
| | | SecurityConstants.INNER); |
| | | if (registerResult.getCode() == Constants.FAIL) { |
| | | throw new ServiceException(registerResult.getMsg()); |
| | | } |
| | | SysUser sysUserRes = registerResult.getData(); |
| | | AppUser appUser = new AppUser(); |
| | | appUser = new AppUser(); |
| | | appUser.setUserId(sysUserRes.getUserId()); |
| | | appUser.setNickname(nickname); |
| | | appUser.setAvatar("qwer"); // TODO 待完善默认头像 |
| | |
| | | this.save(appUser); |
| | | // 初始化用户树苗 |
| | | initUserTree(appUser.getId()); |
| | | appleLoginUser.setSysUser(null); |
| | | appleLoginUser.setBindStatus(DisabledEnum.NO.getCode()); |
| | | } |
| | | |
| | | return appleLoginUser; |
| | | appLoginUser.setUserid(sysUser.getUserId()); |
| | | appLoginUser.setUsername(appUser.getNickname()); |
| | | appLoginUser.setAppUserId(appUser.getId()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | if (Objects.nonNull(sysUser.getUserName())) { |
| | | appLoginUser.setBindStatus(DisabledEnum.YES.getCode()); |
| | | appLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | } |
| | | return appLoginUser; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public LoginUser appCaptchaLogin(AppCaptchaBody body) { |
| | | LoginUser loginUser = new LoginUser(); |
| | | public AppLoginUser appCaptchaLogin(AppCaptchaBody body) { |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | Optional<AppUser> optionalAppUser = this.getUserByCondition( |
| | | AppUserDTO.builder().cellPhone(body.getCellPhone()).build()); |
| | | AppUser appUser; |
| | | SysUser sysUser; |
| | | if (optionalAppUser.isPresent()) { |
| | | AppUser appUser = optionalAppUser.get(); |
| | | SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | loginUser.setSysUser(sysUser); |
| | | appUser = optionalAppUser.get(); |
| | | sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData(); |
| | | } else { |
| | | // 注册用户信息 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser = new SysUser(); |
| | | String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6); |
| | | sysUser.setNickName(nickname); |
| | | sysUser.setAvatar("qwer"); |
| | | sysUser.setUserName(body.getCellPhone()); |
| | | sysUser.setUserType("01"); // app用户 |
| | | // 设置默认密码123456 |
| | | sysUser.setPassword(SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWORD)); |
| | | |
| | |
| | | throw new ServiceException(registerResult.getMsg()); |
| | | } |
| | | SysUser sysUserRes = registerResult.getData(); |
| | | AppUser appUser = new AppUser(); |
| | | appUser = new AppUser(); |
| | | appUser.setUserId(sysUserRes.getUserId()); |
| | | appUser.setNickname(nickname); |
| | | appUser.setCellPhone(body.getCellPhone()); |
| | |
| | | this.save(appUser); |
| | | // 初始化用户树苗 |
| | | initUserTree(appUser.getId()); |
| | | |
| | | } |
| | | return loginUser; |
| | | appLoginUser.setUserid(sysUser.getUserId()); |
| | | appLoginUser.setUsername(appUser.getNickname()); |
| | | appLoginUser.setAppUserId(appUser.getId()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | appLoginUser.setCellPhone(appUser.getCellPhone()); |
| | | return appLoginUser; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | @Override |
| | | public WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { |
| | | public AppLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) { |
| | | Integer loginType = body.getLoginType(); |
| | | String wxOrAppleId = body.getWxOrAppleId(); |
| | | SysUser sysUser; |
| | |
| | | } |
| | | sysUser.setUserName(body.getCellPhone()); |
| | | sysUser.setPassword( |
| | | SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWORD)); // 默认密码为123456 |
| | | SecurityUtils.encryptPassword( |
| | | SecureUtil.md5(Constants.DEFAULT_PASSWORD).toUpperCase( |
| | | Locale.ROOT))) |
| | | ; // 默认密码为123456 |
| | | sysUser.setPhonenumber(body.getCellPhone()); |
| | | sysUserClient.updateSysUser(sysUser); |
| | | } |
| | | // 更新用户信息 |
| | | this.updateById(appUser); |
| | | if (loginType.equals(1)) { |
| | | // 微信登录 |
| | | WXLoginUser wxLoginUser = new WXLoginUser(); |
| | | wxLoginUser.setBindStatus(1); |
| | | wxLoginUser.setCellPhone(body.getCellPhone()); |
| | | wxLoginUser.setSysUser(sysUser); |
| | | return wxLoginUser; |
| | | } else { |
| | | // 苹果登录 |
| | | AppleLoginUser appleLoginUser = new AppleLoginUser(); |
| | | appleLoginUser.setBindStatus(1); |
| | | appleLoginUser.setCellPhone(body.getCellPhone()); |
| | | appleLoginUser.setSysUser(sysUser); |
| | | return appleLoginUser; |
| | | } |
| | | AppLoginUser appLoginUser = new AppLoginUser(); |
| | | appLoginUser.setBindStatus(1); |
| | | appLoginUser.setCellPhone(body.getCellPhone()); |
| | | appLoginUser.setSysUser(sysUser); |
| | | return appLoginUser; |
| | | } |
| | | |
| | | // 定义一个方法来处理用户不存在的情况 |
| | | private void handleUserNotPresent(Optional<AppUser> userOptional, String errorMessage) { |
| | | if (!userOptional.isPresent()) { |
| | |
| | | return this.lambdaQuery() |
| | | .eq(loginType.equals(1), AppUser::getWxOpenId, wxOrAppleId) |
| | | .eq(loginType.equals(2), AppUser::getAppleId, wxOrAppleId) |
| | | .ne(AppUser::getUserStatus, AppUserStatusEnum.LOGOUT) |
| | | .ne(AppUser::getUserStatus, AppUserStatusEnum.LOGOUT.getCode()) |
| | | .oneOpt(); |
| | | } |
| | | |
| | | /** |
| | | * 保存计划引导页用户的答案 |
| | | * |
| | | * @param dto 用户计划引导答案数据传输对象 |
| | | */ |
| | | @Override |
| | | public void saveUserAnswers(UserAnswerDTO dto) { |
| | | // 获取当前登录用户 |
| | | Long userId = SecurityUtils.getUserId(); |
| | | AppUser appUser = this.getUserBySysUserId(userId); |
| | | List<AppUserQuestion> appUserQuestionList = BeanUtils.copyList( |
| | | dto.getUserAnswerOneDTOList(), AppUserQuestion.class); |
| | | // 查询用户已填写的答案 |
| | | List<AppUserQuestion> baseAppUserQuestionList = appUserQuestionService.lambdaQuery() |
| | | .eq(AppUserQuestion::getAppUserId, appUser.getUserId()) |
| | | .list(); |
| | | if (CollUtils.isNotEmpty(baseAppUserQuestionList)) { |
| | | // 根据类型更新答案 |
| | | for (AppUserQuestion appUserQuestion : appUserQuestionList) { |
| | | Optional<AppUserQuestion> baseAppUserQuestionOptional = baseAppUserQuestionList.stream() |
| | | .filter(baseAppUserQuestion -> baseAppUserQuestion.getType() |
| | | .equals(appUserQuestion.getType())).findFirst(); |
| | | baseAppUserQuestionOptional.ifPresent( |
| | | userQuestion -> appUserQuestion.setId(userQuestion.getId())); |
| | | } |
| | | } |
| | | appUserQuestionService.saveOrUpdateBatch(appUserQuestionList); |
| | | // 筛选答案为是和偶尔有的问题,为用户设置对应的标签 |
| | | List<AppUserQuestion> appUserQuestionYesList = appUserQuestionList.stream() |
| | | .filter(appUserQuestion -> appUserQuestion.getAnswer().equals("1") |
| | | || appUserQuestion.getAnswer().equals("3")).collect(Collectors.toList()); |
| | | StringBuilder sb = new StringBuilder(); |
| | | // 使用 StringBuilder 提高字符串拼接效率 |
| | | if (CollUtils.isNotEmpty(appUserQuestionYesList)) { |
| | | List<Long> tagIdList = appUserQuestionYesList.stream() |
| | | .map(appUserQuestion -> AnswerTagEnum.getEnumByCode(appUserQuestion.getType()) |
| | | .getTagId()).collect(Collectors.toList()); |
| | | if (CollUtils.isNotEmpty(tagIdList)) { |
| | | sb.append(CollUtils.join(tagIdList, ",")); |
| | | } |
| | | } |
| | | sb.append(","); |
| | | sb.append(dto.getTagIds()); |
| | | appUser.setTagId(sb.toString()); |
| | | this.updateById(appUser); |
| | | } |
| | | |
| | | /** |
| | | * 获取AppUser |
| | | * |
| | | * @param userId 系统用户userId |
| | | * @return AppUser |
| | | */ |
| | | private AppUser getUserBySysUserId(Long userId) { |
| | | Optional<AppUser> appUserOptional = this.lambdaQuery().eq(AppUser::getUserId, userId) |
| | | .oneOpt(); |
| | | if (!appUserOptional.isPresent()) { |
| | | throw new ServiceException("获取用户信息失败,请重新登录"); |
| | | } |
| | | return appUserOptional.get(); |
| | | } |
| | | |
| | | /** |
| | | * 获取问题二的标签列表 |
| | | * |
| | | * @return List<TagVO> |
| | | */ |
| | | @Override |
| | | public List<TagVO> getTagList() { |
| | | List<Tag> list = tagService.list(Wrappers.lambdaQuery(Tag.class).eq(Tag::getTagType, 2)); |
| | | return BeanUtils.copyList(list, TagVO.class); |
| | | } |
| | | |
| | | /** |
| | | * 更新APP用户信息 |
| | | * |
| | | * @param dto APP用户数据传输对象 |
| | | */ |
| | | @Override |
| | | public void updateAppUser(AppUserDTO dto) { |
| | | // 拷贝数据 |
| | | AppUser appUser = BeanUtils.copyBean(dto, AppUser.class); |
| | | this.updateById(appUser); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前登录用户信息 |
| | | * |
| | | * @return 用户信息 |
| | | * @see com.xinquan.user.domain.vo.AppUserVO |
| | | */ |
| | | @Override |
| | | public AppUserVO getCurrentUser() { |
| | | AppUser appUser = this.getById(SecurityUtils.getUserId()); |
| | | return BeanUtils.copyBean(appUser, AppUserVO.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xinquan.user.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xinquan.user.domain.AppUserViewingHistory; |
| | | import com.xinquan.user.mapper.AppUserViewingHistoryMapper; |
| | | import com.xinquan.user.service.AppUserViewingHistoryService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户观看历史 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2024-09-06 |
| | | */ |
| | | @Service |
| | | public class AppUserViewingHistoryServiceImpl extends |
| | | ServiceImpl<AppUserViewingHistoryMapper, AppUserViewingHistory> implements |
| | | AppUserViewingHistoryService { |
| | | |
| | | /** |
| | | * 记录用户观看记录 |
| | | * |
| | | * @param bizId 业务id |
| | | * @param viewingType 观看类型 1=疗愈 2=课程 |
| | | */ |
| | | @Override |
| | | public void saveViewingRecord(Long bizId, Integer viewingType) { |
| | | AppUserViewingHistory appUserViewingHistory = new AppUserViewingHistory(); |
| | | appUserViewingHistory.setBizId(bizId); |
| | | appUserViewingHistory.setViewingType(viewingType); |
| | | this.save(appUserViewingHistory); |
| | | } |
| | | } |
| | |
| | | <result column="register_time" property="registerTime" /> |
| | | <result column="logout_time" property="logoutTime" /> |
| | | <result column="level_setting_id" property="levelSettingId" /> |
| | | <result column="tag_id" property="tagId"/> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, user_id, cell_phone, apple_id, open_id, avatar, nickname, signature, gender, birthday, education, industry, company, occupation, location, hometown, email, vip_expire_time, user_status, freezing_reason, freezing_operator, sanskrit_flag, invite_user_id, balance, total_energy_value, register_time, logout_time, level_setting_id |
| | | id, user_id, cell_phone, apple_id, open_id, avatar, nickname, signature, gender, birthday, education, industry, company, occupation, location, hometown, email, vip_expire_time, user_status, freezing_reason, freezing_operator, sanskrit_flag, invite_user_id, balance, total_energy_value, register_time, logout_time, level_setting_id,tag_id |
| | | </sql> |
| | | |
| | | </mapper> |
File was renamed from xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xinquan.meditation.mapper.MeditationUserOperationMapper"> |
| | | <mapper namespace="com.xinquan.user.mapper.AppUserViewingHistoryMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.MeditationUserOperation"> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.user.domain.AppUserViewingHistory"> |
| | | <id column="id" property="id" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="like" property="like" /> |
| | | <result column="favorite" property="favorite" /> |
| | | <result column="meditation_id" property="meditationId" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="biz_id" property="bizId" /> |
| | | <result column="viewing_type" property="viewingType" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, like, favorite, meditation_id, app_user_id |
| | | id, app_user_id, biz_id, viewing_type |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xinquan.user.domain.Tag"> |
| | | <id column="id" property="id" /> |
| | | <id column="tag_type" property="tagType"/> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="create_time" property="createTime" /> |
| | |
| | | create_time, |
| | | update_by, |
| | | update_time, |
| | | id, tag_name |
| | | id, tag_name,tag_type |
| | | </sql> |
| | | |
| | | </mapper> |