瀏覽代碼

Merge branch 'develop'

songfuqiang 2 年之前
父節點
當前提交
62163ce0c7
共有 59 個文件被更改,包括 8946 次插入35 次删除
  1. 1 0
      backend-common/src/main/java/constant/CommonConstant.java
  2. 30 0
      backend-common/src/main/java/pojo/AppRequestParam.java
  3. 100 0
      backend-common/src/main/java/pojo/AppResultMap.java
  4. 51 0
      backend-common/src/main/java/pojo/Device.java
  5. 52 0
      backend-common/src/main/java/pojo/Location.java
  6. 16 0
      backend-common/src/main/java/pojo/Relationship.java
  7. 2 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/constant/MissionConstant.java
  8. 13 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/controller/AuthController.java
  9. 82 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/controller/MembersController.java
  10. 45 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/enums/ProviderEnum.java
  11. 33 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/AdvertisementsMapper.java
  12. 33 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/DevicesMapper.java
  13. 25 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/LocationsMapper.java
  14. 25 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/SocialAccountsMapper.java
  15. 364 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Advertisements.java
  16. 1431 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/AdvertisementsExample.java
  17. 292 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Devices.java
  18. 1191 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/DevicesExample.java
  19. 257 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Locations.java
  20. 1042 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/LocationsExample.java
  21. 202 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/SocialAccounts.java
  22. 831 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/model/SocialAccountsExample.java
  23. 27 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/params/AppLoginParam.java
  24. 28 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/params/BindAccountParam.java
  25. 29 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/params/RelationParam.java
  26. 17 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/AvatarUrlsVo.java
  27. 16 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/BindAccountVo.java
  28. 23 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/LoginInfoVo.java
  29. 23 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/MemberVo.java
  30. 18 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/SocialAccountVo.java
  31. 53 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/Tencent.java
  32. 19 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/TencentMe.java
  33. 27 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/Wechat.java
  34. 9 1
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/AuthService.java
  35. 33 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/DeviceService.java
  36. 30 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/LocationService.java
  37. 35 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/MemberService.java
  38. 55 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/SocialAccountService.java
  39. 243 11
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/AuthServiceImpl.java
  40. 68 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/DeviceServiceImpl.java
  41. 57 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/LocationServiceImpl.java
  42. 161 8
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MemberServiceImpl.java
  43. 2 1
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MissionFileServiceImpl.java
  44. 1 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MissionServiceImpl.java
  45. 3 3
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/OrderServiceImpl.java
  46. 149 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/SocialAccountServiceImpl.java
  47. 248 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/HttpClientUtils.java
  48. 81 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/TencentUtils.java
  49. 43 0
      backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/WechatUtils.java
  50. 1 1
      backend-core/src/main/resources/application-local-db.properties
  51. 1 1
      backend-core/src/main/resources/application-local.yml
  52. 6 3
      backend-core/src/main/resources/application-test-db.properties
  53. 1 1
      backend-core/src/main/resources/application-test.yml
  54. 1 1
      backend-core/src/main/resources/application.yml
  55. 11 4
      backend-core/src/main/resources/generatorConfig.xml
  56. 432 0
      backend-core/src/main/resources/sqlmap/AdvertisementsMapper.xml
  57. 367 0
      backend-core/src/main/resources/sqlmap/DevicesMapper.xml
  58. 273 0
      backend-core/src/main/resources/sqlmap/LocationsMapper.xml
  59. 237 0
      backend-core/src/main/resources/sqlmap/SocialAccountsMapper.xml

+ 1 - 0
backend-common/src/main/java/constant/CommonConstant.java

@@ -35,6 +35,7 @@ public interface CommonConstant {
     String STRING_NO_CACHE = "No-cache";
     int SUCCESS = 200;
     String RESULT_SUCCESS = "success";
+    String APP_CODE = "PDF Reader";
     String CODE_SUCCESS = "SUCCESS";
     String PAGE_INFO = "pageInfo";
 

+ 30 - 0
backend-common/src/main/java/pojo/AppRequestParam.java

@@ -0,0 +1,30 @@
+package pojo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class AppRequestParam<T> {
+
+    /**
+     * 客户端id
+     */
+    @JsonProperty("client_id")
+    private String clientId;
+
+    /**
+     * 客户端密码
+     */
+    @JsonProperty("client_secret")
+    private String clientSecret;
+
+    /**
+     * 业务参数
+     */
+    private T data;
+
+}

+ 100 - 0
backend-common/src/main/java/pojo/AppResultMap.java

@@ -0,0 +1,100 @@
+package pojo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import constant.CommonConstant;
+import lombok.Data;
+import utils.JsonUtils;
+
+import java.util.Objects;
+
+/**
+ * @author songfuqiang
+ * @description app返回包装类
+ */
+@Data
+public class AppResultMap<T> {
+
+    private int code;
+    private String msg;
+    private String appCode;
+    private T data;
+
+    public AppResultMap() {
+        code = CommonConstant.SUCCESS;
+        msg = CommonConstant.RESULT_SUCCESS;
+        appCode = CommonConstant.APP_CODE;
+    }
+
+    public AppResultMap(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+        this.appCode = CommonConstant.APP_CODE;
+    }
+
+    public AppResultMap(int code, String msg, T data) {
+        super();
+        this.code = code;
+        this.msg = msg;
+        this.appCode = CommonConstant.APP_CODE;
+        this.data = data;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public String getAppCode() {
+        return appCode;
+    }
+
+    public void setAppCode(String appCode) {
+        this.appCode = appCode;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        AppResultMap<?> resultMap = (AppResultMap<?>) o;
+        return code == resultMap.code &&
+                Objects.equals(msg, resultMap.msg) &&
+                Objects.equals(data, resultMap.data);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(code, msg, data);
+    }
+
+
+    @Override
+    public String toString() {
+        return JsonUtils.getJsonString(this);
+    }
+
+    @JsonIgnore
+    public boolean isSuccess() {
+        return this.code == CommonConstant.SUCCESS;
+    }
+
+}

+ 51 - 0
backend-common/src/main/java/pojo/Device.java

@@ -0,0 +1,51 @@
+package pojo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class Device {
+
+    /**
+     * app版本号
+     */
+    @JsonProperty("app_version")
+    private String appVersion;
+
+    /**
+     * 语言
+     */
+    private String language;
+
+    /**
+     * 手机型号
+     */
+    private String model;
+
+    /**
+     * 系统
+     */
+    private String os;
+
+    /**
+     * 注册id
+     */
+    @JsonProperty("register_id")
+    private String registerId;
+
+    /**
+     * 时区
+     */
+    @JsonProperty("time_zone")
+    private String timeZone;
+
+    /**
+     * uuid
+     */
+    private String uuid;
+
+}

+ 52 - 0
backend-common/src/main/java/pojo/Location.java

@@ -0,0 +1,52 @@
+package pojo;
+
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class Location {
+
+    /**
+     * 城市
+     */
+    private String city;
+
+    /**
+     * 国家
+     */
+    private String country;
+
+    /**
+     * 区
+     */
+    private String district;
+
+    /**
+     * 纬度
+     */
+    private String latitude;
+
+    /**
+     * 经度
+     */
+    private String longitude;
+
+    /**
+     * 省份
+     */
+    private String state;
+
+    /**
+     * 街道
+     */
+    private String street;
+
+    /**
+     * 邮编
+     */
+    private String zip;
+
+}

+ 16 - 0
backend-common/src/main/java/pojo/Relationship.java

@@ -0,0 +1,16 @@
+package pojo;
+
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class Relationship {
+
+    private Device device;
+
+    private Location location;
+
+}

+ 2 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/constant/MissionConstant.java

@@ -10,4 +10,6 @@ public interface MissionConstant {
     String EXCEPTION_MSG_NO_ENOUGH_CREDIT = "No Enough Credit";
 
     String LOCK_KEY = "PRE_DEDUCTION_LOCK_KEY_";
+
+    String UNKNOWN_ERROR_MSG = "未知错误,如重试失败请进官方客服QQ群:188917181获得即时帮助。";
 }

+ 13 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/controller/AuthController.java

@@ -3,10 +3,14 @@ package cn.kdan.pdf.backend.core.controller;
 import cn.kdan.pdf.backend.core.constant.AuthConstant;
 import cn.kdan.pdf.backend.core.enums.CaptchaActionEnum;
 import cn.kdan.pdf.backend.core.enums.VerifyTypeEnum;
+import cn.kdan.pdf.backend.core.params.RelationParam;
+import cn.kdan.pdf.backend.core.pojo.app.LoginInfoVo;
 import cn.kdan.pdf.backend.core.pojo.oauth2.TokenPOJO;
 import cn.kdan.pdf.backend.core.service.AuthService;
 import constant.CommonConstant;
 import org.springframework.web.bind.annotation.*;
+import pojo.AppRequestParam;
+import pojo.AppResultMap;
 import pojo.ResultMap;
 
 import javax.annotation.Resource;
@@ -91,5 +95,14 @@ public class AuthController {
         return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS,authService.checkExist(key,account,code));
     }
 
+    /**
+     * app端登录
+     * @param param 登录参数
+     * @return 返回token
+     */
+    @PostMapping("/appGetToken")
+    public AppResultMap<LoginInfoVo> appGetToken(@RequestBody AppRequestParam<RelationParam> param){
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,authService.appGetToken(param.getData()));
+    }
 
 }

+ 82 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/controller/MembersController.java

@@ -1,16 +1,26 @@
 package cn.kdan.pdf.backend.core.controller;
 
+import cn.kdan.pdf.backend.core.constant.AuthConstant;
 import cn.kdan.pdf.backend.core.constant.MembersConstant;
+import cn.kdan.pdf.backend.core.enums.CaptchaActionEnum;
 import cn.kdan.pdf.backend.core.model.Members;
 import cn.kdan.pdf.backend.core.model.member.MemberInfoResp;
 import cn.kdan.pdf.backend.core.model.member.MemberRegisterReq;
 import cn.kdan.pdf.backend.core.model.member.MemberRegisterResp;
 import cn.kdan.pdf.backend.core.model.member.ModifyPasswordReq;
+import cn.kdan.pdf.backend.core.params.BindAccountParam;
 import cn.kdan.pdf.backend.core.params.UserResetPwdParams;
+import cn.kdan.pdf.backend.core.pojo.app.BindAccountVo;
+import cn.kdan.pdf.backend.core.pojo.app.MemberVo;
+import cn.kdan.pdf.backend.core.service.AuthService;
 import cn.kdan.pdf.backend.core.service.MemberService;
+import com.sun.org.apache.xpath.internal.objects.XString;
 import constant.CommonConstant;
+import exception.BackendRuntimeException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+import pojo.AppRequestParam;
+import pojo.AppResultMap;
 import pojo.ResultMap;
 
 /**
@@ -22,6 +32,8 @@ public class MembersController {
 
     @Autowired
     private MemberService memberService;
+    @Autowired
+    private AuthService authService;
 
     /**
      * 用户注册
@@ -98,4 +110,74 @@ public class MembersController {
         }
     }
 
+
+    /**
+     * 用于忘记密码时检查重置密码连接是否失效
+     *
+     * @param account 邮箱
+     * @param code 验证码
+     * @return Boolean
+     */
+    @PostMapping("checkResetPasswordValid")
+    public ResultMap<Boolean> checkResetPasswordValid(@RequestParam String account,@RequestParam String code ) {
+        if (!authService.checkVerifyCode(CaptchaActionEnum.FORGET_PASSWORD.value(), account, code)) {
+            throw new BackendRuntimeException(AuthConstant.EXCEPTION_MSG_RESET_PASSWORD_ERROR);
+        }
+        return new ResultMap<>(CommonConstant.SUCCESS, CommonConstant.RESULT_SUCCESS, true);
+    }
+
+    /**
+     * 注销账号
+     * @return 提示信息
+     */
+    @GetMapping("/cancelAccount")
+    public AppResultMap<String> cancelAccount(){
+        String memberid = memberService.cancelAccount();
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,"注销账号成功");
+    }
+
+    /**
+     * 绑定账号
+     * @param param 入参
+     * @return 绑定信息
+     */
+    @PostMapping("/bindAccount")
+    public AppResultMap<BindAccountVo> bindAccount(@RequestBody AppRequestParam<BindAccountParam> param){
+        BindAccountVo bindAccountVo = memberService.bindAccount(param.getData());
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,bindAccountVo);
+    }
+
+    /**
+     * 解绑账号
+     * @param param 入参
+     * @return 解绑信息
+     */
+    @PostMapping("/unbindAccount")
+    public AppResultMap<BindAccountVo> unbindAccount(@RequestBody AppRequestParam<BindAccountParam> param){
+        BindAccountVo bindAccountVo = memberService.unbindAccount(param.getData());
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,bindAccountVo);
+    }
+
+    /**
+     * app端获取用户信息
+     * @param subscription 1:不显示订阅信息 0:显示订阅信息
+     * @param withSocial 如果是QQ、微信登录,传入字段可实现第三方登录的信息。0:不显示, 1:显示
+     * @return 用户信息
+     */
+    @GetMapping("appGetMemberInfo")
+    public AppResultMap<MemberInfoResp> appGetMemberInfo(@RequestParam("subscription") String subscription, @RequestParam("withSocial") String withSocial){
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,memberService.getMemberDetail(null));
+    }
+
+    /**
+     * app端修改昵称
+     * @param param 用户输入新昵称
+     * @return 用户信息
+     */
+    @PutMapping("appModifyName")
+    public AppResultMap<MemberVo> appModifyName(@RequestParam("name") AppRequestParam<String> param){
+        return new AppResultMap<>(CommonConstant.SUCCESS,CommonConstant.CODE_SUCCESS,memberService.appModifyName(param.getData()));
+    }
+
+
 }

+ 45 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/enums/ProviderEnum.java

@@ -0,0 +1,45 @@
+package cn.kdan.pdf.backend.core.enums;
+
+/**
+ * tencent: 0, wechat: 1, weibo: 2, facebook: 3, twitter: 4, line: 5, linked_in: 6, google: 7
+ * @author SongFuQiang
+ * @description
+ */
+public enum ProviderEnum {
+
+    /**
+     * 腾讯QQ
+     */
+    TENCENT("tencent",0),
+
+    /**
+     * 微信
+     */
+    WECHAT("wechat",1);
+
+    private final String name;
+    private final Integer value;
+
+    ProviderEnum(String name, Integer value){
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public static Integer getCodeByName(String name){
+        Integer value = 0;
+        for (ProviderEnum providerEnum : ProviderEnum.values()) {
+            if(providerEnum.getName().equals(name)){
+                value = providerEnum.getValue();
+            }
+        }
+        return value;
+    }
+}

+ 33 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/AdvertisementsMapper.java

@@ -0,0 +1,33 @@
+package cn.kdan.pdf.backend.core.mapper;
+
+import cn.kdan.pdf.backend.core.model.Advertisements;
+import cn.kdan.pdf.backend.core.model.AdvertisementsExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
+
+public interface AdvertisementsMapper {
+    long countByExample(AdvertisementsExample example);
+
+    int deleteByExample(AdvertisementsExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(Advertisements record);
+
+    int insertSelective(Advertisements record);
+
+    List<Advertisements> selectByExampleWithRowbounds(AdvertisementsExample example, RowBounds rowBounds);
+
+    List<Advertisements> selectByExample(AdvertisementsExample example);
+
+    Advertisements selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") Advertisements record, @Param("example") AdvertisementsExample example);
+
+    int updateByExample(@Param("record") Advertisements record, @Param("example") AdvertisementsExample example);
+
+    int updateByPrimaryKeySelective(Advertisements record);
+
+    int updateByPrimaryKey(Advertisements record);
+}

+ 33 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/DevicesMapper.java

@@ -0,0 +1,33 @@
+package cn.kdan.pdf.backend.core.mapper;
+
+import cn.kdan.pdf.backend.core.model.Devices;
+import cn.kdan.pdf.backend.core.model.DevicesExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
+
+public interface DevicesMapper {
+    long countByExample(DevicesExample example);
+
+    int deleteByExample(DevicesExample example);
+
+    int deleteByPrimaryKey(String id);
+
+    int insert(Devices record);
+
+    int insertSelective(Devices record);
+
+    List<Devices> selectByExampleWithRowbounds(DevicesExample example, RowBounds rowBounds);
+
+    List<Devices> selectByExample(DevicesExample example);
+
+    Devices selectByPrimaryKey(String id);
+
+    int updateByExampleSelective(@Param("record") Devices record, @Param("example") DevicesExample example);
+
+    int updateByExample(@Param("record") Devices record, @Param("example") DevicesExample example);
+
+    int updateByPrimaryKeySelective(Devices record);
+
+    int updateByPrimaryKey(Devices record);
+}

+ 25 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/LocationsMapper.java

@@ -0,0 +1,25 @@
+package cn.kdan.pdf.backend.core.mapper;
+
+import cn.kdan.pdf.backend.core.model.Locations;
+import cn.kdan.pdf.backend.core.model.LocationsExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
+
+public interface LocationsMapper {
+    long countByExample(LocationsExample example);
+
+    int deleteByExample(LocationsExample example);
+
+    int insert(Locations record);
+
+    int insertSelective(Locations record);
+
+    List<Locations> selectByExampleWithRowbounds(LocationsExample example, RowBounds rowBounds);
+
+    List<Locations> selectByExample(LocationsExample example);
+
+    int updateByExampleSelective(@Param("record") Locations record, @Param("example") LocationsExample example);
+
+    int updateByExample(@Param("record") Locations record, @Param("example") LocationsExample example);
+}

+ 25 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/mapper/SocialAccountsMapper.java

@@ -0,0 +1,25 @@
+package cn.kdan.pdf.backend.core.mapper;
+
+import cn.kdan.pdf.backend.core.model.SocialAccounts;
+import cn.kdan.pdf.backend.core.model.SocialAccountsExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
+
+public interface SocialAccountsMapper {
+    long countByExample(SocialAccountsExample example);
+
+    int deleteByExample(SocialAccountsExample example);
+
+    int insert(SocialAccounts record);
+
+    int insertSelective(SocialAccounts record);
+
+    List<SocialAccounts> selectByExampleWithRowbounds(SocialAccountsExample example, RowBounds rowBounds);
+
+    List<SocialAccounts> selectByExample(SocialAccountsExample example);
+
+    int updateByExampleSelective(@Param("record") SocialAccounts record, @Param("example") SocialAccountsExample example);
+
+    int updateByExample(@Param("record") SocialAccounts record, @Param("example") SocialAccountsExample example);
+}

+ 364 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Advertisements.java

@@ -0,0 +1,364 @@
+package cn.kdan.pdf.backend.core.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class Advertisements implements Serializable {
+    private String id;
+
+    private String slug;
+
+    private String title;
+
+    private String description;
+
+    private String image;
+
+    private String dimension;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private String linkText;
+
+    private String linkUrl;
+
+    private Integer totalHits;
+
+    private Integer language;
+
+    private Date startDate;
+
+    private Date endDate;
+
+    private String displayType;
+
+    private Float startHour;
+
+    private Float endHour;
+
+    private String extraInfo;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public Advertisements withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getSlug() {
+        return slug;
+    }
+
+    public Advertisements withSlug(String slug) {
+        this.setSlug(slug);
+        return this;
+    }
+
+    public void setSlug(String slug) {
+        this.slug = slug;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public Advertisements withTitle(String title) {
+        this.setTitle(title);
+        return this;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public Advertisements withDescription(String description) {
+        this.setDescription(description);
+        return this;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public Advertisements withImage(String image) {
+        this.setImage(image);
+        return this;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    public String getDimension() {
+        return dimension;
+    }
+
+    public Advertisements withDimension(String dimension) {
+        this.setDimension(dimension);
+        return this;
+    }
+
+    public void setDimension(String dimension) {
+        this.dimension = dimension;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public Advertisements withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public Advertisements withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getLinkText() {
+        return linkText;
+    }
+
+    public Advertisements withLinkText(String linkText) {
+        this.setLinkText(linkText);
+        return this;
+    }
+
+    public void setLinkText(String linkText) {
+        this.linkText = linkText;
+    }
+
+    public String getLinkUrl() {
+        return linkUrl;
+    }
+
+    public Advertisements withLinkUrl(String linkUrl) {
+        this.setLinkUrl(linkUrl);
+        return this;
+    }
+
+    public void setLinkUrl(String linkUrl) {
+        this.linkUrl = linkUrl;
+    }
+
+    public Integer getTotalHits() {
+        return totalHits;
+    }
+
+    public Advertisements withTotalHits(Integer totalHits) {
+        this.setTotalHits(totalHits);
+        return this;
+    }
+
+    public void setTotalHits(Integer totalHits) {
+        this.totalHits = totalHits;
+    }
+
+    public Integer getLanguage() {
+        return language;
+    }
+
+    public Advertisements withLanguage(Integer language) {
+        this.setLanguage(language);
+        return this;
+    }
+
+    public void setLanguage(Integer language) {
+        this.language = language;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public Advertisements withStartDate(Date startDate) {
+        this.setStartDate(startDate);
+        return this;
+    }
+
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public Advertisements withEndDate(Date endDate) {
+        this.setEndDate(endDate);
+        return this;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getDisplayType() {
+        return displayType;
+    }
+
+    public Advertisements withDisplayType(String displayType) {
+        this.setDisplayType(displayType);
+        return this;
+    }
+
+    public void setDisplayType(String displayType) {
+        this.displayType = displayType;
+    }
+
+    public Float getStartHour() {
+        return startHour;
+    }
+
+    public Advertisements withStartHour(Float startHour) {
+        this.setStartHour(startHour);
+        return this;
+    }
+
+    public void setStartHour(Float startHour) {
+        this.startHour = startHour;
+    }
+
+    public Float getEndHour() {
+        return endHour;
+    }
+
+    public Advertisements withEndHour(Float endHour) {
+        this.setEndHour(endHour);
+        return this;
+    }
+
+    public void setEndHour(Float endHour) {
+        this.endHour = endHour;
+    }
+
+    public String getExtraInfo() {
+        return extraInfo;
+    }
+
+    public Advertisements withExtraInfo(String extraInfo) {
+        this.setExtraInfo(extraInfo);
+        return this;
+    }
+
+    public void setExtraInfo(String extraInfo) {
+        this.extraInfo = extraInfo;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        Advertisements other = (Advertisements) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getSlug() == null ? other.getSlug() == null : this.getSlug().equals(other.getSlug()))
+            && (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle()))
+            && (this.getDescription() == null ? other.getDescription() == null : this.getDescription().equals(other.getDescription()))
+            && (this.getImage() == null ? other.getImage() == null : this.getImage().equals(other.getImage()))
+            && (this.getDimension() == null ? other.getDimension() == null : this.getDimension().equals(other.getDimension()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+            && (this.getLinkText() == null ? other.getLinkText() == null : this.getLinkText().equals(other.getLinkText()))
+            && (this.getLinkUrl() == null ? other.getLinkUrl() == null : this.getLinkUrl().equals(other.getLinkUrl()))
+            && (this.getTotalHits() == null ? other.getTotalHits() == null : this.getTotalHits().equals(other.getTotalHits()))
+            && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
+            && (this.getStartDate() == null ? other.getStartDate() == null : this.getStartDate().equals(other.getStartDate()))
+            && (this.getEndDate() == null ? other.getEndDate() == null : this.getEndDate().equals(other.getEndDate()))
+            && (this.getDisplayType() == null ? other.getDisplayType() == null : this.getDisplayType().equals(other.getDisplayType()))
+            && (this.getStartHour() == null ? other.getStartHour() == null : this.getStartHour().equals(other.getStartHour()))
+            && (this.getEndHour() == null ? other.getEndHour() == null : this.getEndHour().equals(other.getEndHour()))
+            && (this.getExtraInfo() == null ? other.getExtraInfo() == null : this.getExtraInfo().equals(other.getExtraInfo()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getSlug() == null) ? 0 : getSlug().hashCode());
+        result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode());
+        result = prime * result + ((getDescription() == null) ? 0 : getDescription().hashCode());
+        result = prime * result + ((getImage() == null) ? 0 : getImage().hashCode());
+        result = prime * result + ((getDimension() == null) ? 0 : getDimension().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        result = prime * result + ((getLinkText() == null) ? 0 : getLinkText().hashCode());
+        result = prime * result + ((getLinkUrl() == null) ? 0 : getLinkUrl().hashCode());
+        result = prime * result + ((getTotalHits() == null) ? 0 : getTotalHits().hashCode());
+        result = prime * result + ((getLanguage() == null) ? 0 : getLanguage().hashCode());
+        result = prime * result + ((getStartDate() == null) ? 0 : getStartDate().hashCode());
+        result = prime * result + ((getEndDate() == null) ? 0 : getEndDate().hashCode());
+        result = prime * result + ((getDisplayType() == null) ? 0 : getDisplayType().hashCode());
+        result = prime * result + ((getStartHour() == null) ? 0 : getStartHour().hashCode());
+        result = prime * result + ((getEndHour() == null) ? 0 : getEndHour().hashCode());
+        result = prime * result + ((getExtraInfo() == null) ? 0 : getExtraInfo().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", slug=").append(slug);
+        sb.append(", title=").append(title);
+        sb.append(", description=").append(description);
+        sb.append(", image=").append(image);
+        sb.append(", dimension=").append(dimension);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", linkText=").append(linkText);
+        sb.append(", linkUrl=").append(linkUrl);
+        sb.append(", totalHits=").append(totalHits);
+        sb.append(", language=").append(language);
+        sb.append(", startDate=").append(startDate);
+        sb.append(", endDate=").append(endDate);
+        sb.append(", displayType=").append(displayType);
+        sb.append(", startHour=").append(startHour);
+        sb.append(", endHour=").append(endHour);
+        sb.append(", extraInfo=").append(extraInfo);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

File diff suppressed because it is too large
+ 1431 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/AdvertisementsExample.java


+ 292 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Devices.java

@@ -0,0 +1,292 @@
+package cn.kdan.pdf.backend.core.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class Devices implements Serializable {
+    private String id;
+
+    private String memberId;
+
+    private String uuid;
+
+    private String model;
+
+    private String os;
+
+    private String timeZone;
+
+    private String language;
+
+    private String registerId;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private Integer lockVersion;
+
+    private Integer status;
+
+    private String appVersion;
+
+    private String clientUid;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public Devices withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMemberId() {
+        return memberId;
+    }
+
+    public Devices withMemberId(String memberId) {
+        this.setMemberId(memberId);
+        return this;
+    }
+
+    public void setMemberId(String memberId) {
+        this.memberId = memberId;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public Devices withUuid(String uuid) {
+        this.setUuid(uuid);
+        return this;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public Devices withModel(String model) {
+        this.setModel(model);
+        return this;
+    }
+
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public Devices withOs(String os) {
+        this.setOs(os);
+        return this;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public String getTimeZone() {
+        return timeZone;
+    }
+
+    public Devices withTimeZone(String timeZone) {
+        this.setTimeZone(timeZone);
+        return this;
+    }
+
+    public void setTimeZone(String timeZone) {
+        this.timeZone = timeZone;
+    }
+
+    public String getLanguage() {
+        return language;
+    }
+
+    public Devices withLanguage(String language) {
+        this.setLanguage(language);
+        return this;
+    }
+
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+
+    public String getRegisterId() {
+        return registerId;
+    }
+
+    public Devices withRegisterId(String registerId) {
+        this.setRegisterId(registerId);
+        return this;
+    }
+
+    public void setRegisterId(String registerId) {
+        this.registerId = registerId;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public Devices withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public Devices withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public Integer getLockVersion() {
+        return lockVersion;
+    }
+
+    public Devices withLockVersion(Integer lockVersion) {
+        this.setLockVersion(lockVersion);
+        return this;
+    }
+
+    public void setLockVersion(Integer lockVersion) {
+        this.lockVersion = lockVersion;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public Devices withStatus(Integer status) {
+        this.setStatus(status);
+        return this;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getAppVersion() {
+        return appVersion;
+    }
+
+    public Devices withAppVersion(String appVersion) {
+        this.setAppVersion(appVersion);
+        return this;
+    }
+
+    public void setAppVersion(String appVersion) {
+        this.appVersion = appVersion;
+    }
+
+    public String getClientUid() {
+        return clientUid;
+    }
+
+    public Devices withClientUid(String clientUid) {
+        this.setClientUid(clientUid);
+        return this;
+    }
+
+    public void setClientUid(String clientUid) {
+        this.clientUid = clientUid;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        Devices other = (Devices) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getMemberId() == null ? other.getMemberId() == null : this.getMemberId().equals(other.getMemberId()))
+            && (this.getUuid() == null ? other.getUuid() == null : this.getUuid().equals(other.getUuid()))
+            && (this.getModel() == null ? other.getModel() == null : this.getModel().equals(other.getModel()))
+            && (this.getOs() == null ? other.getOs() == null : this.getOs().equals(other.getOs()))
+            && (this.getTimeZone() == null ? other.getTimeZone() == null : this.getTimeZone().equals(other.getTimeZone()))
+            && (this.getLanguage() == null ? other.getLanguage() == null : this.getLanguage().equals(other.getLanguage()))
+            && (this.getRegisterId() == null ? other.getRegisterId() == null : this.getRegisterId().equals(other.getRegisterId()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
+            && (this.getLockVersion() == null ? other.getLockVersion() == null : this.getLockVersion().equals(other.getLockVersion()))
+            && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
+            && (this.getAppVersion() == null ? other.getAppVersion() == null : this.getAppVersion().equals(other.getAppVersion()))
+            && (this.getClientUid() == null ? other.getClientUid() == null : this.getClientUid().equals(other.getClientUid()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getMemberId() == null) ? 0 : getMemberId().hashCode());
+        result = prime * result + ((getUuid() == null) ? 0 : getUuid().hashCode());
+        result = prime * result + ((getModel() == null) ? 0 : getModel().hashCode());
+        result = prime * result + ((getOs() == null) ? 0 : getOs().hashCode());
+        result = prime * result + ((getTimeZone() == null) ? 0 : getTimeZone().hashCode());
+        result = prime * result + ((getLanguage() == null) ? 0 : getLanguage().hashCode());
+        result = prime * result + ((getRegisterId() == null) ? 0 : getRegisterId().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        result = prime * result + ((getLockVersion() == null) ? 0 : getLockVersion().hashCode());
+        result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
+        result = prime * result + ((getAppVersion() == null) ? 0 : getAppVersion().hashCode());
+        result = prime * result + ((getClientUid() == null) ? 0 : getClientUid().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", memberId=").append(memberId);
+        sb.append(", uuid=").append(uuid);
+        sb.append(", model=").append(model);
+        sb.append(", os=").append(os);
+        sb.append(", timeZone=").append(timeZone);
+        sb.append(", language=").append(language);
+        sb.append(", registerId=").append(registerId);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", lockVersion=").append(lockVersion);
+        sb.append(", status=").append(status);
+        sb.append(", appVersion=").append(appVersion);
+        sb.append(", clientUid=").append(clientUid);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

File diff suppressed because it is too large
+ 1191 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/DevicesExample.java


+ 257 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/Locations.java

@@ -0,0 +1,257 @@
+package cn.kdan.pdf.backend.core.model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+public class Locations implements Serializable {
+    private String id;
+
+    private String memberId;
+
+    private BigDecimal longitude;
+
+    private BigDecimal latitude;
+
+    private String country;
+
+    private String state;
+
+    private String city;
+
+    private String district;
+
+    private String street;
+
+    private String zip;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public Locations withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMemberId() {
+        return memberId;
+    }
+
+    public Locations withMemberId(String memberId) {
+        this.setMemberId(memberId);
+        return this;
+    }
+
+    public void setMemberId(String memberId) {
+        this.memberId = memberId;
+    }
+
+    public BigDecimal getLongitude() {
+        return longitude;
+    }
+
+    public Locations withLongitude(BigDecimal longitude) {
+        this.setLongitude(longitude);
+        return this;
+    }
+
+    public void setLongitude(BigDecimal longitude) {
+        this.longitude = longitude;
+    }
+
+    public BigDecimal getLatitude() {
+        return latitude;
+    }
+
+    public Locations withLatitude(BigDecimal latitude) {
+        this.setLatitude(latitude);
+        return this;
+    }
+
+    public void setLatitude(BigDecimal latitude) {
+        this.latitude = latitude;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public Locations withCountry(String country) {
+        this.setCountry(country);
+        return this;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public Locations withState(String state) {
+        this.setState(state);
+        return this;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public Locations withCity(String city) {
+        this.setCity(city);
+        return this;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getDistrict() {
+        return district;
+    }
+
+    public Locations withDistrict(String district) {
+        this.setDistrict(district);
+        return this;
+    }
+
+    public void setDistrict(String district) {
+        this.district = district;
+    }
+
+    public String getStreet() {
+        return street;
+    }
+
+    public Locations withStreet(String street) {
+        this.setStreet(street);
+        return this;
+    }
+
+    public void setStreet(String street) {
+        this.street = street;
+    }
+
+    public String getZip() {
+        return zip;
+    }
+
+    public Locations withZip(String zip) {
+        this.setZip(zip);
+        return this;
+    }
+
+    public void setZip(String zip) {
+        this.zip = zip;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public Locations withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public Locations withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        Locations other = (Locations) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getMemberId() == null ? other.getMemberId() == null : this.getMemberId().equals(other.getMemberId()))
+            && (this.getLongitude() == null ? other.getLongitude() == null : this.getLongitude().equals(other.getLongitude()))
+            && (this.getLatitude() == null ? other.getLatitude() == null : this.getLatitude().equals(other.getLatitude()))
+            && (this.getCountry() == null ? other.getCountry() == null : this.getCountry().equals(other.getCountry()))
+            && (this.getState() == null ? other.getState() == null : this.getState().equals(other.getState()))
+            && (this.getCity() == null ? other.getCity() == null : this.getCity().equals(other.getCity()))
+            && (this.getDistrict() == null ? other.getDistrict() == null : this.getDistrict().equals(other.getDistrict()))
+            && (this.getStreet() == null ? other.getStreet() == null : this.getStreet().equals(other.getStreet()))
+            && (this.getZip() == null ? other.getZip() == null : this.getZip().equals(other.getZip()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getMemberId() == null) ? 0 : getMemberId().hashCode());
+        result = prime * result + ((getLongitude() == null) ? 0 : getLongitude().hashCode());
+        result = prime * result + ((getLatitude() == null) ? 0 : getLatitude().hashCode());
+        result = prime * result + ((getCountry() == null) ? 0 : getCountry().hashCode());
+        result = prime * result + ((getState() == null) ? 0 : getState().hashCode());
+        result = prime * result + ((getCity() == null) ? 0 : getCity().hashCode());
+        result = prime * result + ((getDistrict() == null) ? 0 : getDistrict().hashCode());
+        result = prime * result + ((getStreet() == null) ? 0 : getStreet().hashCode());
+        result = prime * result + ((getZip() == null) ? 0 : getZip().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", memberId=").append(memberId);
+        sb.append(", longitude=").append(longitude);
+        sb.append(", latitude=").append(latitude);
+        sb.append(", country=").append(country);
+        sb.append(", state=").append(state);
+        sb.append(", city=").append(city);
+        sb.append(", district=").append(district);
+        sb.append(", street=").append(street);
+        sb.append(", zip=").append(zip);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

File diff suppressed because it is too large
+ 1042 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/LocationsExample.java


+ 202 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/SocialAccounts.java

@@ -0,0 +1,202 @@
+package cn.kdan.pdf.backend.core.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class SocialAccounts implements Serializable {
+    private String id;
+
+    private String memberId;
+
+    private Integer provider;
+
+    private String accountId;
+
+    private String name;
+
+    private String email;
+
+    private String avatar;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+
+    private static final long serialVersionUID = 1L;
+
+    public String getId() {
+        return id;
+    }
+
+    public SocialAccounts withId(String id) {
+        this.setId(id);
+        return this;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMemberId() {
+        return memberId;
+    }
+
+    public SocialAccounts withMemberId(String memberId) {
+        this.setMemberId(memberId);
+        return this;
+    }
+
+    public void setMemberId(String memberId) {
+        this.memberId = memberId;
+    }
+
+    public Integer getProvider() {
+        return provider;
+    }
+
+    public SocialAccounts withProvider(Integer provider) {
+        this.setProvider(provider);
+        return this;
+    }
+
+    public void setProvider(Integer provider) {
+        this.provider = provider;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public SocialAccounts withAccountId(String accountId) {
+        this.setAccountId(accountId);
+        return this;
+    }
+
+    public void setAccountId(String accountId) {
+        this.accountId = accountId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public SocialAccounts withName(String name) {
+        this.setName(name);
+        return this;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public SocialAccounts withEmail(String email) {
+        this.setEmail(email);
+        return this;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public SocialAccounts withAvatar(String avatar) {
+        this.setAvatar(avatar);
+        return this;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public SocialAccounts withCreatedAt(Date createdAt) {
+        this.setCreatedAt(createdAt);
+        return this;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public SocialAccounts withUpdatedAt(Date updatedAt) {
+        this.setUpdatedAt(updatedAt);
+        return this;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        SocialAccounts other = (SocialAccounts) that;
+        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
+            && (this.getMemberId() == null ? other.getMemberId() == null : this.getMemberId().equals(other.getMemberId()))
+            && (this.getProvider() == null ? other.getProvider() == null : this.getProvider().equals(other.getProvider()))
+            && (this.getAccountId() == null ? other.getAccountId() == null : this.getAccountId().equals(other.getAccountId()))
+            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
+            && (this.getEmail() == null ? other.getEmail() == null : this.getEmail().equals(other.getEmail()))
+            && (this.getAvatar() == null ? other.getAvatar() == null : this.getAvatar().equals(other.getAvatar()))
+            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
+            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
+        result = prime * result + ((getMemberId() == null) ? 0 : getMemberId().hashCode());
+        result = prime * result + ((getProvider() == null) ? 0 : getProvider().hashCode());
+        result = prime * result + ((getAccountId() == null) ? 0 : getAccountId().hashCode());
+        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
+        result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode());
+        result = prime * result + ((getAvatar() == null) ? 0 : getAvatar().hashCode());
+        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
+        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", memberId=").append(memberId);
+        sb.append(", provider=").append(provider);
+        sb.append(", accountId=").append(accountId);
+        sb.append(", name=").append(name);
+        sb.append(", email=").append(email);
+        sb.append(", avatar=").append(avatar);
+        sb.append(", createdAt=").append(createdAt);
+        sb.append(", updatedAt=").append(updatedAt);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 831 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/model/SocialAccountsExample.java

@@ -0,0 +1,831 @@
+package cn.kdan.pdf.backend.core.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class SocialAccountsExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    public SocialAccountsExample() {
+        oredCriteria = new ArrayList<Criteria>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<Criterion>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(String value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(String value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(String value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(String value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(String value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(String value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLike(String value) {
+            addCriterion("id like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotLike(String value) {
+            addCriterion("id not like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<String> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<String> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(String value1, String value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(String value1, String value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdIsNull() {
+            addCriterion("member_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdIsNotNull() {
+            addCriterion("member_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdEqualTo(String value) {
+            addCriterion("member_id =", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdNotEqualTo(String value) {
+            addCriterion("member_id <>", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdGreaterThan(String value) {
+            addCriterion("member_id >", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdGreaterThanOrEqualTo(String value) {
+            addCriterion("member_id >=", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdLessThan(String value) {
+            addCriterion("member_id <", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdLessThanOrEqualTo(String value) {
+            addCriterion("member_id <=", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdLike(String value) {
+            addCriterion("member_id like", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdNotLike(String value) {
+            addCriterion("member_id not like", value, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdIn(List<String> values) {
+            addCriterion("member_id in", values, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdNotIn(List<String> values) {
+            addCriterion("member_id not in", values, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdBetween(String value1, String value2) {
+            addCriterion("member_id between", value1, value2, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdNotBetween(String value1, String value2) {
+            addCriterion("member_id not between", value1, value2, "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderIsNull() {
+            addCriterion("provider is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderIsNotNull() {
+            addCriterion("provider is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderEqualTo(Integer value) {
+            addCriterion("provider =", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderNotEqualTo(Integer value) {
+            addCriterion("provider <>", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderGreaterThan(Integer value) {
+            addCriterion("provider >", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderGreaterThanOrEqualTo(Integer value) {
+            addCriterion("provider >=", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderLessThan(Integer value) {
+            addCriterion("provider <", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderLessThanOrEqualTo(Integer value) {
+            addCriterion("provider <=", value, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderIn(List<Integer> values) {
+            addCriterion("provider in", values, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderNotIn(List<Integer> values) {
+            addCriterion("provider not in", values, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderBetween(Integer value1, Integer value2) {
+            addCriterion("provider between", value1, value2, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andProviderNotBetween(Integer value1, Integer value2) {
+            addCriterion("provider not between", value1, value2, "provider");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdIsNull() {
+            addCriterion("account_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdIsNotNull() {
+            addCriterion("account_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdEqualTo(String value) {
+            addCriterion("account_id =", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdNotEqualTo(String value) {
+            addCriterion("account_id <>", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdGreaterThan(String value) {
+            addCriterion("account_id >", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdGreaterThanOrEqualTo(String value) {
+            addCriterion("account_id >=", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdLessThan(String value) {
+            addCriterion("account_id <", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdLessThanOrEqualTo(String value) {
+            addCriterion("account_id <=", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdLike(String value) {
+            addCriterion("account_id like", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdNotLike(String value) {
+            addCriterion("account_id not like", value, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdIn(List<String> values) {
+            addCriterion("account_id in", values, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdNotIn(List<String> values) {
+            addCriterion("account_id not in", values, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdBetween(String value1, String value2) {
+            addCriterion("account_id between", value1, value2, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdNotBetween(String value1, String value2) {
+            addCriterion("account_id not between", value1, value2, "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameIsNull() {
+            addCriterion("`name` is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameIsNotNull() {
+            addCriterion("`name` is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameEqualTo(String value) {
+            addCriterion("`name` =", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameNotEqualTo(String value) {
+            addCriterion("`name` <>", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameGreaterThan(String value) {
+            addCriterion("`name` >", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameGreaterThanOrEqualTo(String value) {
+            addCriterion("`name` >=", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameLessThan(String value) {
+            addCriterion("`name` <", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameLessThanOrEqualTo(String value) {
+            addCriterion("`name` <=", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameLike(String value) {
+            addCriterion("`name` like", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameNotLike(String value) {
+            addCriterion("`name` not like", value, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameIn(List<String> values) {
+            addCriterion("`name` in", values, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameNotIn(List<String> values) {
+            addCriterion("`name` not in", values, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameBetween(String value1, String value2) {
+            addCriterion("`name` between", value1, value2, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameNotBetween(String value1, String value2) {
+            addCriterion("`name` not between", value1, value2, "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailIsNull() {
+            addCriterion("email is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailIsNotNull() {
+            addCriterion("email is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailEqualTo(String value) {
+            addCriterion("email =", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailNotEqualTo(String value) {
+            addCriterion("email <>", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailGreaterThan(String value) {
+            addCriterion("email >", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailGreaterThanOrEqualTo(String value) {
+            addCriterion("email >=", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailLessThan(String value) {
+            addCriterion("email <", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailLessThanOrEqualTo(String value) {
+            addCriterion("email <=", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailLike(String value) {
+            addCriterion("email like", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailNotLike(String value) {
+            addCriterion("email not like", value, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailIn(List<String> values) {
+            addCriterion("email in", values, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailNotIn(List<String> values) {
+            addCriterion("email not in", values, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailBetween(String value1, String value2) {
+            addCriterion("email between", value1, value2, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailNotBetween(String value1, String value2) {
+            addCriterion("email not between", value1, value2, "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarIsNull() {
+            addCriterion("avatar is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarIsNotNull() {
+            addCriterion("avatar is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarEqualTo(String value) {
+            addCriterion("avatar =", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarNotEqualTo(String value) {
+            addCriterion("avatar <>", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarGreaterThan(String value) {
+            addCriterion("avatar >", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarGreaterThanOrEqualTo(String value) {
+            addCriterion("avatar >=", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarLessThan(String value) {
+            addCriterion("avatar <", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarLessThanOrEqualTo(String value) {
+            addCriterion("avatar <=", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarLike(String value) {
+            addCriterion("avatar like", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarNotLike(String value) {
+            addCriterion("avatar not like", value, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarIn(List<String> values) {
+            addCriterion("avatar in", values, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarNotIn(List<String> values) {
+            addCriterion("avatar not in", values, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarBetween(String value1, String value2) {
+            addCriterion("avatar between", value1, value2, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarNotBetween(String value1, String value2) {
+            addCriterion("avatar not between", value1, value2, "avatar");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIsNull() {
+            addCriterion("created_at is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIsNotNull() {
+            addCriterion("created_at is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtEqualTo(Date value) {
+            addCriterion("created_at =", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotEqualTo(Date value) {
+            addCriterion("created_at <>", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtGreaterThan(Date value) {
+            addCriterion("created_at >", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtGreaterThanOrEqualTo(Date value) {
+            addCriterion("created_at >=", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtLessThan(Date value) {
+            addCriterion("created_at <", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtLessThanOrEqualTo(Date value) {
+            addCriterion("created_at <=", value, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtIn(List<Date> values) {
+            addCriterion("created_at in", values, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotIn(List<Date> values) {
+            addCriterion("created_at not in", values, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtBetween(Date value1, Date value2) {
+            addCriterion("created_at between", value1, value2, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatedAtNotBetween(Date value1, Date value2) {
+            addCriterion("created_at not between", value1, value2, "createdAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIsNull() {
+            addCriterion("updated_at is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIsNotNull() {
+            addCriterion("updated_at is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtEqualTo(Date value) {
+            addCriterion("updated_at =", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotEqualTo(Date value) {
+            addCriterion("updated_at <>", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtGreaterThan(Date value) {
+            addCriterion("updated_at >", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtGreaterThanOrEqualTo(Date value) {
+            addCriterion("updated_at >=", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtLessThan(Date value) {
+            addCriterion("updated_at <", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtLessThanOrEqualTo(Date value) {
+            addCriterion("updated_at <=", value, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtIn(List<Date> values) {
+            addCriterion("updated_at in", values, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotIn(List<Date> values) {
+            addCriterion("updated_at not in", values, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtBetween(Date value1, Date value2) {
+            addCriterion("updated_at between", value1, value2, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdatedAtNotBetween(Date value1, Date value2) {
+            addCriterion("updated_at not between", value1, value2, "updatedAt");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLikeInsensitive(String value) {
+            addCriterion("upper(id) like", value.toUpperCase(), "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andMemberIdLikeInsensitive(String value) {
+            addCriterion("upper(member_id) like", value.toUpperCase(), "memberId");
+            return (Criteria) this;
+        }
+
+        public Criteria andAccountIdLikeInsensitive(String value) {
+            addCriterion("upper(account_id) like", value.toUpperCase(), "accountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andNameLikeInsensitive(String value) {
+            addCriterion("upper(`name`) like", value.toUpperCase(), "name");
+            return (Criteria) this;
+        }
+
+        public Criteria andEmailLikeInsensitive(String value) {
+            addCriterion("upper(email) like", value.toUpperCase(), "email");
+            return (Criteria) this;
+        }
+
+        public Criteria andAvatarLikeInsensitive(String value) {
+            addCriterion("upper(avatar) like", value.toUpperCase(), "avatar");
+            return (Criteria) this;
+        }
+    }
+
+    public static class Criteria extends GeneratedCriteria {
+
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 27 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/params/AppLoginParam.java

@@ -0,0 +1,27 @@
+package cn.kdan.pdf.backend.core.params;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class AppLoginParam {
+
+    private String account;
+
+    private String password;
+
+    @JsonProperty("phone_zone")
+    private String phoneZone;
+
+    @JsonProperty("access_token")
+    private String accessToken;
+
+    private String openid;
+
+    private String provider;
+
+}

+ 28 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/params/BindAccountParam.java

@@ -0,0 +1,28 @@
+package cn.kdan.pdf.backend.core.params;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class BindAccountParam {
+
+    @JsonProperty("access_token")
+    private String accessToken;
+
+    @JsonProperty("force_bind")
+    private String forceBind;
+
+    private String openid;
+
+    private String provider;
+
+    private String phone;
+
+    @JsonProperty("phone_zone")
+    private String phoneZone;
+
+}

+ 29 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/params/RelationParam.java

@@ -0,0 +1,29 @@
+package cn.kdan.pdf.backend.core.params;
+
+import lombok.Data;
+import pojo.Device;
+import pojo.Location;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class RelationParam {
+
+    /**
+     * 用户登录信息
+     */
+    private AppLoginParam attribute;
+
+    /**
+     * 设备
+     */
+    private Device device;
+
+    /**
+     * 位置
+     */
+    private Location location;
+
+}

+ 17 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/AvatarUrlsVo.java

@@ -0,0 +1,17 @@
+package cn.kdan.pdf.backend.core.pojo.app;
+
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class AvatarUrlsVo {
+
+    private String original;
+    private String thumb;
+    private String normal;
+    private String jpg;
+
+}

+ 16 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/BindAccountVo.java

@@ -0,0 +1,16 @@
+package cn.kdan.pdf.backend.core.pojo.app;
+
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class BindAccountVo {
+
+    private MemberVo member;
+
+    private SocialAccountVo socialAccount;
+
+}

+ 23 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/LoginInfoVo.java

@@ -0,0 +1,23 @@
+package cn.kdan.pdf.backend.core.pojo.app;
+
+import cn.kdan.pdf.backend.core.pojo.oauth2.TokenPOJO;
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class LoginInfoVo {
+
+    /**
+     * token信息
+     */
+    private TokenPOJO token;
+
+    /**
+     * 用户信息
+     */
+    private MemberVo member;
+
+}

+ 23 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/MemberVo.java

@@ -0,0 +1,23 @@
+package cn.kdan.pdf.backend.core.pojo.app;
+
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class MemberVo {
+
+    private String id;
+    private String name;
+    private String phone;
+    private String phoneZone;
+    private String email;
+    private String status;
+    private String timeZone;
+    private String signature;
+    private String avatarUrl;
+    private AvatarUrlsVo avatarUrls;
+
+}

+ 18 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/app/SocialAccountVo.java

@@ -0,0 +1,18 @@
+package cn.kdan.pdf.backend.core.pojo.app;
+
+import lombok.Data;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Data
+public class SocialAccountVo {
+
+    private String provider;
+
+    private String accountId;
+
+    private String name;
+
+}

+ 53 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/Tencent.java

@@ -0,0 +1,53 @@
+package cn.kdan.pdf.backend.core.pojo.third;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class Tencent {
+
+    private String ret;
+    private String msg;
+    @JsonProperty("is_lost")
+    private String isLost;
+    private String nickname;
+    private String gender;
+    @JsonProperty("gender_type")
+    private String genderType;
+    private String province;
+    private String city;
+    private String year;
+    private String constellation;
+
+    @JsonProperty("figureurl")
+    private String figureUrl;
+    @JsonProperty("figureurl_1")
+    private String figureUrl1;
+    @JsonProperty("figureurl_2")
+    private String figureUrl2;
+    @JsonProperty("figureurl_qq_1")
+    private String figureUrlQq1;
+    @JsonProperty("figureurl_qq_2")
+    private String figureUrlQq2;
+    @JsonProperty("figureurl_qq")
+    private String figureUrlQq;
+    @JsonProperty("figureurl_type")
+    private String figureUrlType;
+    @JsonProperty("is_yellow_vip")
+    private String isYellowVip;
+    private String vip;
+    @JsonProperty("yellow_vip_level")
+    private String yellowVipLevel;
+    private String level;
+    @JsonProperty("is_yellow_year_vip")
+    private String isYellowYearVip;
+
+    private String accessToken;
+    private String unionId;
+    private String clientId;
+
+}

+ 19 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/TencentMe.java

@@ -0,0 +1,19 @@
+package cn.kdan.pdf.backend.core.pojo.third;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Data
+public class TencentMe {
+
+    private String openid;
+    @JsonProperty("client_id")
+    private String clientId;
+    @JsonProperty("unionid")
+    private String unionId;
+
+}

+ 27 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/pojo/third/Wechat.java

@@ -0,0 +1,27 @@
+package cn.kdan.pdf.backend.core.pojo.third;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author SongFuQiang
+ * @description 微信用户信息
+ */
+@Data
+public class Wechat {
+
+    private String openid;
+    private String nickname;
+    private int sex;
+    private String language;
+    private String city;
+    private String country;
+    @JsonProperty("headimgurl")
+    private String headImgUrl;
+    private List privilege;
+    @JsonProperty("unionid")
+    private String unionId;
+
+}

+ 9 - 1
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/AuthService.java

@@ -4,9 +4,10 @@ import cn.kdan.pdf.backend.core.enums.CaptchaActionEnum;
 import cn.kdan.pdf.backend.core.enums.ImageCodeTypeEnum;
 import cn.kdan.pdf.backend.core.enums.VerifyTypeEnum;
 import cn.kdan.pdf.backend.core.model.OauthClientDetails;
+import cn.kdan.pdf.backend.core.params.RelationParam;
+import cn.kdan.pdf.backend.core.pojo.app.LoginInfoVo;
 import cn.kdan.pdf.backend.core.pojo.oauth2.TokenPOJO;
 
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import java.io.IOException;
@@ -114,4 +115,11 @@ public interface AuthService {
      * @return boolean
      */
     boolean checkVerifyCode(String action, String receiver, String code);
+
+    /**
+     * app端获取token登录
+     * @param param 登录参数
+     * @return token
+     */
+    LoginInfoVo appGetToken(RelationParam param);
 }

+ 33 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/DeviceService.java

@@ -0,0 +1,33 @@
+package cn.kdan.pdf.backend.core.service;
+
+import cn.kdan.pdf.backend.core.model.Devices;
+
+/**
+ * @author : SongFuQiang
+ * @date : 2022/12/12 9:44
+ */
+public interface DeviceService {
+
+    /**
+     * 插入设备信息
+     * @param devices devices
+     * @return
+     */
+    int insert(Devices devices);
+
+    /**
+     * 根据用户查询设备信息
+     * @param memberId 用户id
+     * @param uuid 设备唯一id
+     * @return
+     */
+    Devices selectByMemberId(String memberId, String uuid);
+
+    /**
+     * 更新设备信息
+     * @param device device
+     * @param uuid 设备唯一标识uuid
+     */
+    void update(Devices device, String uuid);
+
+}

+ 30 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/LocationService.java

@@ -0,0 +1,30 @@
+package cn.kdan.pdf.backend.core.service;
+
+import cn.kdan.pdf.backend.core.model.Locations;
+
+/**
+ * @author : SongFuQiang
+ * @date : 2022/12/12 9:56
+ */
+public interface LocationService {
+
+    /**
+     * 插入一条位置数据
+     * @param locations locations
+     * @return
+     */
+    int insert(Locations locations);
+
+    /**
+     * 根据用户id查询位置数据
+     * @param memberId 用户id
+     * @return
+     */
+    Locations selectByMemberId(String memberId);
+
+    /**
+     * 更新位置信息
+     * @param location location
+     */
+    void update(Locations location);
+}

+ 35 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/MemberService.java

@@ -5,7 +5,10 @@ import cn.kdan.pdf.backend.core.model.member.MemberInfoResp;
 import cn.kdan.pdf.backend.core.model.member.MemberRegisterReq;
 import cn.kdan.pdf.backend.core.model.member.MemberRegisterResp;
 import cn.kdan.pdf.backend.core.model.member.ModifyPasswordReq;
+import cn.kdan.pdf.backend.core.params.BindAccountParam;
 import cn.kdan.pdf.backend.core.params.UserResetPwdParams;
+import cn.kdan.pdf.backend.core.pojo.app.BindAccountVo;
+import cn.kdan.pdf.backend.core.pojo.app.MemberVo;
 
 public interface MemberService {
 
@@ -68,4 +71,36 @@ public interface MemberService {
      * @param member 用户
      */
     void update(Members member);
+
+    /**
+     * 根据用户名查询用户
+     * @param name 昵称
+     * @return 用户信息
+     */
+    Members selectByName(String name);
+
+    /**
+     * 注销账号
+     * @return 用户id
+     */
+    String cancelAccount();
+
+    /**
+     * 绑定账号
+     * @return 绑定信息
+     */
+    BindAccountVo bindAccount(BindAccountParam param);
+
+    /**
+     * 解绑账号
+     * @return 解绑信息
+     */
+    BindAccountVo unbindAccount(BindAccountParam param);
+
+    /**
+     * 修改用户昵称
+     * @param name 用户输入新昵称
+     * @return 用户信息
+     */
+    MemberVo appModifyName(String name);
 }

+ 55 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/SocialAccountService.java

@@ -0,0 +1,55 @@
+package cn.kdan.pdf.backend.core.service;
+
+import cn.kdan.pdf.backend.core.model.Members;
+import cn.kdan.pdf.backend.core.model.SocialAccounts;
+import cn.kdan.pdf.backend.core.params.BindAccountParam;
+
+/**
+ * @author : SongFuQiang
+ * @date : 2022/12/9 16:37
+ */
+public interface SocialAccountService {
+
+    /**
+     * 根据第三方账号id查询社交账号
+     * @param accountId 第三方账号id
+     * @return 社交账号信息
+     */
+    SocialAccounts selectByAccountId(String accountId);
+
+    /**
+     * 插入社交账号表数据
+     * @param socialAccounts socialAccounts
+     * @return
+     */
+    int insertSocialAccount(SocialAccounts socialAccounts);
+
+    /**
+     * 根据用户id查询社交账号表数据
+     * @param userId 用户id
+     * @param provider 第三方
+     * @return 社交账号信息
+     */
+    SocialAccounts selectByMemberId(String userId, Integer provider);
+
+    /**
+     * 根据用户id删除社交账号信息
+     * @param memberId 用户ID
+     */
+    void deleteByMemberId(String memberId);
+
+    /**
+     * 绑定社交账号
+     * @param member 当前用户
+     * @param param 绑定参数
+     */
+    String bindSocialAccount(Members member, BindAccountParam param);
+
+    /**
+     * 解绑账号
+     * @param currentUser 当前用户
+     * @param param 绑定参数
+     * @return socialAccount的id
+     */
+    String unbindSocialAccount(Members currentUser, BindAccountParam param);
+}

+ 243 - 11
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/AuthServiceImpl.java

@@ -4,16 +4,22 @@ import cn.kdan.pdf.backend.core.constant.AuthConstant;
 import cn.kdan.pdf.backend.core.constant.MembersConstant;
 import cn.kdan.pdf.backend.core.enums.CaptchaActionEnum;
 import cn.kdan.pdf.backend.core.enums.ImageCodeTypeEnum;
+import cn.kdan.pdf.backend.core.enums.ProviderEnum;
 import cn.kdan.pdf.backend.core.enums.VerifyTypeEnum;
 import cn.kdan.pdf.backend.core.mapper.OauthClientDetailsMapper;
-import cn.kdan.pdf.backend.core.model.Members;
-import cn.kdan.pdf.backend.core.model.OauthClientDetails;
-import cn.kdan.pdf.backend.core.model.OauthClientDetailsExample;
+import cn.kdan.pdf.backend.core.model.*;
+import cn.kdan.pdf.backend.core.params.AppLoginParam;
+import cn.kdan.pdf.backend.core.params.RelationParam;
+import cn.kdan.pdf.backend.core.pojo.app.LoginInfoVo;
+import cn.kdan.pdf.backend.core.pojo.app.MemberVo;
 import cn.kdan.pdf.backend.core.pojo.oauth2.TokenPOJO;
+import cn.kdan.pdf.backend.core.pojo.third.Tencent;
+import cn.kdan.pdf.backend.core.pojo.third.Wechat;
 import cn.kdan.pdf.backend.core.properties.Oauth2LoginProperties;
-import cn.kdan.pdf.backend.core.service.AuthService;
-import cn.kdan.pdf.backend.core.service.UserService;
+import cn.kdan.pdf.backend.core.service.*;
+import cn.kdan.pdf.backend.core.utils.TencentUtils;
 import cn.kdan.pdf.backend.core.utils.TokenUtils;
+import cn.kdan.pdf.backend.core.utils.WechatUtils;
 import constant.CommonConstant;
 import enums.ValidStatusEnum;
 import exception.BackendRuntimeException;
@@ -22,14 +28,21 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.http.HttpHeaders;
 import org.apache.http.entity.ContentType;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.oauth2.common.OAuth2AccessToken;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import pojo.CustomUserDetails;
+import pojo.Device;
+import pojo.Location;
+import pojo.ResultMap;
 import utils.*;
 
 import javax.annotation.Resource;
@@ -78,6 +91,14 @@ public class AuthServiceImpl implements AuthService {
 
     @Resource
     private UserService userService;
+    @Resource
+    private SocialAccountService socialAccountService;
+    @Resource
+    private DeviceService deviceService;
+    @Resource
+    private LocationService locationService;
+    @Resource
+    private MemberServiceImpl memberService;
 
     @Override
     public OauthClientDetails getById(String clientId) {
@@ -104,12 +125,7 @@ public class AuthServiceImpl implements AuthService {
     public TokenPOJO getTokenByUserId(String userId) {
         Members members = userService.getById(userId);
         Set<SimpleGrantedAuthority> authorities = new LinkedHashSet<>();
-        String account = "";
-        if(!StringUtils.isEmpty(members.getPhone())){
-            account = members.getPhone();
-        }else{
-            account = members.getEmail();
-        }
+        String account = members.getId();
         CustomUserDetails principal = new CustomUserDetails(members.getId(),
                 account,
                 members.getPasswordDigest(),
@@ -228,4 +244,220 @@ public class AuthServiceImpl implements AuthService {
         return StringUtils.isNotEmpty(code) && code.equals(captchaCode);
     }
 
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public LoginInfoVo appGetToken(RelationParam param) {
+        AppLoginParam attribute= param.getAttribute();
+        String provider = attribute.getProvider();
+        String password = attribute.getPassword();
+        if(StringUtils.isBlank(password)){
+            password = "false";
+        }
+        String openid = attribute.getOpenid();
+        String accessToken = attribute.getAccessToken();
+        String memberId = "";
+        MemberVo memberVo = new MemberVo();
+        memberVo.setStatus("verified");
+        memberVo.setTimeZone("UTC");
+        memberVo.setPhoneZone("86");
+
+        //provider不为空则为QQ、微信登录(tencent、wechat)
+        if(StringUtils.isNotEmpty(provider)){
+            // 判断是否存在用户数据,存在则不新增members数据
+            if(ProviderEnum.TENCENT.getName().equals(provider)){
+                Tencent tencent = TencentUtils.getUserInfo(accessToken);
+                memberVo.setAvatarUrl(tencent.getFigureUrl());
+                memberVo.setName(tencent.getNickname());
+                memberId = insertMemberAndSocialAccount(provider, password, tencent, null);
+            }else if(ProviderEnum.WECHAT.getName().equals(provider)){
+                Wechat wechat = WechatUtils.getUserInfo(openid, accessToken);
+                memberVo.setName(wechat.getNickname());
+                memberVo.setAvatarUrl(wechat.getHeadImgUrl());
+                memberId = insertMemberAndSocialAccount(provider, password,null,wechat);
+            }
+        }else{
+            //手机号、邮箱登录
+            String account = attribute.getAccount();
+            if(StringUtils.isEmpty(account)){
+                throw new BackendRuntimeException("请输入账号");
+            }
+            //根据账号查询members数据
+            Members member = userService.getByAccount(attribute.getAccount());
+            String mobileRegex = CommonConstant.mobileRegex;
+            //如果members为空并且account为手机号,新增一条members数据;邮箱不支持注册,只允许输入账号密码登录
+            if(account.matches(mobileRegex)){
+                if(ObjectUtils.isEmpty(member)) {
+                    member = new Members();
+                    member.setName(String.valueOf(System.currentTimeMillis()).substring(0, 10));
+                    memberId = memberService.insertMembers(member, password);
+                    memberVo.setName(member.getName());
+                    memberVo.setEmail(member.getEmail());
+                    memberVo.setPhone(member.getPhone());
+                    memberVo.setPhoneZone(member.getPhoneZone());
+                    memberVo.setTimeZone(member.getTimeZone());
+                    memberVo.setAvatarUrl("");
+                }else {
+                    if("false".equals(password)){
+                        memberVo.setName(member.getName());
+                        memberVo.setEmail(member.getEmail());
+                        memberVo.setPhone(member.getPhone());
+                        memberVo.setPhoneZone(member.getPhoneZone());
+                        memberVo.setAvatarUrl("");
+                        memberVo.setTimeZone(member.getTimeZone());
+                        memberId = member.getId();
+                    }
+                }
+            }else {
+                //如果用户存在将用户id返回,否则其他情况(邮箱登录)全部抛异常:用户未注册
+                if (ObjectUtils.isNotEmpty(member)) {
+                    String passwordDigest = member.getPasswordDigest();
+                    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+                    if(encoder.matches(password, passwordDigest)){
+                        memberVo.setName(member.getName());
+                        memberVo.setEmail(member.getEmail());
+                        memberVo.setPhone(member.getPhone());
+                        memberVo.setPhoneZone(member.getPhoneZone());
+                        memberVo.setAvatarUrl("");
+                        memberVo.setTimeZone(member.getTimeZone());
+                        memberId = member.getId();
+                    }else {
+                        throw new BackendRuntimeException("账号/密码输入有误");
+                    }
+                } else {
+                    throw new UsernameNotFoundException(JsonUtils.getJsonString(new ResultMap<>(AuthConstant.EXCEPTION_CODE_USER_NOT_FOUND, AuthConstant.EXCEPTION_MSG_USER_NOT_FOUND)));
+                }
+            }
+        }
+
+        //增加设备数据 todo 踢下线功能(需配合退出登录)
+        Device loginDevice = param.getDevice();
+        Devices queryDevice = deviceService.selectByMemberId(memberId,loginDevice.getUuid());
+        // 如果查询的设备为空,并且传参进来的device不为空,新增一条device数据
+        if(ObjectUtils.isEmpty(queryDevice)) {
+            if (StringUtils.isNotBlank(loginDevice.getUuid())) {
+                Devices device = new Devices();
+                BeanUtils.copyProperties(loginDevice, device);
+                device.setId(CommonUtils.generateId());
+                device.setMemberId(memberId);
+                memberVo.setTimeZone(loginDevice.getTimeZone());
+                deviceService.insert(device);
+            } else {
+                memberVo.setTimeZone("UTC");
+            }
+        }else{
+            // 根据uuid和memberId修改device设备信息
+            String uuid = queryDevice.getUuid();
+            if (StringUtils.isNotBlank(uuid)) {
+                BeanUtils.copyProperties(loginDevice, queryDevice);
+                deviceService.update(queryDevice, uuid);
+            }
+        }
+
+        //查询是否存在位置信息,存在则更新,不存在则新增
+        Location loginLocation = param.getLocation();
+        Locations queryLocation = locationService.selectByMemberId(memberId);
+        if (ObjectUtils.isEmpty(queryLocation)) {
+            if(StringUtils.isNotEmpty(loginLocation.getCountry())) {
+                Locations location = new Locations();
+                BeanUtils.copyProperties(loginLocation, location);
+                location.setId(CommonUtils.generateId());
+                location.setMemberId(memberId);
+                locationService.insert(location);
+            }
+        }else{
+            if(StringUtils.isNotEmpty(loginLocation.getCountry())) {
+                BeanUtils.copyProperties(loginLocation, queryLocation);
+                locationService.update(queryLocation);
+            }
+        }
+
+        LoginInfoVo vo = new LoginInfoVo();
+        //根据用户id查询token todo token过期设置
+//        String token = redisUtils.hget("token", memberId);
+        TokenPOJO tokenPOJO = new TokenPOJO();
+//        if(StringUtils.isNotBlank(token)){
+//            tokenPOJO.setAccessToken(token);
+//            tokenPOJO.setTokenType("bearer");
+//        }else {
+            tokenPOJO = getTokenByUserId(memberId);
+//        }
+//        redisUtils.hset("token",memberId,tokenPOJO.getAccessToken(),60*60*24*15);
+        vo.setToken(tokenPOJO);
+        //获取用户信息
+        memberVo.setId(memberId);
+        vo.setMember(memberVo);
+        return vo;
+    }
+
+    /**
+     * 判断members表是否存在数据,不存在则插入用户和社交账户表,并返回memberId
+     * 存在则不插入直接返回memberId
+     *
+     * @param provider 第三方平台
+     * @param tencent qq用户信息
+     * @param wechat 微信用户信息
+     * @return 用户id
+     */
+    private String insertMemberAndSocialAccount(String provider,String password, Tencent tencent, Wechat wechat) {
+        String memberId = "";
+        if(ProviderEnum.TENCENT.getName().equals(provider)){
+            SocialAccounts socialAccounts = socialAccountService.selectByAccountId(tencent.getUnionId());
+            if(ObjectUtils.isEmpty(socialAccounts)){
+                Members member = new Members();
+                setMembersName(tencent.getNickname(), member);
+                String id = memberService.insertMembers(member, password);
+                insertSocialAccount(provider, id, tencent.getUnionId(), tencent.getFigureUrl(), tencent.getNickname());
+                memberId = id;
+            } else{
+                memberId = socialAccounts.getMemberId();
+            }
+        }else if(ProviderEnum.WECHAT.getName().equals(provider)){
+            SocialAccounts socialAccounts = socialAccountService.selectByAccountId(wechat.getUnionId());
+            if(ObjectUtils.isEmpty(socialAccounts)){
+                Members member = new Members();
+                setMembersName(wechat.getNickname(),member);
+                String id = memberService.insertMembers(member, password);
+                insertSocialAccount(provider, id, wechat.getUnionId(), wechat.getHeadImgUrl(), wechat.getNickname());
+                memberId = id;
+            } else{
+                memberId = socialAccounts.getMemberId();
+            }
+        }
+        return memberId;
+    }
+
+    /**
+     * 设置用户名(用户名唯一性)
+     * @param name
+     * @param member
+     */
+    private void setMembersName(String name, Members member) {
+        Members queryMembers = memberService.selectByName(name);
+        if(queryMembers != null){
+            //todo 待考虑第三方名称与数据库数据重名后该怎么赋值
+            member.setName(String.valueOf(System.currentTimeMillis()).substring(0, 10));
+        }else{
+            member.setName(name);
+        }
+    }
+
+    /**
+     * 新增社交账号表数据
+     * @param provider tencent/wechat
+     * @param memberId 用户id
+     * @param unionId accountId(第三方返回的唯一标识)
+     * @param figureUrl 头像地址
+     * @param nickname 昵称
+     */
+    private void insertSocialAccount(String provider, String memberId, String unionId, String figureUrl, String nickname) {
+        SocialAccounts account = new SocialAccounts();
+        account.setId(CommonUtils.generateId());
+        account.setMemberId(memberId);
+        account.setAccountId(unionId);
+        account.setAvatar(figureUrl);
+        account.setName(nickname);
+        Integer providerValue = ProviderEnum.getCodeByName(provider);
+        account.setProvider(providerValue);
+        socialAccountService.insertSocialAccount(account);
+    }
 }

+ 68 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/DeviceServiceImpl.java

@@ -0,0 +1,68 @@
+package cn.kdan.pdf.backend.core.service.impl;
+
+import cn.kdan.pdf.backend.core.mapper.DevicesMapper;
+import cn.kdan.pdf.backend.core.model.Devices;
+import cn.kdan.pdf.backend.core.model.DevicesExample;
+import cn.kdan.pdf.backend.core.service.DeviceService;
+import exception.BackendRuntimeException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Slf4j
+@Service
+public class DeviceServiceImpl implements DeviceService {
+
+    @Resource
+    private DevicesMapper devicesMapper;
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public int insert(Devices devices) {
+        Date now = new Date();
+        devices.setCreatedAt(now);
+        devices.setUpdatedAt(now);
+        return devicesMapper.insert(devices);
+    }
+
+    @Override
+    public Devices selectByMemberId(String memberId, String uuid) {
+        //todo 最多允许三台设备
+        DevicesExample example = new DevicesExample();
+        DevicesExample.Criteria criteria = example.createCriteria();
+        criteria.andMemberIdEqualTo(memberId);
+        example.setOrderByClause("updated_at ASC");
+        //先根据用户id查询设备信息
+        List<Devices> devices = devicesMapper.selectByExample(example);
+        if(CollectionUtils.isEmpty(devices)){
+            return null;
+        }
+        criteria.andUuidEqualTo(uuid);
+        //再根据用户id+设备唯一标识uuid查询
+        List<Devices> list = devicesMapper.selectByExample(example);
+        //如果数据大于等于3条,不允许新增数据,只能更新
+        if(devices.size() >= 3 && CollectionUtils.isEmpty(list)){
+            return devices.get(0);
+        }
+        return list.get(0);
+    }
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public void update(Devices device, String uuid) {
+        Date date = new Date();
+        device.setUpdatedAt(date);
+        DevicesExample example = new DevicesExample();
+        example.createCriteria().andMemberIdEqualTo(device.getMemberId()).andUuidEqualTo(uuid);
+        devicesMapper.updateByExample(device,example);
+    }
+}

+ 57 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/LocationServiceImpl.java

@@ -0,0 +1,57 @@
+package cn.kdan.pdf.backend.core.service.impl;
+
+import cn.kdan.pdf.backend.core.mapper.LocationsMapper;
+import cn.kdan.pdf.backend.core.model.Locations;
+import cn.kdan.pdf.backend.core.model.LocationsExample;
+import cn.kdan.pdf.backend.core.service.LocationService;
+import exception.BackendRuntimeException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author sfq
+ * @description
+ */
+@Slf4j
+@Service
+public class LocationServiceImpl implements LocationService {
+
+    @Resource
+    private LocationsMapper locationsMapper;
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public int insert(Locations locations) {
+        Date now = new Date();
+        locations.setCreatedAt(now);
+        locations.setUpdatedAt(now);
+        return locationsMapper.insert(locations);
+    }
+
+    @Override
+    public Locations selectByMemberId(String memberId) {
+        LocationsExample example = new LocationsExample();
+        example.createCriteria().andMemberIdEqualTo(memberId);
+        List<Locations> locations = locationsMapper.selectByExample(example);
+        if(CollectionUtils.isEmpty(locations)){
+            return null;
+        }
+        return locations.get(0);
+    }
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public void update(Locations location) {
+        Date date = new Date();
+        location.setUpdatedAt(date);
+        LocationsExample example = new LocationsExample();
+        example.createCriteria().andMemberIdEqualTo(location.getMemberId());
+        locationsMapper.updateByExampleSelective(location, example);
+    }
+}

+ 161 - 8
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MemberServiceImpl.java

@@ -3,15 +3,22 @@ package cn.kdan.pdf.backend.core.service.impl;
 import cn.kdan.pdf.backend.core.constant.AuthConstant;
 import cn.kdan.pdf.backend.core.constant.MembersConstant;
 import cn.kdan.pdf.backend.core.enums.CaptchaActionEnum;
+import cn.kdan.pdf.backend.core.enums.ProviderEnum;
 import cn.kdan.pdf.backend.core.enums.SubscriberTypeEnum;
 import cn.kdan.pdf.backend.core.enums.VerifyTypeEnum;
 import cn.kdan.pdf.backend.core.mapper.*;
 import cn.kdan.pdf.backend.core.mapper.ext.ExtMembersMapper;
 import cn.kdan.pdf.backend.core.model.*;
 import cn.kdan.pdf.backend.core.model.member.*;
+import cn.kdan.pdf.backend.core.params.BindAccountParam;
 import cn.kdan.pdf.backend.core.params.UserResetPwdParams;
+import cn.kdan.pdf.backend.core.pojo.app.BindAccountVo;
+import cn.kdan.pdf.backend.core.pojo.app.MemberVo;
+import cn.kdan.pdf.backend.core.pojo.app.SocialAccountVo;
 import cn.kdan.pdf.backend.core.service.AuthService;
 import cn.kdan.pdf.backend.core.service.MemberService;
+import cn.kdan.pdf.backend.core.service.SocialAccountService;
+import cn.kdan.pdf.backend.core.service.UserService;
 import constant.CommonConstant;
 import enums.CommonEnum;
 import exception.BackendRuntimeException;
@@ -57,6 +64,10 @@ public class MemberServiceImpl implements MemberService {
     private RedisUtils redisUtils;
     @Autowired
     private ExtMembersMapper extMembersMapper;
+    @Autowired
+    private SocialAccountService socialAccountService;
+    @Autowired
+    private UserService userService;
 
     /**
      * 默认时区
@@ -125,15 +136,28 @@ public class MemberServiceImpl implements MemberService {
 
         // 添加数据
         Members member = new Members();
-        member.setId(CommonUtils.generateId());
-        Date date = new Date();
-        //用户命名使用时间戳
-        member.setName(String.valueOf(date.getTime()).substring(0, 10));
         if (username.matches(mobileRegex)) {
             member.setPhone(username);
         } else if (username.matches(emailRegex)) {
             member.setEmail(username);
         }
+        //用户命名使用时间戳
+        member.setName(String.valueOf(System.currentTimeMillis()).substring(0, 10));
+        insertMembers(member, password);
+        resp.setMessage("注册成功");
+        return resp;
+    }
+
+    /**
+     * 为members设置基础值并插入数据库
+     * @param member member数据
+     * @param password 密码
+     * @return  用户id
+     */
+    public String insertMembers(Members member, String password) {
+        String id = CommonUtils.generateId();
+        member.setId(id);
+        Date date = new Date();
         //使用Bcrypt加密方式对密码进行加密处理
         BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
         member.setPasswordDigest(encoder.encode(password));
@@ -144,15 +168,14 @@ public class MemberServiceImpl implements MemberService {
         member.setStatus(CommonEnum.YesOrNoEnum.NO.value());
         member.setPhoneZone(DEFAULT_PHONE_ZONE);
         member.setSubscriberType(CommonEnum.YesOrNoEnum.NO.value());
-        // todo 用户账号待确定
+        // todo 用户账号account = sha1(86-phone / email)
         member.setAccount("");
         member.setPoints(INIT_POINTS);
         member.setTotalPoints(INIT_POINTS);
         member.setTotalSpace(DEFAULT_SPACE);
         member.setLeftSpace(new BigDecimal(DEFAULT_SPACE));
         membersMapper.insert(member);
-        resp.setMessage("注册成功");
-        return resp;
+        return id;
     }
 
     /**
@@ -377,7 +400,7 @@ public class MemberServiceImpl implements MemberService {
     }
 
     @Override
-    @Transactional
+    @Transactional(rollbackFor = BackendRuntimeException.class)
     public boolean resetPassword(UserResetPwdParams params) {
         MembersExample example = new MembersExample();
         //如果是手机方式
@@ -436,4 +459,134 @@ public class MemberServiceImpl implements MemberService {
     public void update(Members member) {
         membersMapper.updateByPrimaryKeySelective(member);
     }
+
+    @Override
+    public Members selectByName(String name) {
+        MembersExample example = new MembersExample();
+        example.createCriteria().andNameEqualTo(name);
+        List<Members> list = membersMapper.selectByExample(example);
+        if(CollectionUtils.isEmpty(list)){
+            return null;
+        }
+        return list.get(0);
+    }
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public String cancelAccount() {
+        Members currentUser = getCurrentUser();
+        String memberId = currentUser.getId();
+        //删除社交账号socialAccount表+用户members表数据
+        //判断用户是否是空数据类型(未充值过券和会员服务)
+        if(!StringUtils.isEmpty(memberId) && currentUser.getTotalPoints() == 10
+                && SubscriberTypeEnum.no.value().equals(currentUser.getSubscriberType())){
+            socialAccountService.deleteByMemberId(memberId);
+            membersMapper.deleteByPrimaryKey(memberId);
+        }
+        return memberId;
+    }
+
+    @Override
+    @Transactional(rollbackFor = BackendRuntimeException.class)
+    public BindAccountVo bindAccount(BindAccountParam param) {
+        BindAccountVo bindAccountVo = new BindAccountVo();
+        SocialAccountVo socialAccountVo = new SocialAccountVo();
+        MemberVo memberVo = new MemberVo();
+        Members currentUser = getCurrentUser();
+        BeanUtils.copyProperties(currentUser,memberVo);
+        memberVo.setStatus("verified");
+        bindAccountVo.setMember(memberVo);
+
+        String provider = param.getProvider();
+        if("phone".equals(provider)){
+            String phone = param.getPhone();
+            if(StringUtils.isEmpty(phone)){
+                throw new BackendRuntimeException("手机号不能为空");
+            }
+            Members member = userService.getByAccount(phone);
+            if(member != null){
+                //不允许绑定自己
+                if(member.getId().equals(currentUser.getId())) {
+                    throw new BackendRuntimeException("不允许绑定自己");
+                }else{
+                    if(member.getTotalPoints() <= 10 && SubscriberTypeEnum.no.value().equals(member.getSubscriberType())){
+                        //删除该手机的账号数据,然后更新手机到当前用户
+                        membersMapper.deleteByPrimaryKey(member.getId());
+                        //更新当前账号的手机号为phone参数
+                        if(!StringUtils.isEmpty(param.getPhoneZone())){
+                            currentUser.setPhoneZone(param.getPhoneZone());
+                        }
+                        currentUser.setPhone(phone);
+                        currentUser.setUpdatedAt(new Date());
+                        update(currentUser);
+                    }else{
+                        throw new BackendRuntimeException("不允许绑定该账号,因为充过钱了!");
+                    }
+                }
+            }else{
+                //直接更新当前账号的手机号为phone参数
+                if(!StringUtils.isEmpty(param.getPhoneZone())){
+                    currentUser.setPhoneZone(param.getPhoneZone());
+                }
+                currentUser.setPhone(phone);
+                currentUser.setUpdatedAt(new Date());
+                update(currentUser);
+            }
+        } else{
+            //绑定第三方账号
+            String accountId = socialAccountService.bindSocialAccount(currentUser,param);
+            SocialAccounts socialAccounts = socialAccountService.selectByAccountId(accountId);
+            BeanUtils.copyProperties(socialAccounts,socialAccountVo);
+            bindAccountVo.setSocialAccount(socialAccountVo);
+        }
+        return bindAccountVo;
+    }
+
+    @Override
+    public BindAccountVo unbindAccount(BindAccountParam param) {
+        BindAccountVo bindAccountVo = new BindAccountVo();
+        MemberVo memberVo = new MemberVo();
+        SocialAccountVo accountVo = new SocialAccountVo();
+
+        Members currentUser = getCurrentUser();
+        BeanUtils.copyProperties(currentUser,memberVo);
+        memberVo.setStatus("verified");
+        bindAccountVo.setMember(memberVo);
+
+        String provider = param.getProvider();
+        if("phone".equals(provider)){
+            currentUser.setPhone("");
+            update(currentUser);
+        } else {
+            String accountId = socialAccountService.unbindSocialAccount(currentUser,param);
+            SocialAccounts socialAccounts = socialAccountService.selectByAccountId(accountId);
+            BeanUtils.copyProperties(socialAccounts,accountVo);
+            bindAccountVo.setSocialAccount(accountVo);
+        }
+        return bindAccountVo;
+    }
+
+    @Override
+    public MemberVo appModifyName(String name) {
+        modifyNickname(name);
+        Members currentUser = getCurrentUser();
+        return createMemberVo(currentUser);
+    }
+
+    /**
+     * 返回一个memberVo对象
+     * @param member 当前用户
+     * @return memberVo
+     */
+    public MemberVo createMemberVo(Members member){
+        MemberVo vo = new MemberVo();
+        BeanUtils.copyProperties(member,vo);
+        AvatarsExample example = new AvatarsExample();
+        example.createCriteria().andMemberIdEqualTo(member.getId());
+        List<Avatars> avatars = avatarsMapper.selectByExample(example);
+        if(!CollectionUtils.isEmpty(avatars)){
+            vo.setAvatarUrl(avatars.get(0).getAvatar());
+        }
+        return vo;
+    }
 }

+ 2 - 1
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MissionFileServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.kdan.pdf.backend.core.service.impl;
 
 import cn.kdan.pdf.backend.core.client.ComPdfKitClient;
+import cn.kdan.pdf.backend.core.constant.MissionConstant;
 import cn.kdan.pdf.backend.core.constant.MissionFilesConstant;
 import cn.kdan.pdf.backend.core.enums.MissionFileStatusEnum;
 import cn.kdan.pdf.backend.core.mapper.ext.ExtMissionFilesMapper;
@@ -74,7 +75,7 @@ public class MissionFileServiceImpl implements MissionFilesService {
             missionFilesMapper.updateByPrimaryKeySelective(missionFile);
         } catch (Exception e) {
             missionFile.setStatus(MissionFileStatusEnum.FAILED.value());
-            missionFile.setFailReason(e.getMessage());
+            missionFile.setFailReason(MissionConstant.UNKNOWN_ERROR_MSG);
             missionFilesMapper.updateByPrimaryKeySelective(missionFile);
             throw new BackendRuntimeException(e.getMessage());
         }

+ 1 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/MissionServiceImpl.java

@@ -343,6 +343,7 @@ public class MissionServiceImpl implements MissionService {
         }else{
             missionFiles.setFailReason(file.getFailureReason());
         }
+        missionFiles.setPrice(0);
         missionFiles.setUpdatedAt(new Date());
         missionFiles.setConvertEndAt(new Date());
         missionFilesService.update(missionFiles);

+ 3 - 3
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/OrderServiceImpl.java

@@ -449,14 +449,14 @@ public class OrderServiceImpl implements OrderService {
                 handleAliOrder(params, paramsJson);
                 // 如果签名验证正确,立即返回success,后续业务另起线程单独处理
                 // 业务处理失败,可查看日志进行补偿,跟支付宝已经没多大关系。
-                return aliResponse(Boolean.TRUE,"success");
+                return "success";
             } else {
                 log.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", paramsJson);
-                return aliResponse(Boolean.FALSE,"failure");
+                return "fail";
             }
         } catch (AlipayApiException e) {
             log.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());
-            return aliResponse(Boolean.FALSE,"failure");
+            return "fail";
         }
     }
 

+ 149 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/service/impl/SocialAccountServiceImpl.java

@@ -0,0 +1,149 @@
+package cn.kdan.pdf.backend.core.service.impl;
+
+import cn.kdan.pdf.backend.core.enums.ProviderEnum;
+import cn.kdan.pdf.backend.core.mapper.SocialAccountsMapper;
+import cn.kdan.pdf.backend.core.model.Members;
+import cn.kdan.pdf.backend.core.model.SocialAccounts;
+import cn.kdan.pdf.backend.core.model.SocialAccountsExample;
+import cn.kdan.pdf.backend.core.params.BindAccountParam;
+import cn.kdan.pdf.backend.core.pojo.third.Tencent;
+import cn.kdan.pdf.backend.core.pojo.third.Wechat;
+import cn.kdan.pdf.backend.core.service.SocialAccountService;
+import cn.kdan.pdf.backend.core.utils.TencentUtils;
+import cn.kdan.pdf.backend.core.utils.WechatUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author SongFuQiang
+ * @description
+ */
+@Slf4j
+@Service
+public class SocialAccountServiceImpl implements SocialAccountService {
+
+    @Resource
+    private SocialAccountsMapper socialAccountsMapper;
+
+    @Override
+    public SocialAccounts selectByAccountId(String accountId) {
+        SocialAccountsExample example = new SocialAccountsExample();
+        example.createCriteria().andAccountIdEqualTo(accountId);
+        List<SocialAccounts> list = socialAccountsMapper.selectByExample(example);
+        if (!CollectionUtils.isEmpty(list)) {
+            return list.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public int insertSocialAccount(SocialAccounts socialAccounts) {
+        Date date = new Date();
+        socialAccounts.setCreatedAt(date);
+        socialAccounts.setUpdatedAt(date);
+        socialAccountsMapper.insert(socialAccounts);
+        return 0;
+    }
+
+    @Override
+    public SocialAccounts selectByMemberId(String userId, Integer provider) {
+        SocialAccountsExample example = new SocialAccountsExample();
+        example.createCriteria().andMemberIdEqualTo(userId).andProviderEqualTo(provider);
+        List<SocialAccounts> list = socialAccountsMapper.selectByExample(example);
+        if(CollectionUtils.isEmpty(list)){
+            return null;
+        }
+        return list.get(0);
+    }
+
+    @Override
+    public void deleteByMemberId(String memberId) {
+        SocialAccountsExample example = new SocialAccountsExample();
+        example.createCriteria().andMemberIdEqualTo(memberId);
+        socialAccountsMapper.deleteByExample(example);
+    }
+
+    @Override
+    public String bindSocialAccount(Members member, BindAccountParam param) {
+        String accountId = "";
+        String accessToken = param.getAccessToken();
+        String openid = param.getOpenid();
+        String provider = param.getProvider();
+        if(ProviderEnum.TENCENT.getName().equals(provider)){
+            Tencent userInfo = TencentUtils.getUserInfo(accessToken);
+            String unionId = userInfo.getUnionId();
+            accountId = unionId;
+            SocialAccounts socialAccount = selectByAccountId(unionId);
+            //看看有没有该账号,没有就新增一条,有就更新用户id
+            if(ObjectUtils.isEmpty(socialAccount)){
+                socialAccount.setAccountId(unionId);
+                socialAccount.setMemberId(member.getId());
+                socialAccount.setName(userInfo.getNickname());
+                socialAccount.setProvider(ProviderEnum.getCodeByName(provider));
+                socialAccount.setAvatar(userInfo.getFigureUrl());
+                insertSocialAccount(socialAccount);
+            } else{
+                socialAccount.setMemberId(member.getId());
+                updateSocialAccount(socialAccount);
+            }
+        }else{
+            Wechat userInfo = WechatUtils.getUserInfo(openid, accessToken);
+            String unionId = userInfo.getUnionId();
+            accountId = unionId;
+            SocialAccounts socialAccount = selectByAccountId(unionId);
+            if(ObjectUtils.isEmpty(socialAccount)){
+                socialAccount.setAvatar(userInfo.getHeadImgUrl());
+                socialAccount.setAccountId(unionId);
+                socialAccount.setProvider(ProviderEnum.getCodeByName(provider));
+                socialAccount.setMemberId(member.getId());
+                socialAccount.setName(userInfo.getNickname());
+                insertSocialAccount(socialAccount);
+            } else{
+                socialAccount.setMemberId(member.getId());
+                updateSocialAccount(socialAccount);
+            }
+        }
+        return accountId;
+    }
+
+    /**
+     * 根据accountId更新社交账号
+     * @param socialAccount 社交账号信息
+     */
+    public void updateSocialAccount(SocialAccounts socialAccount) {
+        SocialAccountsExample example = new SocialAccountsExample();
+        example.createCriteria().andAccountIdEqualTo(socialAccount.getAccountId());
+        socialAccount.setUpdatedAt(new Date());
+        socialAccountsMapper.updateByExample(socialAccount,example);
+    }
+
+    @Override
+    public String unbindSocialAccount(Members currentUser, BindAccountParam param) {
+        String accountId = "";
+        String accessToken = param.getAccessToken();
+        String openid = param.getOpenid();
+        String provider = param.getProvider();
+        SocialAccountsExample example = new SocialAccountsExample();
+        if(ProviderEnum.TENCENT.getName().equals(provider)){
+            Tencent userInfo = TencentUtils.getUserInfo(accessToken);
+            String unionId = userInfo.getUnionId();
+            accountId = unionId;
+            example.createCriteria().andAccountIdEqualTo(unionId);
+            socialAccountsMapper.deleteByExample(example);
+        } else {
+            Wechat userInfo = WechatUtils.getUserInfo(openid, accessToken);
+            String unionId = userInfo.getUnionId();
+            accountId = unionId;
+            SocialAccounts socialAccount = selectByAccountId(unionId);
+            example.createCriteria().andAccountIdEqualTo(unionId);
+            socialAccountsMapper.deleteByExample(example);
+        }
+        return accountId;
+    }
+}

+ 248 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/HttpClientUtils.java

@@ -0,0 +1,248 @@
+package cn.kdan.pdf.backend.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author songfuqiang
+ * @description http请求发送工具类
+ */
+@Slf4j
+public class HttpClientUtils {
+
+    private HttpClientUtils() {
+    }
+
+    public static void main(String[] args) {
+    }
+
+    /**
+     * 封装HTTP POST方法
+     *
+     * @param
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String post(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpPost httpPost = new HttpPost(url);
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpPost.setConfig(requestConfig);
+        List<NameValuePair> formParams = setHttpParams(paramMap);
+        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formParams, "UTF-8");
+        httpPost.setEntity(param);
+        log.info("************开始发送post请求:{}", httpPost);
+        HttpResponse response = httpClient.execute(httpPost);
+        log.info("************post请求返回参数:{}", response);
+        String httpEntityContent = getHttpEntityContent(response);
+        log.info("************post请求content内容:{}", httpEntityContent);
+        httpPost.abort();
+        log.info("************post情求最后返回内容{}", httpEntityContent);
+        return httpEntityContent;
+
+    }
+
+    /**
+     * 封装HTTP POST方法
+     *
+     * @param
+     * @param (如JSON串)
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String post(String url, String data) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpPost httpPost = new HttpPost(url);
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpPost.setConfig(requestConfig);
+        httpPost.setHeader("Content-Type", "text/json; charset=utf-8");
+        httpPost.setEntity(new StringEntity(URLEncoder.encode(data, "UTF-8")));
+        HttpResponse response = httpClient.execute(httpPost);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpPost.abort();
+        return httpEntityContent;
+    }
+
+    /**
+     * 封装HTTP GET方法
+     *
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String get(String url) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpGet httpGet = new HttpGet();
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpGet.setConfig(requestConfig);
+        httpGet.setURI(URI.create(url));
+        HttpResponse response = httpClient.execute(httpGet);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpGet.abort();
+        return httpEntityContent;
+    }
+
+    /**
+     * 封装HTTP GET方法
+     *
+     * @param
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String get(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpGet httpGet = new HttpGet();
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpGet.setConfig(requestConfig);
+        List<NameValuePair> formparams = setHttpParams(paramMap);
+        String param = URLEncodedUtils.format(formparams, "UTF-8");
+        httpGet.setURI(URI.create(url + "?" + param));
+        HttpResponse response = httpClient.execute(httpGet);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpGet.abort();
+        return httpEntityContent;
+    }
+
+    /**
+     * 封装HTTP PUT方法
+     *
+     * @param
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String put(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpPut httpPut = new HttpPut(url);
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpPut.setConfig(requestConfig);
+        List<NameValuePair> formparams = setHttpParams(paramMap);
+        UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
+        httpPut.setEntity(param);
+        HttpResponse response = httpClient.execute(httpPut);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpPut.abort();
+        return httpEntityContent;
+    }
+
+    /**
+     * 封装HTTP DELETE方法
+     *
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String delete(String url) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpDelete httpDelete = new HttpDelete();
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpDelete.setConfig(requestConfig);
+        httpDelete.setURI(URI.create(url));
+        HttpResponse response = httpClient.execute(httpDelete);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpDelete.abort();
+        return httpEntityContent;
+    }
+
+    /**
+     * 封装HTTP DELETE方法
+     *
+     * @param
+     * @param
+     * @return
+     * @throws ClientProtocolException
+     * @throws IOException
+     */
+    public static String delete(String url, Map<String, String> paramMap) throws ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+        HttpDelete httpDelete = new HttpDelete();
+        //设置请求和传输超时时间
+        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build();
+        httpDelete.setConfig(requestConfig);
+        List<NameValuePair> formparams = setHttpParams(paramMap);
+        String param = URLEncodedUtils.format(formparams, "UTF-8");
+        httpDelete.setURI(URI.create(url + "?" + param));
+        HttpResponse response = httpClient.execute(httpDelete);
+        String httpEntityContent = getHttpEntityContent(response);
+        httpDelete.abort();
+        return httpEntityContent;
+    }
+
+
+    /**
+     * 设置请求参数
+     *
+     * @param
+     * @return
+     */
+    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
+        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
+        Set<Map.Entry<String, String>> set = paramMap.entrySet();
+        for (Map.Entry<String, String> entry : set) {
+            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+        }
+        return formparams;
+    }
+
+    /**
+     * 获得响应HTTP实体内容
+     *
+     * @param response
+     * @return
+     * @throws IOException
+     * @throws UnsupportedEncodingException
+     */
+    private static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException {
+        HttpEntity entity = response.getEntity();
+        if (entity != null) {
+            InputStream is = entity.getContent();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+            String line = br.readLine();
+            StringBuilder sb = new StringBuilder();
+            while (line != null) {
+                sb.append(line + "\n");
+                line = br.readLine();
+            }
+            return sb.toString();
+        }
+        return "";
+    }
+
+
+}

+ 81 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/TencentUtils.java

@@ -0,0 +1,81 @@
+package cn.kdan.pdf.backend.core.utils;
+
+import cn.kdan.pdf.backend.core.pojo.third.Tencent;
+import cn.kdan.pdf.backend.core.pojo.third.TencentMe;
+import exception.BackendRuntimeException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import utils.JsonUtils;
+
+/**
+ * @author SongFuQiang
+ * @description QQ登录工具类
+ */
+@Slf4j
+public class TencentUtils {
+    private static String OPENID_ENDPOINT = "https://graph.qq.com/oauth2.0/me?access_token=ACCESS_TOKEN&unionid=1";
+    private static String ENDPOINT = "https://graph.qq.com/user/get_user_info?oauth_consumer_key=CLIENT_ID&openid=OPENID&access_token=ACCESS_TOKEN";
+
+    /**
+     * 获取unionId、clientId数据
+     * @param accessToken 权限token
+     * @return 返回unionId、clientId
+     */
+    public static TencentMe me(String accessToken){
+        String url = OPENID_ENDPOINT.replace("ACCESS_TOKEN", accessToken);
+        try {
+            String tencent = HttpClientUtils.get(url);
+            String trim = tencent.replace("callback(", "").replace(")", "").trim();
+            TencentMe me = JsonUtils.jsonStringToBean(trim, TencentMe.class);
+            if(ObjectUtils.isNotEmpty(me)) {
+                if (StringUtils.isEmpty(me.getOpenid()) || StringUtils.isEmpty(me.getUnionId())) {
+                    log.error("获取QQ用户权限信息失败:{},accessToken:{}", tencent, accessToken);
+                    throw new BackendRuntimeException("获取QQ用户权限信息失败");
+                }
+                return me;
+            }
+        }catch (Exception e){
+            log.error("获取QQ用户信息失败:{},{}",e,e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * 获取用户信息
+     * @param accessToken 权限token
+     * @return 返回qq用户信息
+     */
+    public static Tencent getUserInfo(String accessToken){
+        Tencent tencent = new Tencent();
+        TencentMe me = me(accessToken);
+        if (ObjectUtils.isEmpty(me)) {
+            throw new BackendRuntimeException("获取QQ用户权限信息失败");
+        }
+        String clientId = me.getClientId();
+        String openid = me.getOpenid();
+        String unionId = me.getUnionId();
+        String url = ENDPOINT.replace("CLIENT_ID",clientId).replace("OPENID",openid).replace("ACCESS_TOKEN",accessToken);
+        try{
+            String resp = HttpClientUtils.get(url);
+            tencent = JsonUtils.jsonStringToBean(resp, Tencent.class);
+            if(ObjectUtils.isNotEmpty(tencent) && StringUtils.isBlank(tencent.getNickname())){
+                log.error("获取QQ用户信息失败:{},accessToken:{}",resp,accessToken);
+                throw new BackendRuntimeException("获取QQ用户信息失败");
+            }
+            tencent.setAccessToken(accessToken);
+            tencent.setClientId(clientId);
+            tencent.setUnionId(unionId);
+            return tencent;
+        }catch (Exception e){
+            log.error("获取QQ用户信息失败:{},{}",e,e.getMessage());
+        }
+        return tencent;
+    }
+
+    public static void main(String[] args) {
+        Tencent tencent = getUserInfo("AA9EC48B21422DAA8B0F9173A0EF404A");
+        System.out.println(tencent != null ? tencent.toString() : "");
+    }
+
+}

+ 43 - 0
backend-core/src/main/java/cn/kdan/pdf/backend/core/utils/WechatUtils.java

@@ -0,0 +1,43 @@
+package cn.kdan.pdf.backend.core.utils;
+
+import cn.kdan.pdf.backend.core.pojo.third.Wechat;
+import exception.BackendRuntimeException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import utils.JsonUtils;
+
+/**
+ * @author SongFuQiang
+ * @description 微信登录工具类
+ */
+@Slf4j
+public class WechatUtils {
+
+    private static String ENDPOINT = "https://api.weixin.qq.com/sns/userinfo?openid=OPEN_ID&access_token=ACCESS_TOKEN";
+
+    /**
+     * 获取用户信息
+     * @param openid openid
+     * @param accessToken accessToken
+     * @return 用户信息
+     */
+    public static Wechat getUserInfo(String openid, String accessToken){
+        Wechat wechat = new Wechat();
+        String url = ENDPOINT.replace("OPEN_ID",openid).replace("ACCESS_TOKEN",accessToken);
+        try {
+            String resp = HttpClientUtils.get(url);
+            wechat = JsonUtils.jsonStringToBean(resp, Wechat.class);
+            if(ObjectUtils.isNotEmpty(wechat)) {
+                if (StringUtils.isEmpty(wechat.getUnionId()) || StringUtils.isEmpty(wechat.getOpenid())) {
+                    log.error("获取微信用户信息失败:{},token:{}", resp, accessToken);
+                    throw new BackendRuntimeException("获取微信用户信息失败");
+                }
+            }
+        }catch (Exception e){
+            log.error("获取微信用户信息失败:{},{}",e,e.getMessage());
+        }
+        return wechat;
+    }
+
+}

+ 1 - 1
backend-core/src/main/resources/application-local-db.properties

@@ -1,5 +1,5 @@
 jdbc.driverClassName=com.mysql.cj.jdbc.Driver
-jdbc.url=jdbc\:mysql\://81.68.234.235\:33056/17pdf_backend_test?autoReconnect\=true&&useSSL\=false
+jdbc.url=jdbc\:mysql\://81.68.234.235\:33056/17pdf_backend_dev?autoReconnect\=true&&useSSL\=false
 jdbc.username=root
 jdbc.password=root123
 

+ 1 - 1
backend-core/src/main/resources/application-local.yml

@@ -70,6 +70,6 @@ ali:
 com:
   pdf:
     kit:
-      address: http://81.68.234.235:7000
+      address: http://101.132.103.13:8090/server
       projectKey: 17PDF
       secretKey: 17PDF@123

+ 6 - 3
backend-core/src/main/resources/application-test-db.properties

@@ -1,4 +1,7 @@
 jdbc.driverClassName=com.mysql.cj.jdbc.Driver
-jdbc.url=jdbc\:mysql\://139.196.160.101\:3306/17pdf_backend_test?useUnicode\=true&characterEncoding\=UTF-8&useSSL\=false
-jdbc.username=debian-sys-maint
-jdbc.password=tRF4SWujyo6rZ4Qm
+#jdbc.url=jdbc\:mysql\://139.196.160.101\:3306/17pdf_backend_test?useUnicode\=true&characterEncoding\=UTF-8&useSSL\=false
+#jdbc.username=debian-sys-maint
+#jdbc.password=tRF4SWujyo6rZ4Qm
+jdbc.url=jdbc\:mysql\://81.68.234.235\:33056/17pdf_backend_dev?autoReconnect\=true&&useSSL\=false
+jdbc.username=root
+jdbc.password=root123

+ 1 - 1
backend-core/src/main/resources/application-test.yml

@@ -70,6 +70,6 @@ ali:
 com:
   pdf:
     kit:
-      address: http://81.68.234.235:7000
+      address: http://101.132.103.13:8090/server
       projectKey: 17PDF
       secretKey: 17PDF@123

+ 1 - 1
backend-core/src/main/resources/application.yml

@@ -79,7 +79,7 @@ cors:
   allow-origins: "*"
   allow-max-age: "3600"
 httpMatchers:
-  request: "/login,/logout,/members/resetPassword,/oauth/**,/auth/**,/members/register,/order/syncOrder,/order/alipaySyncOrder,/alipayRedirect/callback,/pricing/list,/setPricing/listForVisitor,/mission/saasCallback"
+  request: "/login,/logout,/members/resetPassword,/members/checkResetPasswordValid,/oauth/**,/auth/**,/members/register,/order/syncOrder,/order/alipaySyncOrder,/alipayRedirect/callback,/pricing/list,/setPricing/listForVisitor,/mission/saasCallback"
   web: "/hystrix.stream,/webjars/**,/resources/**,/swagger-ui.html,/swagger-resources/**,/v2/api-docs"
 
 

+ 11 - 4
backend-core/src/main/resources/generatorConfig.xml

@@ -37,10 +37,10 @@
         </javaClientGenerator>
         <!--        <table tableName="convert_types"/>-->
         <!--        <table tableName="members"/>-->
-        <table tableName="mission_files">
-            <columnOverride column="trace_result" javaType="java.lang.String" jdbcType="VARCHAR"/>
-            <columnOverride column="output_bucket" javaType="java.lang.String" jdbcType="VARCHAR"/>
-        </table>
+<!--        <table tableName="mission_files">-->
+<!--            <columnOverride column="trace_result" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
+<!--            <columnOverride column="output_bucket" javaType="java.lang.String" jdbcType="VARCHAR"/>-->
+<!--        </table>-->
         <!--        <table tableName="missions"/>-->
         <!--        <table tableName="oauth_client_details"/>-->
         <!--        <table tableName="avatars"/>-->
@@ -53,5 +53,12 @@
         <!--            <columnOverride column="result" javaType="java.lang.String" jdbcType="VARCHAR" />-->
         <!--        </table>-->
 <!--        <table tableName="missions"/>-->
+        <table tableName="advertisements">
+            <columnOverride column="description" javaType="java.lang.String" jdbcType="VARCHAR" />
+            <columnOverride column="extra_info" javaType="java.lang.String" jdbcType="VARCHAR" />
+        </table>
+        <table tableName="devices"/>
+        <table tableName="locations"/>
+        <table tableName="social_accounts"/>
     </context>
 </generatorConfiguration>

+ 432 - 0
backend-core/src/main/resources/sqlmap/AdvertisementsMapper.xml

@@ -0,0 +1,432 @@
+<?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="cn.kdan.pdf.backend.core.mapper.AdvertisementsMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.pdf.backend.core.model.Advertisements">
+    <id column="id" jdbcType="VARCHAR" property="id" />
+    <result column="slug" jdbcType="VARCHAR" property="slug" />
+    <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="description" jdbcType="VARCHAR" property="description" />
+    <result column="image" jdbcType="VARCHAR" property="image" />
+    <result column="dimension" jdbcType="VARCHAR" property="dimension" />
+    <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+    <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+    <result column="link_text" jdbcType="VARCHAR" property="linkText" />
+    <result column="link_url" jdbcType="VARCHAR" property="linkUrl" />
+    <result column="total_hits" jdbcType="INTEGER" property="totalHits" />
+    <result column="language" jdbcType="INTEGER" property="language" />
+    <result column="start_date" jdbcType="TIMESTAMP" property="startDate" />
+    <result column="end_date" jdbcType="TIMESTAMP" property="endDate" />
+    <result column="display_type" jdbcType="VARCHAR" property="displayType" />
+    <result column="start_hour" jdbcType="REAL" property="startHour" />
+    <result column="end_hour" jdbcType="REAL" property="endHour" />
+    <result column="extra_info" jdbcType="VARCHAR" property="extraInfo" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, slug, title, description, image, dimension, created_at, updated_at, link_text, 
+    link_url, total_hits, `language`, start_date, end_date, display_type, start_hour, 
+    end_hour, extra_info
+  </sql>
+  <select id="selectByExample" parameterType="cn.kdan.pdf.backend.core.model.AdvertisementsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from advertisements
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from advertisements
+    where id = #{id,jdbcType=VARCHAR}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
+    delete from advertisements
+    where id = #{id,jdbcType=VARCHAR}
+  </delete>
+  <delete id="deleteByExample" parameterType="cn.kdan.pdf.backend.core.model.AdvertisementsExample">
+    delete from advertisements
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="cn.kdan.pdf.backend.core.model.Advertisements">
+    insert into advertisements (id, slug, title, 
+      description, image, dimension, 
+      created_at, updated_at, link_text, 
+      link_url, total_hits, `language`, 
+      start_date, end_date, display_type, 
+      start_hour, end_hour, extra_info
+      )
+    values (#{id,jdbcType=VARCHAR}, #{slug,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, 
+      #{description,jdbcType=VARCHAR}, #{image,jdbcType=VARCHAR}, #{dimension,jdbcType=VARCHAR}, 
+      #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}, #{linkText,jdbcType=VARCHAR}, 
+      #{linkUrl,jdbcType=VARCHAR}, #{totalHits,jdbcType=INTEGER}, #{language,jdbcType=INTEGER}, 
+      #{startDate,jdbcType=TIMESTAMP}, #{endDate,jdbcType=TIMESTAMP}, #{displayType,jdbcType=VARCHAR}, 
+      #{startHour,jdbcType=REAL}, #{endHour,jdbcType=REAL}, #{extraInfo,jdbcType=VARCHAR}
+      )
+  </insert>
+  <insert id="insertSelective" parameterType="cn.kdan.pdf.backend.core.model.Advertisements">
+    insert into advertisements
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="slug != null">
+        slug,
+      </if>
+      <if test="title != null">
+        title,
+      </if>
+      <if test="description != null">
+        description,
+      </if>
+      <if test="image != null">
+        image,
+      </if>
+      <if test="dimension != null">
+        dimension,
+      </if>
+      <if test="createdAt != null">
+        created_at,
+      </if>
+      <if test="updatedAt != null">
+        updated_at,
+      </if>
+      <if test="linkText != null">
+        link_text,
+      </if>
+      <if test="linkUrl != null">
+        link_url,
+      </if>
+      <if test="totalHits != null">
+        total_hits,
+      </if>
+      <if test="language != null">
+        `language`,
+      </if>
+      <if test="startDate != null">
+        start_date,
+      </if>
+      <if test="endDate != null">
+        end_date,
+      </if>
+      <if test="displayType != null">
+        display_type,
+      </if>
+      <if test="startHour != null">
+        start_hour,
+      </if>
+      <if test="endHour != null">
+        end_hour,
+      </if>
+      <if test="extraInfo != null">
+        extra_info,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=VARCHAR},
+      </if>
+      <if test="slug != null">
+        #{slug,jdbcType=VARCHAR},
+      </if>
+      <if test="title != null">
+        #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="description != null">
+        #{description,jdbcType=VARCHAR},
+      </if>
+      <if test="image != null">
+        #{image,jdbcType=VARCHAR},
+      </if>
+      <if test="dimension != null">
+        #{dimension,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="linkText != null">
+        #{linkText,jdbcType=VARCHAR},
+      </if>
+      <if test="linkUrl != null">
+        #{linkUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="totalHits != null">
+        #{totalHits,jdbcType=INTEGER},
+      </if>
+      <if test="language != null">
+        #{language,jdbcType=INTEGER},
+      </if>
+      <if test="startDate != null">
+        #{startDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="endDate != null">
+        #{endDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="displayType != null">
+        #{displayType,jdbcType=VARCHAR},
+      </if>
+      <if test="startHour != null">
+        #{startHour,jdbcType=REAL},
+      </if>
+      <if test="endHour != null">
+        #{endHour,jdbcType=REAL},
+      </if>
+      <if test="extraInfo != null">
+        #{extraInfo,jdbcType=VARCHAR},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="cn.kdan.pdf.backend.core.model.AdvertisementsExample" resultType="java.lang.Long">
+    select count(*) from advertisements
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update advertisements
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=VARCHAR},
+      </if>
+      <if test="record.slug != null">
+        slug = #{record.slug,jdbcType=VARCHAR},
+      </if>
+      <if test="record.title != null">
+        title = #{record.title,jdbcType=VARCHAR},
+      </if>
+      <if test="record.description != null">
+        description = #{record.description,jdbcType=VARCHAR},
+      </if>
+      <if test="record.image != null">
+        image = #{record.image,jdbcType=VARCHAR},
+      </if>
+      <if test="record.dimension != null">
+        dimension = #{record.dimension,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createdAt != null">
+        created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.updatedAt != null">
+        updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.linkText != null">
+        link_text = #{record.linkText,jdbcType=VARCHAR},
+      </if>
+      <if test="record.linkUrl != null">
+        link_url = #{record.linkUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="record.totalHits != null">
+        total_hits = #{record.totalHits,jdbcType=INTEGER},
+      </if>
+      <if test="record.language != null">
+        `language` = #{record.language,jdbcType=INTEGER},
+      </if>
+      <if test="record.startDate != null">
+        start_date = #{record.startDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.endDate != null">
+        end_date = #{record.endDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.displayType != null">
+        display_type = #{record.displayType,jdbcType=VARCHAR},
+      </if>
+      <if test="record.startHour != null">
+        start_hour = #{record.startHour,jdbcType=REAL},
+      </if>
+      <if test="record.endHour != null">
+        end_hour = #{record.endHour,jdbcType=REAL},
+      </if>
+      <if test="record.extraInfo != null">
+        extra_info = #{record.extraInfo,jdbcType=VARCHAR},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update advertisements
+    set id = #{record.id,jdbcType=VARCHAR},
+      slug = #{record.slug,jdbcType=VARCHAR},
+      title = #{record.title,jdbcType=VARCHAR},
+      description = #{record.description,jdbcType=VARCHAR},
+      image = #{record.image,jdbcType=VARCHAR},
+      dimension = #{record.dimension,jdbcType=VARCHAR},
+      created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      link_text = #{record.linkText,jdbcType=VARCHAR},
+      link_url = #{record.linkUrl,jdbcType=VARCHAR},
+      total_hits = #{record.totalHits,jdbcType=INTEGER},
+      `language` = #{record.language,jdbcType=INTEGER},
+      start_date = #{record.startDate,jdbcType=TIMESTAMP},
+      end_date = #{record.endDate,jdbcType=TIMESTAMP},
+      display_type = #{record.displayType,jdbcType=VARCHAR},
+      start_hour = #{record.startHour,jdbcType=REAL},
+      end_hour = #{record.endHour,jdbcType=REAL},
+      extra_info = #{record.extraInfo,jdbcType=VARCHAR}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="cn.kdan.pdf.backend.core.model.Advertisements">
+    update advertisements
+    <set>
+      <if test="slug != null">
+        slug = #{slug,jdbcType=VARCHAR},
+      </if>
+      <if test="title != null">
+        title = #{title,jdbcType=VARCHAR},
+      </if>
+      <if test="description != null">
+        description = #{description,jdbcType=VARCHAR},
+      </if>
+      <if test="image != null">
+        image = #{image,jdbcType=VARCHAR},
+      </if>
+      <if test="dimension != null">
+        dimension = #{dimension,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        created_at = #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="linkText != null">
+        link_text = #{linkText,jdbcType=VARCHAR},
+      </if>
+      <if test="linkUrl != null">
+        link_url = #{linkUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="totalHits != null">
+        total_hits = #{totalHits,jdbcType=INTEGER},
+      </if>
+      <if test="language != null">
+        `language` = #{language,jdbcType=INTEGER},
+      </if>
+      <if test="startDate != null">
+        start_date = #{startDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="endDate != null">
+        end_date = #{endDate,jdbcType=TIMESTAMP},
+      </if>
+      <if test="displayType != null">
+        display_type = #{displayType,jdbcType=VARCHAR},
+      </if>
+      <if test="startHour != null">
+        start_hour = #{startHour,jdbcType=REAL},
+      </if>
+      <if test="endHour != null">
+        end_hour = #{endHour,jdbcType=REAL},
+      </if>
+      <if test="extraInfo != null">
+        extra_info = #{extraInfo,jdbcType=VARCHAR},
+      </if>
+    </set>
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="cn.kdan.pdf.backend.core.model.Advertisements">
+    update advertisements
+    set slug = #{slug,jdbcType=VARCHAR},
+      title = #{title,jdbcType=VARCHAR},
+      description = #{description,jdbcType=VARCHAR},
+      image = #{image,jdbcType=VARCHAR},
+      dimension = #{dimension,jdbcType=VARCHAR},
+      created_at = #{createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      link_text = #{linkText,jdbcType=VARCHAR},
+      link_url = #{linkUrl,jdbcType=VARCHAR},
+      total_hits = #{totalHits,jdbcType=INTEGER},
+      `language` = #{language,jdbcType=INTEGER},
+      start_date = #{startDate,jdbcType=TIMESTAMP},
+      end_date = #{endDate,jdbcType=TIMESTAMP},
+      display_type = #{displayType,jdbcType=VARCHAR},
+      start_hour = #{startHour,jdbcType=REAL},
+      end_hour = #{endHour,jdbcType=REAL},
+      extra_info = #{extraInfo,jdbcType=VARCHAR}
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+  <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.pdf.backend.core.model.AdvertisementsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from advertisements
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+</mapper>

+ 367 - 0
backend-core/src/main/resources/sqlmap/DevicesMapper.xml

@@ -0,0 +1,367 @@
+<?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="cn.kdan.pdf.backend.core.mapper.DevicesMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.pdf.backend.core.model.Devices">
+    <id column="id" jdbcType="VARCHAR" property="id" />
+    <result column="member_id" jdbcType="VARCHAR" property="memberId" />
+    <result column="uuid" jdbcType="VARCHAR" property="uuid" />
+    <result column="model" jdbcType="VARCHAR" property="model" />
+    <result column="os" jdbcType="VARCHAR" property="os" />
+    <result column="time_zone" jdbcType="VARCHAR" property="timeZone" />
+    <result column="language" jdbcType="VARCHAR" property="language" />
+    <result column="register_id" jdbcType="VARCHAR" property="registerId" />
+    <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+    <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+    <result column="lock_version" jdbcType="INTEGER" property="lockVersion" />
+    <result column="status" jdbcType="INTEGER" property="status" />
+    <result column="app_version" jdbcType="VARCHAR" property="appVersion" />
+    <result column="client_uid" jdbcType="VARCHAR" property="clientUid" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, member_id, uuid, model, os, time_zone, `language`, register_id, created_at, updated_at, 
+    lock_version, `status`, app_version, client_uid
+  </sql>
+  <select id="selectByExample" parameterType="cn.kdan.pdf.backend.core.model.DevicesExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from devices
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from devices
+    where id = #{id,jdbcType=VARCHAR}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
+    delete from devices
+    where id = #{id,jdbcType=VARCHAR}
+  </delete>
+  <delete id="deleteByExample" parameterType="cn.kdan.pdf.backend.core.model.DevicesExample">
+    delete from devices
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="cn.kdan.pdf.backend.core.model.Devices">
+    insert into devices (id, member_id, uuid, 
+      model, os, time_zone, 
+      `language`, register_id, created_at, 
+      updated_at, lock_version, `status`, 
+      app_version, client_uid)
+    values (#{id,jdbcType=VARCHAR}, #{memberId,jdbcType=VARCHAR}, #{uuid,jdbcType=VARCHAR}, 
+      #{model,jdbcType=VARCHAR}, #{os,jdbcType=VARCHAR}, #{timeZone,jdbcType=VARCHAR}, 
+      #{language,jdbcType=VARCHAR}, #{registerId,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, 
+      #{updatedAt,jdbcType=TIMESTAMP}, #{lockVersion,jdbcType=INTEGER}, #{status,jdbcType=INTEGER}, 
+      #{appVersion,jdbcType=VARCHAR}, #{clientUid,jdbcType=VARCHAR})
+  </insert>
+  <insert id="insertSelective" parameterType="cn.kdan.pdf.backend.core.model.Devices">
+    insert into devices
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="memberId != null">
+        member_id,
+      </if>
+      <if test="uuid != null">
+        uuid,
+      </if>
+      <if test="model != null">
+        model,
+      </if>
+      <if test="os != null">
+        os,
+      </if>
+      <if test="timeZone != null">
+        time_zone,
+      </if>
+      <if test="language != null">
+        `language`,
+      </if>
+      <if test="registerId != null">
+        register_id,
+      </if>
+      <if test="createdAt != null">
+        created_at,
+      </if>
+      <if test="updatedAt != null">
+        updated_at,
+      </if>
+      <if test="lockVersion != null">
+        lock_version,
+      </if>
+      <if test="status != null">
+        `status`,
+      </if>
+      <if test="appVersion != null">
+        app_version,
+      </if>
+      <if test="clientUid != null">
+        client_uid,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=VARCHAR},
+      </if>
+      <if test="memberId != null">
+        #{memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="uuid != null">
+        #{uuid,jdbcType=VARCHAR},
+      </if>
+      <if test="model != null">
+        #{model,jdbcType=VARCHAR},
+      </if>
+      <if test="os != null">
+        #{os,jdbcType=VARCHAR},
+      </if>
+      <if test="timeZone != null">
+        #{timeZone,jdbcType=VARCHAR},
+      </if>
+      <if test="language != null">
+        #{language,jdbcType=VARCHAR},
+      </if>
+      <if test="registerId != null">
+        #{registerId,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="lockVersion != null">
+        #{lockVersion,jdbcType=INTEGER},
+      </if>
+      <if test="status != null">
+        #{status,jdbcType=INTEGER},
+      </if>
+      <if test="appVersion != null">
+        #{appVersion,jdbcType=VARCHAR},
+      </if>
+      <if test="clientUid != null">
+        #{clientUid,jdbcType=VARCHAR},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="cn.kdan.pdf.backend.core.model.DevicesExample" resultType="java.lang.Long">
+    select count(*) from devices
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update devices
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=VARCHAR},
+      </if>
+      <if test="record.memberId != null">
+        member_id = #{record.memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.uuid != null">
+        uuid = #{record.uuid,jdbcType=VARCHAR},
+      </if>
+      <if test="record.model != null">
+        model = #{record.model,jdbcType=VARCHAR},
+      </if>
+      <if test="record.os != null">
+        os = #{record.os,jdbcType=VARCHAR},
+      </if>
+      <if test="record.timeZone != null">
+        time_zone = #{record.timeZone,jdbcType=VARCHAR},
+      </if>
+      <if test="record.language != null">
+        `language` = #{record.language,jdbcType=VARCHAR},
+      </if>
+      <if test="record.registerId != null">
+        register_id = #{record.registerId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createdAt != null">
+        created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.updatedAt != null">
+        updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.lockVersion != null">
+        lock_version = #{record.lockVersion,jdbcType=INTEGER},
+      </if>
+      <if test="record.status != null">
+        `status` = #{record.status,jdbcType=INTEGER},
+      </if>
+      <if test="record.appVersion != null">
+        app_version = #{record.appVersion,jdbcType=VARCHAR},
+      </if>
+      <if test="record.clientUid != null">
+        client_uid = #{record.clientUid,jdbcType=VARCHAR},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update devices
+    set id = #{record.id,jdbcType=VARCHAR},
+      member_id = #{record.memberId,jdbcType=VARCHAR},
+      uuid = #{record.uuid,jdbcType=VARCHAR},
+      model = #{record.model,jdbcType=VARCHAR},
+      os = #{record.os,jdbcType=VARCHAR},
+      time_zone = #{record.timeZone,jdbcType=VARCHAR},
+      `language` = #{record.language,jdbcType=VARCHAR},
+      register_id = #{record.registerId,jdbcType=VARCHAR},
+      created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      lock_version = #{record.lockVersion,jdbcType=INTEGER},
+      `status` = #{record.status,jdbcType=INTEGER},
+      app_version = #{record.appVersion,jdbcType=VARCHAR},
+      client_uid = #{record.clientUid,jdbcType=VARCHAR}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="cn.kdan.pdf.backend.core.model.Devices">
+    update devices
+    <set>
+      <if test="memberId != null">
+        member_id = #{memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="uuid != null">
+        uuid = #{uuid,jdbcType=VARCHAR},
+      </if>
+      <if test="model != null">
+        model = #{model,jdbcType=VARCHAR},
+      </if>
+      <if test="os != null">
+        os = #{os,jdbcType=VARCHAR},
+      </if>
+      <if test="timeZone != null">
+        time_zone = #{timeZone,jdbcType=VARCHAR},
+      </if>
+      <if test="language != null">
+        `language` = #{language,jdbcType=VARCHAR},
+      </if>
+      <if test="registerId != null">
+        register_id = #{registerId,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        created_at = #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="lockVersion != null">
+        lock_version = #{lockVersion,jdbcType=INTEGER},
+      </if>
+      <if test="status != null">
+        `status` = #{status,jdbcType=INTEGER},
+      </if>
+      <if test="appVersion != null">
+        app_version = #{appVersion,jdbcType=VARCHAR},
+      </if>
+      <if test="clientUid != null">
+        client_uid = #{clientUid,jdbcType=VARCHAR},
+      </if>
+    </set>
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="cn.kdan.pdf.backend.core.model.Devices">
+    update devices
+    set member_id = #{memberId,jdbcType=VARCHAR},
+      uuid = #{uuid,jdbcType=VARCHAR},
+      model = #{model,jdbcType=VARCHAR},
+      os = #{os,jdbcType=VARCHAR},
+      time_zone = #{timeZone,jdbcType=VARCHAR},
+      `language` = #{language,jdbcType=VARCHAR},
+      register_id = #{registerId,jdbcType=VARCHAR},
+      created_at = #{createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{updatedAt,jdbcType=TIMESTAMP},
+      lock_version = #{lockVersion,jdbcType=INTEGER},
+      `status` = #{status,jdbcType=INTEGER},
+      app_version = #{appVersion,jdbcType=VARCHAR},
+      client_uid = #{clientUid,jdbcType=VARCHAR}
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+  <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.pdf.backend.core.model.DevicesExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from devices
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+</mapper>

+ 273 - 0
backend-core/src/main/resources/sqlmap/LocationsMapper.xml

@@ -0,0 +1,273 @@
+<?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="cn.kdan.pdf.backend.core.mapper.LocationsMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.pdf.backend.core.model.Locations">
+    <result column="id" jdbcType="VARCHAR" property="id" />
+    <result column="member_id" jdbcType="VARCHAR" property="memberId" />
+    <result column="longitude" jdbcType="DECIMAL" property="longitude" />
+    <result column="latitude" jdbcType="DECIMAL" property="latitude" />
+    <result column="country" jdbcType="VARCHAR" property="country" />
+    <result column="state" jdbcType="VARCHAR" property="state" />
+    <result column="city" jdbcType="VARCHAR" property="city" />
+    <result column="district" jdbcType="VARCHAR" property="district" />
+    <result column="street" jdbcType="VARCHAR" property="street" />
+    <result column="zip" jdbcType="VARCHAR" property="zip" />
+    <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+    <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, member_id, longitude, latitude, country, `state`, city, district, street, zip, 
+    created_at, updated_at
+  </sql>
+  <select id="selectByExample" parameterType="cn.kdan.pdf.backend.core.model.LocationsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from locations
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <delete id="deleteByExample" parameterType="cn.kdan.pdf.backend.core.model.LocationsExample">
+    delete from locations
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="cn.kdan.pdf.backend.core.model.Locations">
+    insert into locations (id, member_id, longitude, 
+      latitude, country, `state`, 
+      city, district, street, 
+      zip, created_at, updated_at
+      )
+    values (#{id,jdbcType=VARCHAR}, #{memberId,jdbcType=VARCHAR}, #{longitude,jdbcType=DECIMAL}, 
+      #{latitude,jdbcType=DECIMAL}, #{country,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR}, 
+      #{city,jdbcType=VARCHAR}, #{district,jdbcType=VARCHAR}, #{street,jdbcType=VARCHAR}, 
+      #{zip,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}
+      )
+  </insert>
+  <insert id="insertSelective" parameterType="cn.kdan.pdf.backend.core.model.Locations">
+    insert into locations
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="memberId != null">
+        member_id,
+      </if>
+      <if test="longitude != null">
+        longitude,
+      </if>
+      <if test="latitude != null">
+        latitude,
+      </if>
+      <if test="country != null">
+        country,
+      </if>
+      <if test="state != null">
+        `state`,
+      </if>
+      <if test="city != null">
+        city,
+      </if>
+      <if test="district != null">
+        district,
+      </if>
+      <if test="street != null">
+        street,
+      </if>
+      <if test="zip != null">
+        zip,
+      </if>
+      <if test="createdAt != null">
+        created_at,
+      </if>
+      <if test="updatedAt != null">
+        updated_at,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=VARCHAR},
+      </if>
+      <if test="memberId != null">
+        #{memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="longitude != null">
+        #{longitude,jdbcType=DECIMAL},
+      </if>
+      <if test="latitude != null">
+        #{latitude,jdbcType=DECIMAL},
+      </if>
+      <if test="country != null">
+        #{country,jdbcType=VARCHAR},
+      </if>
+      <if test="state != null">
+        #{state,jdbcType=VARCHAR},
+      </if>
+      <if test="city != null">
+        #{city,jdbcType=VARCHAR},
+      </if>
+      <if test="district != null">
+        #{district,jdbcType=VARCHAR},
+      </if>
+      <if test="street != null">
+        #{street,jdbcType=VARCHAR},
+      </if>
+      <if test="zip != null">
+        #{zip,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="cn.kdan.pdf.backend.core.model.LocationsExample" resultType="java.lang.Long">
+    select count(*) from locations
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update locations
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=VARCHAR},
+      </if>
+      <if test="record.memberId != null">
+        member_id = #{record.memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.longitude != null">
+        longitude = #{record.longitude,jdbcType=DECIMAL},
+      </if>
+      <if test="record.latitude != null">
+        latitude = #{record.latitude,jdbcType=DECIMAL},
+      </if>
+      <if test="record.country != null">
+        country = #{record.country,jdbcType=VARCHAR},
+      </if>
+      <if test="record.state != null">
+        `state` = #{record.state,jdbcType=VARCHAR},
+      </if>
+      <if test="record.city != null">
+        city = #{record.city,jdbcType=VARCHAR},
+      </if>
+      <if test="record.district != null">
+        district = #{record.district,jdbcType=VARCHAR},
+      </if>
+      <if test="record.street != null">
+        street = #{record.street,jdbcType=VARCHAR},
+      </if>
+      <if test="record.zip != null">
+        zip = #{record.zip,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createdAt != null">
+        created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.updatedAt != null">
+        updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update locations
+    set id = #{record.id,jdbcType=VARCHAR},
+      member_id = #{record.memberId,jdbcType=VARCHAR},
+      longitude = #{record.longitude,jdbcType=DECIMAL},
+      latitude = #{record.latitude,jdbcType=DECIMAL},
+      country = #{record.country,jdbcType=VARCHAR},
+      `state` = #{record.state,jdbcType=VARCHAR},
+      city = #{record.city,jdbcType=VARCHAR},
+      district = #{record.district,jdbcType=VARCHAR},
+      street = #{record.street,jdbcType=VARCHAR},
+      zip = #{record.zip,jdbcType=VARCHAR},
+      created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.pdf.backend.core.model.LocationsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from locations
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+</mapper>

+ 237 - 0
backend-core/src/main/resources/sqlmap/SocialAccountsMapper.xml

@@ -0,0 +1,237 @@
+<?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="cn.kdan.pdf.backend.core.mapper.SocialAccountsMapper">
+  <resultMap id="BaseResultMap" type="cn.kdan.pdf.backend.core.model.SocialAccounts">
+    <result column="id" jdbcType="VARCHAR" property="id" />
+    <result column="member_id" jdbcType="VARCHAR" property="memberId" />
+    <result column="provider" jdbcType="INTEGER" property="provider" />
+    <result column="account_id" jdbcType="VARCHAR" property="accountId" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="email" jdbcType="VARCHAR" property="email" />
+    <result column="avatar" jdbcType="VARCHAR" property="avatar" />
+    <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+    <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, member_id, provider, account_id, `name`, email, avatar, created_at, updated_at
+  </sql>
+  <select id="selectByExample" parameterType="cn.kdan.pdf.backend.core.model.SocialAccountsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from social_accounts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <delete id="deleteByExample" parameterType="cn.kdan.pdf.backend.core.model.SocialAccountsExample">
+    delete from social_accounts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="cn.kdan.pdf.backend.core.model.SocialAccounts">
+    insert into social_accounts (id, member_id, provider, 
+      account_id, `name`, email, 
+      avatar, created_at, updated_at
+      )
+    values (#{id,jdbcType=VARCHAR}, #{memberId,jdbcType=VARCHAR}, #{provider,jdbcType=INTEGER}, 
+      #{accountId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, 
+      #{avatar,jdbcType=VARCHAR}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}
+      )
+  </insert>
+  <insert id="insertSelective" parameterType="cn.kdan.pdf.backend.core.model.SocialAccounts">
+    insert into social_accounts
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="memberId != null">
+        member_id,
+      </if>
+      <if test="provider != null">
+        provider,
+      </if>
+      <if test="accountId != null">
+        account_id,
+      </if>
+      <if test="name != null">
+        `name`,
+      </if>
+      <if test="email != null">
+        email,
+      </if>
+      <if test="avatar != null">
+        avatar,
+      </if>
+      <if test="createdAt != null">
+        created_at,
+      </if>
+      <if test="updatedAt != null">
+        updated_at,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=VARCHAR},
+      </if>
+      <if test="memberId != null">
+        #{memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="provider != null">
+        #{provider,jdbcType=INTEGER},
+      </if>
+      <if test="accountId != null">
+        #{accountId,jdbcType=VARCHAR},
+      </if>
+      <if test="name != null">
+        #{name,jdbcType=VARCHAR},
+      </if>
+      <if test="email != null">
+        #{email,jdbcType=VARCHAR},
+      </if>
+      <if test="avatar != null">
+        #{avatar,jdbcType=VARCHAR},
+      </if>
+      <if test="createdAt != null">
+        #{createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updatedAt != null">
+        #{updatedAt,jdbcType=TIMESTAMP},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="cn.kdan.pdf.backend.core.model.SocialAccountsExample" resultType="java.lang.Long">
+    select count(*) from social_accounts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update social_accounts
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=VARCHAR},
+      </if>
+      <if test="record.memberId != null">
+        member_id = #{record.memberId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.provider != null">
+        provider = #{record.provider,jdbcType=INTEGER},
+      </if>
+      <if test="record.accountId != null">
+        account_id = #{record.accountId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.name != null">
+        `name` = #{record.name,jdbcType=VARCHAR},
+      </if>
+      <if test="record.email != null">
+        email = #{record.email,jdbcType=VARCHAR},
+      </if>
+      <if test="record.avatar != null">
+        avatar = #{record.avatar,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createdAt != null">
+        created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      </if>
+      <if test="record.updatedAt != null">
+        updated_at = #{record.updatedAt,jdbcType=TIMESTAMP},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update social_accounts
+    set id = #{record.id,jdbcType=VARCHAR},
+      member_id = #{record.memberId,jdbcType=VARCHAR},
+      provider = #{record.provider,jdbcType=INTEGER},
+      account_id = #{record.accountId,jdbcType=VARCHAR},
+      `name` = #{record.name,jdbcType=VARCHAR},
+      email = #{record.email,jdbcType=VARCHAR},
+      avatar = #{record.avatar,jdbcType=VARCHAR},
+      created_at = #{record.createdAt,jdbcType=TIMESTAMP},
+      updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <select id="selectByExampleWithRowbounds" parameterType="cn.kdan.pdf.backend.core.model.SocialAccountsExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from social_accounts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+</mapper>