xiongzhu пре 4 година
родитељ
комит
720fcb7e7c

+ 8 - 0
pom.xml

@@ -44,6 +44,14 @@
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>9</source>
+                    <target>9</target>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 

+ 5 - 1
src/main/java/com/izouma/nineth/domain/User.java

@@ -89,7 +89,7 @@ public class User extends BaseEntity implements Serializable {
 
     private String bg;
 
-    private String realName;
+    private Long authId;
 
     @ApiModelProperty("实名审核状态")
     @Enumerated(EnumType.STRING)
@@ -111,4 +111,8 @@ public class User extends BaseEntity implements Serializable {
     @ApiModelProperty("分成比例")
     @Column(precision = 10, scale = 2)
     private BigDecimal shareRatio;
+
+    private String memberId;
+
+    private String settleAccountId;
 }

+ 25 - 0
src/main/java/com/izouma/nineth/dto/BankValidate.java

@@ -0,0 +1,25 @@
+package com.izouma.nineth.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BankValidate {
+
+    private boolean validated;
+
+    private String stat;
+
+    private String bank;
+
+    private String bankName;
+
+    private String cardType;
+
+    private String cardTypeDesc;
+
+    private String key;
+}

+ 29 - 0
src/main/java/com/izouma/nineth/dto/UserBankCard.java

@@ -0,0 +1,29 @@
+package com.izouma.nineth.dto;
+
+import com.izouma.nineth.domain.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class UserBankCard extends BaseEntity {
+
+    private Long userId;
+
+    private String bank;
+
+    private String bankName;
+
+    private String cardType;
+
+    private String cardTypeDesc;
+
+    private String bankNo;
+}

+ 11 - 0
src/main/java/com/izouma/nineth/repo/UserBankCardRepo.java

@@ -0,0 +1,11 @@
+package com.izouma.nineth.repo;
+
+import com.izouma.nineth.dto.UserBankCard;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import java.util.List;
+
+public interface UserBankCardRepo extends JpaRepository<UserBankCard, Long>, JpaSpecificationExecutor<UserBankCard> {
+    List<UserBankCard> findByUserId(Long userId);
+}

+ 40 - 4
src/main/java/com/izouma/nineth/service/AdapayService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.huifu.adapay.core.exception.BaseAdaPayException;
 import com.huifu.adapay.model.AdapayCommon;
+import com.huifu.adapay.model.SettleAccount;
 import com.izouma.nineth.config.AdapayProperties;
 import com.izouma.nineth.exception.BusinessException;
 import lombok.AllArgsConstructor;
@@ -21,7 +22,7 @@ public class AdapayService {
 
     private final AdapayProperties adapayProperties;
 
-    public void createMember(Long id, String tel, String name, String idNo) throws BaseAdaPayException {
+    public String createMember(Long id, String tel, String name, String idNo) throws BaseAdaPayException {
         Map<String, Object> memberParams = new HashMap<>();
         memberParams.put("adapay_func_code", "members.realname");
         memberParams.put("member_id", id.toString());
@@ -32,9 +33,44 @@ public class AdapayService {
         memberParams.put("cert_id", idNo);
         Map<String, Object> member = AdapayCommon.requestAdapay(memberParams);
         log.info("createMember\n{}", JSON.toJSONString(member, SerializerFeature.PrettyFormat));
-        if (!"succeeded".equals(MapUtils.getString(member, "status"))) {
-            String errMsg = MapUtils.getString(member, "error_msg");
-            String errCode = MapUtils.getString(member, "error_code");
+        checkSuccess(member);
+        return MapUtils.getString(member, "member_id");
+    }
+
+    public String createSettleAccount(String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException {
+        Map<String, Object> settleCountParams = new HashMap<>();
+        Map<String, Object> accountInfo = new HashMap<>();
+        accountInfo.put("card_id", bankNo);
+        accountInfo.put("card_name", realName);
+        accountInfo.put("cert_id", idNo);
+        accountInfo.put("cert_type", "00");
+        accountInfo.put("tel_no", phone);
+        accountInfo.put("bank_acct_type", "2");
+        settleCountParams.put("member_id", memberId);
+        settleCountParams.put("app_id", adapayProperties.getAppId());
+        settleCountParams.put("channel", "bank_account");
+        settleCountParams.put("account_info", accountInfo);
+        Map<String, Object> settleCount = SettleAccount.create(settleCountParams);
+        log.info("createSettleAccount\n{}", JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
+        checkSuccess(settleCount);
+        return MapUtils.getString(settleCount, "id");
+    }
+
+    public void delSettleAccount(String memberId, String accountId) throws BaseAdaPayException {
+        Map<String, Object> settleCountParams = new HashMap<>();
+        settleCountParams.put("settle_account_id", accountId);
+        settleCountParams.put("member_id", memberId);
+        settleCountParams.put("app_id", adapayProperties.getAppId());
+        Map<String, Object> settleCount = SettleAccount.delete(settleCountParams);
+        log.info("delSettleAccount\n{}", JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
+        checkSuccess(settleCount);
+    }
+
+
+    public void checkSuccess(Map<String, Object> map) {
+        if (!"succeeded".equals(MapUtils.getString(map, "status"))) {
+            String errMsg = MapUtils.getString(map, "error_msg");
+            String errCode = MapUtils.getString(map, "error_code");
             throw new BusinessException(errMsg + "(" + errCode + ")");
         }
     }

+ 12 - 0
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -5,6 +5,7 @@ import com.izouma.nineth.domain.Collection;
 import com.izouma.nineth.dto.CollectionDTO;
 import com.izouma.nineth.dto.CreateBlindBox;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.CollectionSource;
 import com.izouma.nineth.enums.CollectionType;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
@@ -290,4 +291,15 @@ public class CollectionService {
         return collection.getCurrentNumber();
     }
 
+    public void addStock(Long id, int number) {
+        Collection collection = collectionRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+        if (collection.getSource() != CollectionSource.OFFICIAL) {
+            throw new BusinessException("用户转售无法增发");
+        }
+        if (collection.getType() == CollectionType.BLIND_BOX) {
+            throw new BusinessException("盲盒无法增发");
+        }
+        collection.setStock(collection.getStock() + number);
+        collection.setTotal(collection.getTotal() + number);
+    }
 }

+ 4 - 0
src/main/java/com/izouma/nineth/service/IdentityAuthService.java

@@ -20,6 +20,7 @@ public class IdentityAuthService {
 
     private IdentityAuthRepo identityAuthRepo;
     private UserRepo         userRepo;
+    private AdapayService    adapayService;
 
     public Page<IdentityAuth> all(PageQuery pageQuery) {
         return identityAuthRepo.findAll(JpaUtils.toSpecification(pageQuery, IdentityAuth.class), JpaUtils.toPageRequest(pageQuery));
@@ -49,6 +50,9 @@ public class IdentityAuthService {
             throw new BusinessException("已经审核过");
         }
         User user = userRepo.findByIdAndDelFalse(auth.getUserId()).orElseThrow(new BusinessException("用户不存在"));
+        if (status == AuthStatus.SUCCESS) {
+            user.setAuthId(auth.getId());
+        }
         auth.setStatus(status);
         identityAuthRepo.save(auth);
         user.setAuthStatus(status);

+ 21 - 0
src/main/java/com/izouma/nineth/service/UserService.java

@@ -3,6 +3,7 @@ package com.izouma.nineth.service;
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import com.huifu.adapay.core.exception.BaseAdaPayException;
 import com.izouma.nineth.config.Constants;
 import com.izouma.nineth.domain.Follow;
 import com.izouma.nineth.domain.IdentityAuth;
@@ -61,6 +62,7 @@ public class UserService {
     private IdentityAuthRepo  identityAuthRepo;
     private SysConfigService  sysConfigService;
     private CollectionService collectionService;
+    private AdapayService     adapayService;
 
     @CacheEvict(value = "user", key = "#user.username")
     public User update(User user) {
@@ -403,4 +405,23 @@ public class UserService {
         return map;
     }
 
+    public void addBankCard(Long userId, String bankNo, String phone, String code) throws BaseAdaPayException {
+        User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
+        IdentityAuth identityAuth = identityAuthRepo.findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(userId, AuthStatus.SUCCESS)
+                .orElseThrow(new BusinessException("用户未认证"));
+        if (identityAuth.isOrg()) {
+            throw new BusinessException("请绑定对公账户");
+        }
+        if (StringUtils.isEmpty(user.getMemberId())) {
+            user.setMemberId(adapayService.createMember(userId, user.getPhone(), identityAuth.getRealName(), identityAuth.getIdNo()));
+            userRepo.save(user);
+        }
+        smsService.verify(phone, code);
+        String accountId = adapayService.createSettleAccount(user.getMemberId(), identityAuth.getRealName(), identityAuth.getIdNo(),
+                phone, bankNo);
+
+        user.setSettleAccountId(accountId);
+        userRepo.save(user);
+    }
+
 }

+ 210 - 0
src/main/java/com/izouma/nineth/utils/BankUtils.java

@@ -0,0 +1,210 @@
+package com.izouma.nineth.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.nineth.dto.BankValidate;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class BankUtils {
+    private static final Map<String, String> nameMap = new HashMap<>() {{
+        put("ABC", "中国农业银行");
+        put("ARCU", "安徽省农村信用社");
+        put("ASCB", "鞍山银行");
+        put("AYCB", "安阳银行");
+        put("BANKWF", "潍坊银行");
+        put("BGB", "广西北部湾银行");
+        put("BHB", "河北银行");
+        put("BJBANK", "北京银行");
+        put("BJRCB", "北京农村商业银行");
+        put("BOC", "中国银行");
+        put("BOCD", "承德银行");
+        put("BOCY", "朝阳银行");
+        put("BOD", "东莞银行");
+        put("BODD", "丹东银行");
+        put("BOHAIB", "渤海银行");
+        put("BOJZ", "锦州银行");
+        put("BOP", "平顶山银行");
+        put("BOQH", "青海银行");
+        put("BOSZ", "苏州银行");
+        put("BOYK", "营口银行");
+        put("BOZK", "周口银行");
+        put("BSB", "包商银行");
+        put("BZMD", "驻马店银行");
+        put("CBBQS", "城市商业银行资金清算中心");
+        put("CBKF", "开封市商业银行");
+        put("CCB", "中国建设银行");
+        put("CCQTGB", "重庆三峡银行");
+        put("CDB", "国家开发银行");
+        put("CDCB", "成都银行");
+        put("CDRCB", "成都农商银行");
+        put("CEB", "中国光大银行");
+        put("CGNB", "南充市商业银行");
+        put("CIB", "兴业银行");
+        put("CITIC", "中信银行");
+        put("CMB", "招商银行");
+        put("CMBC", "中国民生银行");
+        put("COMM", "交通银行");
+        put("CQBANK", "重庆银行");
+        put("CRCBANK", "重庆农村商业银行");
+        put("CSCB", "长沙银行");
+        put("CSRCB", "常熟农村商业银行");
+        put("CZBANK", "浙商银行");
+        put("CZCB", "浙江稠州商业银行");
+        put("CZRCB", "常州农村信用联社");
+        put("DAQINGB", "龙江银行");
+        put("DLB", "大连银行");
+        put("DRCBCL", "东莞农村商业银行");
+        put("DYCB", "德阳商业银行");
+        put("DYCCB", "东营市商业银行");
+        put("DZBANK", "德州银行");
+        put("EGBANK", "恒丰银行");
+        put("FDB", "富滇银行");
+        put("FJHXBC", "福建海峡银行");
+        put("FJNX", "福建省农村信用社联合社");
+        put("FSCB", "抚顺银行");
+        put("FXCB", "阜新银行");
+        put("GCB", "广州银行");
+        put("GDB", "广东发展银行");
+        put("GDRCC", "广东省农村信用社联合社");
+        put("GLBANK", "桂林银行");
+        put("GRCB", "广州农商银行");
+        put("GSRCU", "甘肃省农村信用");
+        put("GXRCU", "广西省农村信用");
+        put("GYCB", "贵阳市商业银行");
+        put("GZB", "赣州银行");
+        put("GZRCU", "贵州省农村信用社");
+        put("H3CB", "内蒙古银行");
+        put("HANABANK", "韩亚银行");
+        put("HBC", "湖北银行");
+        put("HBHSBANK", "湖北银行黄石分行");
+        put("HBRCU", "河北省农村信用社");
+        put("HBYCBANK", "湖北银行宜昌分行");
+        put("HDBANK", "邯郸银行");
+        put("HKB", "汉口银行");
+        put("HKBEA", "东亚银行");
+        put("HNRCC", "湖南省农村信用社");
+        put("HNRCU", "河南省农村信用");
+        put("HRXJB", "华融湘江银行");
+        put("HSBANK", "徽商银行");
+        put("HSBK", "衡水银行");
+        put("HURCB", "湖北省农村信用社");
+        put("HXBANK", "华夏银行");
+        put("HZCB", "杭州银行");
+        put("HZCCB", "湖州市商业银行");
+        put("ICBC", "中国工商银行");
+        put("JHBANK", "金华银行");
+        put("JINCHB", "晋城银行JCBANK");
+        put("JJBANK", "九江银行");
+        put("JLBANK", "吉林银行");
+        put("JLRCU", "吉林农信");
+        put("JNBANK", "济宁银行");
+        put("JRCB", "江苏江阴农村商业银行");
+        put("JSB", "晋商银行");
+        put("JSBANK", "江苏银行");
+        put("JSRCU", "江苏省农村信用联合社");
+        put("JXBANK", "嘉兴银行");
+        put("JXRCU", "江西省农村信用");
+        put("JZBANK", "晋中市商业银行");
+        put("KLB", "昆仑银行");
+        put("KORLABANK", "库尔勒市商业银行");
+        put("KSRB", "昆山农村商业银行");
+        put("LANGFB", "廊坊银行");
+        put("LSBANK", "莱商银行");
+        put("LSBC", "临商银行");
+        put("LSCCB", "乐山市商业银行");
+        put("LYBANK", "洛阳银行");
+        put("LYCB", "辽阳市商业银行");
+        put("LZYH", "兰州银行");
+        put("MTBANK", "浙江民泰商业银行");
+        put("NBBANK", "宁波银行");
+        put("NBYZ", "鄞州银行");
+        put("NCB", "南昌银行");
+        put("NHB", "南海农村信用联社");
+        put("NHQS", "农信银清算中心");
+        put("NJCB", "南京银行");
+        put("NXBANK", "宁夏银行");
+        put("NXRCU", "宁夏黄河农村商业银行");
+        put("NYBANK", "广东南粤银行");
+        put("ORBANK", "鄂尔多斯银行");
+        put("PSBC", "中国邮政储蓄银行");
+        put("QDCCB", "青岛银行");
+        put("QLBANK", "齐鲁银行");
+        put("SCCB", "三门峡银行");
+        put("SCRCU", "四川省农村信用");
+        put("SDEB", "顺德农商银行");
+        put("SDRCU", "山东农信");
+        put("SHBANK", "上海银行");
+        put("SHRCB", "上海农村商业银行");
+        put("SJBANK", "盛京银行");
+        put("SPABANK", "平安银行");
+        put("SPDB", "上海浦东发展银行");
+        put("SRBANK", "上饶银行");
+        put("SRCB", "深圳农村商业银行");
+        put("SXCB", "绍兴银行");
+        put("SXRCCU", "陕西信合");
+        put("SZSBK", "石嘴山银行");
+        put("TACCB", "泰安市商业银行");
+        put("TCCB", "天津银行");
+        put("TCRCB", "江苏太仓农村商业银行");
+        put("TRCB", "天津农商银行");
+        put("TZCB", "台州银行");
+        put("URMQCCB", "乌鲁木齐市商业银行");
+        put("WHCCB", "威海市商业银行");
+        put("WHRCB", "武汉农村商业银行");
+        put("WJRCB", "吴江农商银行");
+        put("WRCB", "无锡农村商业银行");
+        put("WZCB", "温州银行");
+        put("XABANK", "西安银行");
+        put("XCYH", "许昌银行");
+        put("XJRCU", "新疆农村信用社");
+        put("XLBANK", "中山小榄村镇银行");
+        put("XMBANK", "厦门银行");
+        put("XTB", "邢台银行");
+        put("XXBANK", "新乡银行");
+        put("XYBANK", "信阳银行");
+        put("YBCCB", "宜宾市商业银行");
+        put("YDRCB", "尧都农商行");
+        put("YNRCC", "云南省农村信用社");
+        put("YQCCB", "阳泉银行");
+        put("YXCCB", "玉溪市商业银行");
+        put("ZBCB", "齐商银行");
+        put("ZGCCB", "自贡市商业银行");
+        put("ZJKCCB", "张家口市商业银行");
+        put("ZJNX", "浙江省农村信用社联合社");
+        put("ZJTLCB", "浙江泰隆商业银行");
+        put("ZRCBANK", "张家港农村商业银行");
+        put("ZYCBANK", "遵义市商业银行");
+        put("ZZBANK", "郑州银行");
+    }};
+
+    public static BankValidate validate(String bankNo) {
+        String body = HttpRequest
+                .get("https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=" + bankNo + "&cardBinCheck=true")
+                .body();
+        BankValidate bankValidate = JSON.parseObject(body, BankValidate.class);
+        log.info(JSON.toJSONString(bankValidate, SerializerFeature.PrettyFormat));
+        if (bankValidate.isValidated()) {
+            bankValidate.setBankName(nameMap.get(bankValidate.getBank()));
+            if ("DC".equals(bankValidate.getCardType())) {
+                bankValidate.setCardTypeDesc("储蓄卡");
+            } else if ("CC".equals(bankValidate.getCardType())) {
+                bankValidate.setCardTypeDesc("信用卡");
+            }
+
+        }
+        return bankValidate;
+    }
+
+    public static void main(String[] args) {
+        BankValidate res = BankUtils.validate("6222024301070380165");
+        log.info(JSON.toJSONString(res, SerializerFeature.PrettyFormat));
+
+        res = BankUtils.validate("6217770007358827");
+        log.info(JSON.toJSONString(res, SerializerFeature.PrettyFormat));
+    }
+}

+ 3 - 4
src/main/java/com/izouma/nineth/web/IdentityAuthController.java

@@ -1,12 +1,11 @@
 package com.izouma.nineth.web;
 
 import com.izouma.nineth.domain.IdentityAuth;
-import com.izouma.nineth.enums.AuthStatus;
-import com.izouma.nineth.service.IdentityAuthService;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.AuthStatus;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.IdentityAuthRepo;
-import com.izouma.nineth.utils.ObjUtils;
+import com.izouma.nineth.service.IdentityAuthService;
 import com.izouma.nineth.utils.SecurityUtils;
 import com.izouma.nineth.utils.excel.ExcelUtils;
 import lombok.AllArgsConstructor;
@@ -25,7 +24,7 @@ public class IdentityAuthController extends BaseController {
     private IdentityAuthService identityAuthService;
     private IdentityAuthRepo    identityAuthRepo;
 
-//    @PreAuthorize("hasRole('ADMIN')")
+//    @PreAuthorize("hasAnyRole('ADMIN','OPERATOR')")
     @PostMapping("/all")
     public Page<IdentityAuth> all(@RequestBody PageQuery pageQuery) {
         return identityAuthService.all(pageQuery);

+ 12 - 4
src/main/java/com/izouma/nineth/web/UserController.java

@@ -2,10 +2,12 @@ package com.izouma.nineth.web;
 
 import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.dto.UserBankCard;
 import com.izouma.nineth.dto.UserDTO;
 import com.izouma.nineth.dto.UserRegister;
 import com.izouma.nineth.enums.AuthorityName;
 import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.UserBankCardRepo;
 import com.izouma.nineth.repo.UserRepo;
 import com.izouma.nineth.security.Authority;
 import com.izouma.nineth.security.JwtTokenUtil;
@@ -34,10 +36,11 @@ import java.util.Map;
 @RestController
 @RequestMapping("/user")
 public class UserController extends BaseController {
-    private UserRepo      userRepo;
-    private UserService   userService;
-    private JwtTokenUtil  jwtTokenUtil;
-    private FollowService followService;
+    private UserRepo         userRepo;
+    private UserService      userService;
+    private JwtTokenUtil     jwtTokenUtil;
+    private FollowService    followService;
+    private UserBankCardRepo userBankCardRepo;
 
     @PostMapping("/register")
     public User register(@RequestParam String username,
@@ -206,6 +209,11 @@ public class UserController extends BaseController {
             ));
         }};
     }
+
+    @GetMapping("/myBankCard")
+    public List<UserBankCard> myBankCard() {
+        return userBankCardRepo.findByUserId(SecurityUtils.getAuthenticatedUser().getId());
+    }
 }
 
 

+ 11 - 0
src/test/java/com/izouma/nineth/service/AdapayServiceTest.java

@@ -15,4 +15,15 @@ public class AdapayServiceTest extends ApplicationTests {
     public void createMember() throws BaseAdaPayException {
         adapayService.createMember(99999999999999L, "15077886171", "熊竹", "321002199408304614");
     }
+
+    @Test
+    public void createSettleAccount() throws BaseAdaPayException {
+        adapayService.createSettleAccount("99999999999999", "熊竹", "321002199408304614",
+                "15077886171", "6222024301070380163");
+    }
+
+    @Test
+    public void delSettleAccount() throws BaseAdaPayException {
+        adapayService.delSettleAccount("99999999999999", "0288070028826880");
+    }
 }