Browse Source

添加抖音小程序相关代码

zsf 10 months ago
parent
commit
2c14deff30
21 changed files with 1177 additions and 172 deletions
  1. 37 0
      src/main/java/com/rf/psychological/douyin/config/DouYinConfig.java
  2. 198 0
      src/main/java/com/rf/psychological/douyin/controller/DouYinController.java
  3. 60 0
      src/main/java/com/rf/psychological/douyin/model/DouYinOrderEntity.java
  4. 39 0
      src/main/java/com/rf/psychological/douyin/repository/DouYinOrderRepository.java
  5. 52 0
      src/main/java/com/rf/psychological/douyin/service/DouYinOrderService.java
  6. 74 0
      src/main/java/com/rf/psychological/douyin/service/DouYinService.java
  7. 93 0
      src/main/java/com/rf/psychological/douyin/service/impl/DouYinOrderServiceImpl.java
  8. 400 0
      src/main/java/com/rf/psychological/douyin/service/impl/DouYinServiceImpl.java
  9. 27 0
      src/main/java/com/rf/psychological/douyin/task/DouYinOrderTask.java
  10. 146 0
      src/main/java/com/rf/psychological/douyin/util/SignUtil.java
  11. 5 1
      src/main/java/com/rf/psychological/enums/OrderStatus.java
  12. 22 9
      src/main/java/com/rf/psychological/rest/DeviceController.java
  13. 2 2
      src/main/java/com/rf/psychological/security/DESede.java
  14. 4 0
      src/main/java/com/rf/psychological/wxpay/utils/OrderNoUtils.java
  15. BIN
      src/main/resources/child.jue-ming.com.jks
  16. 0 100
      src/main/resources/config/application-dev.yml
  17. 0 56
      src/main/resources/config/application-prod.yml
  18. 18 4
      src/main/resources/config/application-public.yml
  19. BIN
      src/main/resources/org.jue-ming.com.jks
  20. BIN
      src/main/resources/server.jks
  21. BIN
      src/main/resources/test.jue-ming.com.jks

+ 37 - 0
src/main/java/com/rf/psychological/douyin/config/DouYinConfig.java

@@ -0,0 +1,37 @@
+package com.rf.psychological.douyin.config;
+
+import lombok.Data;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @Description:抖音相关配置参数
+ * @Author: mimang
+ * @Date: 2023/8/15
+ */
+@Data
+@Configuration
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class DouYinConfig {
+
+    private String appid;
+
+    private String appName;
+
+    private String secret;
+
+    private String sessionUrl;
+
+    private String tokenUrl;
+
+    private String codeUrl;
+
+    private String notifyUrl;
+
+    private String createOrderUrl;
+
+    private String queryOrderUrl;
+
+    private String pushOrderUrl;
+}

+ 198 - 0
src/main/java/com/rf/psychological/douyin/controller/DouYinController.java

@@ -0,0 +1,198 @@
+package com.rf.psychological.douyin.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.rf.psychological.base.rest.BaseController;
+import com.rf.psychological.douyin.service.DouYinService;
+import com.rf.psychological.security.AesEncryptUtils;
+import com.rf.psychological.security.SafetyProcess;
+import com.rf.psychological.utils.Result;
+import com.rf.psychological.wxpay.utils.HttpUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * @Description:抖音相关接口
+ * @Author: mimang
+ * @Date: 2023/8/15
+ */
+@CrossOrigin //跨域
+@RestController
+@RequestMapping("/api/douyin")
+@Api(tags = "抖音相关接口")
+@Slf4j
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class DouYinController extends BaseController {
+
+    @Autowired
+    private DouYinService douYinService;
+
+
+    @PostMapping("/code2Session")
+    @ApiOperation(value = "抖音小程序登录",notes = "code:临时code,获取openid")
+    @SafetyProcess
+    public Result code2openid2(@RequestBody String json) throws Exception {
+        JSONObject resultJson = new JSONObject();
+
+        try {
+            JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
+            //校验参数
+            if (data==null){
+                return fail(null,"参数错误");
+            }
+            String code = data.getString("code");
+            if (StringUtils.isEmpty(code)){
+                return fail(null,"参数错误");
+            }
+            //获取session
+            String openid = douYinService.jscode2session(code);
+            if (StringUtils.isEmpty(openid)){
+                return fail(null,"获取openId异常");
+            }
+            //静默注册登录
+            resultJson.put("openId",openid);
+            resultJson = douYinService.douyinLogin(openid,resultJson);
+
+            return success(resultJson);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            return fail(null,"操作失败"+e.getMessage());
+        }
+    }
+
+    @PostMapping("/getRQCode")
+    @ApiOperation(value = "获取小程序二维码",notes = "appname:是打开二维码的字节系app名称(toutiao:今日头条,toutiao_lite:今日头条极速版,douyin:抖音,douyin_lite:抖音极速版,huoshan:抖音火山版);" +
+            "path:小程序/小游戏启动参数,小程序则格式为 encode({path}?{query}),小游戏则格式为 JSON 字符串,默认为空")
+    @SafetyProcess
+    public Result getRQCode(@RequestBody String json) throws Exception {
+        try {
+            JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
+            //校验参数
+            if (data==null){
+                return fail(null,"参数错误");
+            }
+            String path = data.getString("path");
+            String appname = data.getString("appname");
+            //获取二维码
+            String resultCode = douYinService.getRQCode(appname,path);
+            return success(resultCode);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            return fail(null,"操作失败"+e.getMessage());
+        }
+    }
+
+    @PostMapping("/createOrder")
+    @ApiOperation(value = "预下单接口",notes = "resultId:测试结果id;total_amount:支付价格(单位为[分]);subject:商品描述。 长度限制不超过 128 字节且不超过 42 字符;" +
+            "body:商品详情 长度限制不超过 128 字节且不超过 42 字符;msgPage:支付完成后推送给用户的抖音消息跳转页面,开发者需要传入在app.json中定义的链接,如果不传则跳转首页" )
+    @SafetyProcess
+    public Result createOrder(@RequestBody String json)  {
+        try {
+            JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
+            //校验参数
+            if (data==null){
+                return fail(null,"参数错误");
+            }
+            int totalAmount = data.getIntValue("total_amount");
+            String subject = data.getString("subject");
+            String body = data.getString("body");
+            String resultId = data.getString("resultId");
+            String path = data.getString("msgPage");
+            Map<String,Object> map = douYinService.createOrder(totalAmount,subject,body,resultId,path);
+            return success(map);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            return fail(null,"操作失败"+e.getMessage());
+        }
+    }
+
+    @SafetyProcess
+    @ApiOperation("查询订单")
+    @GetMapping("/queryOrder/{orderNo}")
+    public Result queryOrder(@PathVariable String orderNo)  {
+        try {
+            Map<String, Object> map = douYinService.queryOrder(orderNo);
+            return success(map);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            return fail(null,"操作失败"+e.getMessage());
+        }
+    }
+
+    @ApiOperation(value = "抖音微信订单回调接口")
+    @RequestMapping(value = "/notify", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
+    @ResponseBody
+    public Object notify(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            request.setCharacterEncoding("utf-8");
+            response.setCharacterEncoding("utf-8");
+            response.setContentType("text/html;charset=UTF-8");
+            response.setHeader("Access-Control-Allow-Origin", "*");
+            String responseJson = HttpUtils.readData(request);
+            log.info("responseJson:{}",responseJson);
+            JSONObject jsonObject = JSONObject.parseObject(responseJson);
+            JSONObject msgJson = jsonObject.getJSONObject("msg");
+            String resultCode = jsonObject.getString("type");
+            JSONObject resultJson = douYinService.notifyOrder(jsonObject,msgJson,resultCode);
+            return resultJson.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+            JSONObject resultJson = new JSONObject();
+            resultJson.put("err_no",8);
+            resultJson.put("err_tips","error");
+            return resultJson.toString();
+        }
+    }
+
+    @SafetyProcess
+    @ApiOperation("根据报告Id查询用户结果支付情况")
+    @GetMapping("/queryOrderByResultId/{resultId}")
+    public Result queryOrderByResultId(@PathVariable("resultId") String resultId ){
+        try {
+            return success(douYinService.queryOrderByResultId(resultId));
+        }catch (Exception e){
+            return fail();
+        }
+    }
+
+    @PostMapping("/pushOrder")
+    @ApiOperation(value = "订单同步",notes = "resultId:测试结果id;total_amount:支付价格(单位为[分]);subject:量表名称;path:量表详情路径" +
+            "orderNo:订单号;openId:用户openid ;orderStatus:0:待支付1:已支付 2:已取消;imgPath:商品图片" )
+    //@SafetyProcess
+    public Result pushOrder(@RequestBody String json)  {
+        try {
+            JSONObject data = JSONObject.parseObject(AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data")));
+            //校验参数
+            if (data==null){
+                return fail(null,"参数错误");
+            }
+            int totalAmount = data.getIntValue("total_amount");
+            String subject = data.getString("subject");
+            String orderNo = data.getString("orderNo");
+            String openId = data.getString("openId");
+            int orderStatus = data.getIntValue("orderStatus");
+            String resultId = data.getString("resultId");
+            String imgPath = data.getString("imgPath");
+            String path = data.getString("msgPage");
+            JSONObject map = douYinService.pushOrder(orderNo,resultId,subject,openId,totalAmount,path,orderStatus,imgPath);
+            return success(map);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            return fail(null,"操作失败"+e.getMessage());
+        }
+    }
+
+}

+ 60 - 0
src/main/java/com/rf/psychological/douyin/model/DouYinOrderEntity.java

@@ -0,0 +1,60 @@
+package com.rf.psychological.douyin.model;
+
+import com.rf.psychological.base.model.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.DynamicUpdate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * @Description:抖音订单
+ * @Author: mimang
+ * @Date: 2023/8/17
+ */
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+@Entity
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper=false)
+@Table(name = "t_douyin_order_info")
+@org.hibernate.annotations.Table(appliesTo = "t_douyin_order_info", comment = "抖音订单信息表")
+@DynamicUpdate(value = true)
+public class DouYinOrderEntity extends BaseEntity {
+
+    @Column(name = "subject", columnDefinition = "varchar(100) comment '商品描述'")
+    private String subject;
+
+    @Column(name = "body", columnDefinition = "varchar(100) comment '商品详情 '")
+    private String body;
+
+    @Column(name = "out_order_no", columnDefinition = "varchar(50) comment '商户订单编号'")
+    private String outOrderNo;//商户订单编号
+
+    @Column(name = "result_id", columnDefinition = "varchar(36) comment '报告结果id'")
+    private String resultId;//报告结果id
+
+    @Column(name = "total_amount", columnDefinition = "int(11) comment '支付价格(分)'")
+    private Integer totalAmount;//订单金额(分)
+
+    @Column(name = "order_id", columnDefinition = "varchar(128) comment '抖音侧唯一订单号'")
+    private String orderId;
+
+    @Column(name = "order_token", columnDefinition = "varchar(200) comment '签名后的订单信息'")
+    private String orderToken;
+
+    @Column(name = "order_status", columnDefinition = "varchar(20) comment '订单状态'")
+    private String orderStatus;//订单状态
+
+    @Column(name = "create_time", columnDefinition = "varchar(20) comment '创建时间'")
+    private String createTime;//创建时间
+
+    @Column(name = "update_time", columnDefinition = "varchar(20) comment '更新时间'")
+    private String updateTime;//更新时间
+}

+ 39 - 0
src/main/java/com/rf/psychological/douyin/repository/DouYinOrderRepository.java

@@ -0,0 +1,39 @@
+package com.rf.psychological.douyin.repository;
+
+import com.rf.psychological.base.repository.BaseRepository;
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.util.List;
+
+/**
+ * @Description:抖音订单
+ * @Author: mimang
+ * @Date: 2023/8/17
+ */
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public interface DouYinOrderRepository extends BaseRepository<DouYinOrderEntity,String> {
+
+    /**
+     * 根据结果Id获取订单信息
+     * @param result
+     * @param status
+     * @return
+     */
+    DouYinOrderEntity findFirstByResultIdAndOrderStatus(String result,String status);
+
+    /**
+     * 根据订单编号查询
+     * @param outOrderNo 订单编号
+     * @return
+     */
+    DouYinOrderEntity findByOutOrderNo(String outOrderNo);
+
+    List<DouYinOrderEntity> findAllByOrderStatus(String type);
+
+    /**
+     * 根据订单编号删除该订单
+     * @param outOrderByNo
+     */
+    void deleteByOutOrderNo(String outOrderByNo);
+}

+ 52 - 0
src/main/java/com/rf/psychological/douyin/service/DouYinOrderService.java

@@ -0,0 +1,52 @@
+package com.rf.psychological.douyin.service;
+
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
+import com.rf.psychological.enums.OrderStatus;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.util.List;
+
+/**
+ * @Description:订单
+ * @Author: mimang
+ * @Date: 2023/8/17
+ */
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public interface DouYinOrderService {
+    /**
+     * 获取订单
+     * @param resultId 结果Id
+     * @param type 支付状态
+     * @return
+     */
+    DouYinOrderEntity findByResultIdAndStatus(String resultId, String type);
+
+    /**
+     * 创建新的新订单
+     * @param totalAmount 金额
+     * @param subject 描述
+     * @param body 详情
+     * @param resultId 结果Id
+     * @return
+     */
+    DouYinOrderEntity createNewOrder(int totalAmount, String subject, String body, String resultId);
+
+    void updateOrder(DouYinOrderEntity orderInfo);
+
+    DouYinOrderEntity findByOutOrderNo(String orderNo);
+
+    /**
+     * 根据订单状态获取到所有订单
+     * @param notpay
+     * @return
+     */
+    List<DouYinOrderEntity> findAllByStatus(OrderStatus notpay);
+    /**
+     * 判断是否支付
+     * @param resultId
+     * @return
+     */
+    boolean checkPayOrder(String resultId);
+
+    void deleteByNo(String outOrderNo);
+}

+ 74 - 0
src/main/java/com/rf/psychological/douyin/service/DouYinService.java

@@ -0,0 +1,74 @@
+package com.rf.psychological.douyin.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.util.Map;
+
+/**
+ * @Description:抖音接口
+ * @Author: mimang
+ * @Date: 2023/8/15
+ */
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public interface DouYinService {
+
+
+
+    /**
+     * 获取到用户openid
+     * @param code
+     * @return
+     * @throws Exception
+     */
+    String jscode2session(String code) throws Exception;
+
+    /**
+     * 静默登录注册
+     * @param openid 用户openid
+     * @param resultJson 待返回结果数据
+     * @return
+     */
+    JSONObject douyinLogin(String openid, JSONObject resultJson);
+
+    /**
+     * 获取到token
+     * @return
+     */
+    String getAccessToken() throws Exception;
+
+    String getRQCode(String appname, String path) throws Exception;
+
+    /**
+     * 预下单
+     * @param totalAmount 金额
+      * @param subject 主题
+     * @param body 介绍
+     * @param resultId 结果Id
+     * @return
+     */
+    Map<String, Object> createOrder(int totalAmount, String subject, String body, String resultId, String path) throws Exception;
+
+
+    /**
+     * 查询订单支付情况
+     * @param orderNo 订单编号
+     * @return
+     */
+    Map<String, Object> queryOrder(String orderNo) throws Exception;
+
+    void checkOrderStatus();
+
+    /**
+     * 处理回调结果
+     * @param msgJson 信息
+     * @param resultCode 返回code
+     * @return
+     */
+    JSONObject notifyOrder(JSONObject jsonObject, JSONObject msgJson, String resultCode);
+
+    DouYinOrderEntity queryOrderByResultId(String resultId);
+
+    JSONObject pushOrder(String orderNo,String resultId,String title,String openId,int totalAmount, String path,int orderStatus,String imgPath) throws Exception;
+}

+ 93 - 0
src/main/java/com/rf/psychological/douyin/service/impl/DouYinOrderServiceImpl.java

@@ -0,0 +1,93 @@
+package com.rf.psychological.douyin.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
+import com.rf.psychological.douyin.repository.DouYinOrderRepository;
+import com.rf.psychological.douyin.service.DouYinOrderService;
+import com.rf.psychological.enums.OrderStatus;
+import com.rf.psychological.wxpay.utils.OrderNoUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Description:订单信息
+ * @Author: mimang
+ * @Date: 2023/8/17
+ */
+@Service
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class DouYinOrderServiceImpl implements DouYinOrderService {
+
+    @Autowired
+    private DouYinOrderRepository repository;
+
+    /**
+     * 获取订单
+     * @param resultId 结果Id
+     * @param type 支付状态
+     * @return
+     */
+    @Override
+    public DouYinOrderEntity findByResultIdAndStatus(String resultId, String type) {
+        return repository.findFirstByResultIdAndOrderStatus(resultId,type);
+    }
+
+    /**
+     * 生成新的订单
+     * @param totalAmount 金额
+     * @param subject 描述
+     * @param body 详情
+     * @param resultId 结果Id
+     * @return
+     */
+    @Override
+    public DouYinOrderEntity createNewOrder(int totalAmount, String subject, String body, String resultId) {
+        DouYinOrderEntity entity = new DouYinOrderEntity();
+        entity.setCreateTime(DateUtil.now());
+        entity.setBody(body);
+        entity.setSubject(subject);
+        entity.setTotalAmount(totalAmount);
+        entity.setResultId(resultId);
+        entity.setOrderStatus(OrderStatus.PROCESSING.name());
+        entity.setOutOrderNo(OrderNoUtils.getDouYinOrderNo());
+        return repository.save(entity);
+    }
+
+    @Override
+    public void updateOrder(DouYinOrderEntity orderInfo) {
+        orderInfo.setUpdateTime(DateUtil.now());
+        repository.save(orderInfo);
+    }
+
+    @Override
+    public DouYinOrderEntity findByOutOrderNo(String orderNo) {
+        return repository.findByOutOrderNo(orderNo);
+    }
+
+    @Override
+    public List<DouYinOrderEntity> findAllByStatus(OrderStatus notpay) {
+        return repository.findAllByOrderStatus(notpay.name());
+    }
+
+    @Override
+    public boolean checkPayOrder(String resultId) {
+        try {
+            DouYinOrderEntity orderInfo = repository.findFirstByResultIdAndOrderStatus(resultId,OrderStatus.SUCCESS.name());
+            if ( orderInfo == null){
+                return false;
+            }
+            return true;
+        }catch (Exception e){
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    @Override
+    public void deleteByNo(String outOrderNo) {
+        repository.deleteByOutOrderNo(outOrderNo);
+    }
+}

+ 400 - 0
src/main/java/com/rf/psychological/douyin/service/impl/DouYinServiceImpl.java

@@ -0,0 +1,400 @@
+package com.rf.psychological.douyin.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.rf.psychological.douyin.config.DouYinConfig;
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
+import com.rf.psychological.douyin.service.DouYinOrderService;
+import com.rf.psychological.douyin.service.DouYinService;
+import com.rf.psychological.douyin.util.SignUtil;
+import com.rf.psychological.enums.OrderStatus;
+import com.rf.psychological.enums.UserRole;
+import com.rf.psychological.group.service.GroupInfoService;
+import com.rf.psychological.user.dao.model.UserEntity;
+import com.rf.psychological.user.service.UserService;
+import com.rf.psychological.utils.Constant;
+import com.rf.psychological.utils.JWTUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * @Description:
+ * @Author: mimang
+ * @Date: 2023/8/15
+ */
+@Slf4j
+@Service
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class DouYinServiceImpl implements DouYinService {
+
+    @Resource
+    private DouYinConfig douYinConfig;
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private GroupInfoService groupInfoService;
+
+    @Resource
+    private DouYinOrderService orderInfoService;
+
+    /**
+     * 获取到openid
+     * @param code login 接口返回的登录凭证
+     * @return
+     */
+    @Override
+    public String jscode2session(String code) throws Exception {
+        String url = douYinConfig.getSessionUrl();
+
+        Map<String,Object> paramsMap = new HashMap<>();
+        paramsMap.put("code",code);
+        paramsMap.put("appid",douYinConfig.getAppid());
+        paramsMap.put("secret",douYinConfig.getSecret());
+        JSONObject data = generateReq(url,paramsMap,"err_no").getObject("data",JSONObject.class);
+        return data.getString("openid");
+    }
+
+    private JSONObject generateReq(String url,Map<String, Object> params,String errCode) throws Exception{
+        //创建httpclient对象
+        CloseableHttpClient client = HttpClients.createDefault();
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeader("Accept", "application/json");
+        String jsonParams = JSONObject.toJSONString(params);
+        StringEntity entity = new StringEntity(jsonParams,"utf-8");
+        entity.setContentType("application/json");
+        httpPost.setEntity(entity);
+        httpPost.setHeader("Accept","application/json");
+
+        CloseableHttpResponse response = client.execute(httpPost);
+        JSONObject bodyJson =JSONObject.parseObject( EntityUtils.toString(response.getEntity()));//获取响应体
+        int errNo = bodyJson.getInteger(errCode);
+        if (errNo != 0){
+            throw new Exception(errNo+"---------"+bodyJson.toString());
+        }
+        log.info(url+"------------"+bodyJson.toString());
+        return bodyJson;
+    }
+
+    private InputStream generateCode(String url, Map<String, Object> params) throws Exception{
+        //创建httpclient对象
+        CloseableHttpClient client = HttpClients.createDefault();
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setHeader("Accept", "application/json");
+        String jsonParams = JSONObject.toJSONString(params);
+        StringEntity entity = new StringEntity(jsonParams,"utf-8");
+        entity.setContentType("application/json");
+        httpPost.setEntity(entity);
+        httpPost.setHeader("Accept","application/json");
+
+        CloseableHttpResponse response = client.execute(httpPost);
+//        JSONObject bodyJson =JSONObject.parseObject( EntityUtils.toString(response.getEntity()));//获取响应体
+//        int errNo = bodyJson.getInteger("errcode");
+//        if (errNo != 0){
+//            throw new Exception(errNo+"---------"+bodyJson.getString("errmsg"));
+//        }
+        return response.getEntity().getContent();
+    }
+
+    @Override
+    public JSONObject douyinLogin(String openid, JSONObject resultJson) {
+        UserEntity userEntity = this.userService.findPhoneAndInstitutionNoAndRoleType(openid, Constant.WEB_INSTITUTION_CODE, UserRole.COMMON.getType());
+        if(userEntity != null){
+            userEntity.setPassword("-");
+            resultJson.put("user", userEntity);
+            resultJson.put("type", userEntity.getRoleType());
+            resultJson.put("improve",false);
+        }else{
+            //注册
+            userEntity = new UserEntity();
+            userEntity.setPassword("-");
+            userEntity.setGId(this.groupInfoService.findGroupByInstitutionNoAndName(Constant.WEB_INSTITUTION_CODE,Constant.DEFAULT_GROUP_NAME).getId());
+            userEntity.setInstitutionName(Constant.WEB_INSTITUTION_NAME);
+            userEntity.setInstitutionNo(Constant.WEB_INSTITUTION_CODE);
+            userEntity.setUserStatus(Constant.USER_STATUS_NORMAL);
+            userEntity.setBirthday("-");
+            userEntity.setGender("-");
+            userEntity.setPetName("抖音用户");
+            userEntity.setProfession("-");
+            userEntity.setAdditionInfo("抖音小程序注册用户");
+            userEntity.setPhone(openid);
+            userEntity.setRoleType(UserRole.COMMON.getType());
+            userEntity = this.userService.save(userEntity);
+            resultJson.put("improve",true);
+        }
+
+        resultJson.put("token", JWTUtil.getTokenByUserInfo(userEntity));
+        resultJson.put("user",userEntity);
+        resultJson.put("type",userEntity.getRoleType());
+        return resultJson;
+    }
+
+    /**
+     * 获取accessToken
+     * @return
+     */
+    @Override
+    public String getAccessToken() throws Exception {
+        String url = douYinConfig.getTokenUrl();
+        Map<String,Object> paramsMap = new HashMap<>();
+        paramsMap.put("appid",douYinConfig.getAppid());
+        paramsMap.put("secret",douYinConfig.getSecret());
+        paramsMap.put("grant_type","client_credential");
+        JSONObject data = generateReq(url,paramsMap,"err_no").getObject("data",JSONObject.class);
+        return data.getString("access_token");
+    }
+
+    @Override
+    public String getRQCode(String appname, String path) throws Exception {
+        String url = douYinConfig.getCodeUrl();
+        String token = this.getAccessToken();
+        Map<String,Object> paramsMap = new HashMap<>();
+        paramsMap.put("access_token",token);
+        paramsMap.put("appname",appname);
+        paramsMap.put("path",path);
+        InputStream inputStream = this.generateCode(url,paramsMap);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len = -1;
+        while ((len = inputStream.read(buffer)) != -1) {
+            baos.write(buffer, 0, len);
+        }
+        return Base64.getEncoder().encodeToString(baos.toByteArray());
+    }
+
+    /**
+     * 预下单
+     * @param totalAmount 金额
+     * @param subject 主题
+     * @param body 介绍
+     * @param resultId 结果Id
+     * @return
+     */
+    @Override
+    public Map<String, Object> createOrder(int totalAmount, String subject, String body, String resultId, String path) throws Exception {
+        Map<String, Object> map = new HashMap<>();
+        //首先检测是否存在未支付订单
+        DouYinOrderEntity orderInfo = orderInfoService.findByResultIdAndStatus(resultId, OrderStatus.PROCESSING.name());
+        if (orderInfo != null) {
+            if (StringUtils.isNotEmpty(orderInfo.getOrderId())) {
+                map.put("orderId", orderInfo.getOrderId());
+                map.put("orderToken", orderInfo.getOrderToken());
+                map.put("orderNo", orderInfo.getOutOrderNo());
+                return map;
+            }
+        } else {
+            //如果为空创建新的订单
+            orderInfo = orderInfoService.createNewOrder(totalAmount, subject, body, resultId);
+        }
+
+        //调用抖音接口生成订单
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("app_id", douYinConfig.getAppid());
+        paramMap.put("out_order_no", orderInfo.getOutOrderNo());
+        paramMap.put("total_amount", totalAmount);
+        paramMap.put("subject", subject);
+        paramMap.put("body", body);
+        paramMap.put("valid_time", 900);
+        paramMap.put("notify_url", douYinConfig.getNotifyUrl());
+        if (StringUtils.isNotEmpty(path)) {
+            paramMap.put("msg_page", path);
+        }
+        paramMap.put("sign", SignUtil.requestSign(paramMap));
+        JSONObject jsonObject = null;
+        try {
+            jsonObject = this.generateReq(douYinConfig.getCreateOrderUrl(), paramMap,"err_no").getObject("data", JSONObject.class);
+
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+            orderInfoService.deleteByNo(orderInfo.getOutOrderNo());
+            return map;
+        }
+        //更新表单
+        orderInfo.setOrderId(jsonObject.getString("order_id"));
+        orderInfo.setOrderToken(jsonObject.getString("order_token"));
+        orderInfoService.updateOrder(orderInfo);
+        map.put("orderId", jsonObject.getString("order_id"));
+        map.put("orderToken", jsonObject.getString("order_token"));
+        map.put("orderNo", orderInfo.getOutOrderNo());
+        return map;
+    }
+
+    @Override
+    public Map<String, Object> queryOrder(String orderNo) throws Exception {
+
+        Map<String,Object> resultMap = new HashMap();
+        //首先查询本地订单
+        DouYinOrderEntity order = orderInfoService.findByOutOrderNo(orderNo);
+        if (order==null){
+            throw new Exception("订单号不存在");
+        }
+        if (OrderStatus.SUCCESS.equals(order.getOrderStatus())){
+            resultMap.put("statusCode",order.getOrderStatus());
+            return resultMap;
+        }
+        //远程查询
+        JSONObject resultJson = this.queryOrderByOutOrderNo(orderNo);
+        String status = resultJson.getString("order_status");
+        order.setOrderStatus(status);
+        orderInfoService.updateOrder(order);
+        resultMap.put("statusCode",status);
+        return resultMap;
+    }
+
+
+
+    private JSONObject queryOrderByOutOrderNo(String order) throws Exception {
+        Map<String,Object> paramMap = new HashMap<>();
+        paramMap.put("app_id",douYinConfig.getAppid());
+        paramMap.put("out_order_no",order);
+        paramMap.put("sign",SignUtil.requestSign(paramMap));
+        JSONObject result = this.generateReq(douYinConfig.getQueryOrderUrl(), paramMap,"err_no").getObject("payment_info",JSONObject.class);
+        return result;
+    }
+
+    /**
+     * 检测订单状态,是否超时
+     */
+    @Override
+    public void checkOrderStatus() {
+        List<DouYinOrderEntity> list  = orderInfoService.findAllByStatus(OrderStatus.PROCESSING);
+        if (CollectionUtils.isEmpty(list)){
+            return;
+        }
+        list.forEach(item->{
+            //远程查询
+            JSONObject resultJson = null;
+            try {
+                resultJson = this.queryOrderByOutOrderNo(item.getOutOrderNo());
+                String status = resultJson.getString("order_status");
+                item.setOrderStatus(status);
+                orderInfoService.updateOrder(item);
+            } catch (Exception e) {
+                //订单号不存在,删除该订单
+                log.error(e.getMessage());
+                String msg = e.getMessage();
+                if (msg.contains("2000")){
+                    orderInfoService.deleteByNo(item.getOutOrderNo());
+                }
+                e.printStackTrace();
+            }
+        });
+
+    }
+
+    /**
+     * 回调信息处理
+     * @param msgJson 信息
+     * @param resultCode 返回code
+     * @return
+     */
+    @Override
+    public JSONObject notifyOrder(JSONObject jsonObject, JSONObject msgJson, String resultCode) {
+        JSONObject resultJson = new JSONObject();
+        //订单编号
+        String outTradeNo = msgJson.getString("cp_orderno");
+        DouYinOrderEntity entity = orderInfoService.findByOutOrderNo(outTradeNo);
+        if ("payment".equalsIgnoreCase(resultCode)) {
+            List<String> sortedString = new ArrayList<>();
+            //token
+            sortedString.add(SignUtil.TOKEN);
+            //时间戳
+            sortedString.add(jsonObject.getString("timestamp"));
+            //随机数
+            sortedString.add(jsonObject.getString("nonce"));
+            //msg
+            sortedString.add(jsonObject.getString("msg"));
+            Collections.sort(sortedString);
+//                StringBuilder sb = new StringBuilder();
+//                sortedString.forEach(sb::append);
+            String msg_signature = jsonObject.getString("msg_signature");
+            String sign = SignUtil.callbackSign(sortedString);
+            log.info("支付回调接口密钥签名:{}",sign);
+            if(!sign.equals(msg_signature)) {//判断签名
+                resultJson.put("err_no",8);
+                resultJson.put("err_tips","error");
+                entity.setOrderStatus(OrderStatus.SUCCESS.name());
+            }
+            resultJson.put("err_no",0);
+            resultJson.put("err_tips","success");
+        } else {
+            log.error("订单" + outTradeNo + "支付失败");
+            resultJson.put("err_no",0);
+            resultJson.put("err_tips","error");
+            entity.setOrderStatus(OrderStatus.FAIL.name());
+        }
+        orderInfoService.updateOrder(entity);
+        return resultJson;
+    }
+
+    @Override
+    public DouYinOrderEntity queryOrderByResultId(String resultId) {
+        return orderInfoService.findByResultIdAndStatus(resultId,OrderStatus.SUCCESS.name());
+    }
+
+    public JSONObject pushOrder(String orderNo,String resultId,String title,String openId,int totalAmount, String path,int orderStatus,String imgPath) throws Exception {
+        JSONObject jsonObject = null;
+        try {
+            List<Map<String,Object>> itemList = new ArrayList<>();
+            Map<String,Object> item = new HashMap<>();
+            item.put("item_code", resultId);
+            item.put("img", imgPath);
+            item.put("title", title);
+            item.put("amount", 1);
+            item.put("price", totalAmount);
+            itemList.add(item);
+
+            //生成订单详情
+            Map<String,Object> detailMap = new HashMap<>();
+            detailMap.put("order_id", orderNo);
+            detailMap.put("create_time", DateUtil.current());
+            switch (orderStatus){
+                case 0:
+                    detailMap.put("status", "待支付");
+                case 1:
+                    detailMap.put("status", "已支付");
+                case 2:
+                    detailMap.put("status", "已取消");
+            }
+            detailMap.put("amount", 1);
+            detailMap.put("total_price", totalAmount);
+            detailMap.put("detail_url", path);
+            detailMap.put("item_list", itemList);
+            //调用抖音接口生成订单
+            Map<String, Object> paramMap = new HashMap<>();
+            paramMap.put("access_token", getAccessToken());
+            paramMap.put("app_name", douYinConfig.getAppName());
+            paramMap.put("app_id", douYinConfig.getAppid());
+            paramMap.put("open_id", openId);
+            paramMap.put("order_detail", JSONObject.toJSONString(detailMap));
+            paramMap.put("order_status", orderStatus);
+            paramMap.put("order_type", 0);
+            paramMap.put("update_time", DateUtil.currentSeconds());
+            jsonObject = this.generateReq(douYinConfig.getPushOrderUrl(), paramMap,"err_code");
+            log.info(jsonObject.toJSONString());
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error(e.getMessage());
+            throw e;
+        }
+        return jsonObject;
+    }
+
+
+}

+ 27 - 0
src/main/java/com/rf/psychological/douyin/task/DouYinOrderTask.java

@@ -0,0 +1,27 @@
+package com.rf.psychological.douyin.task;
+
+import com.rf.psychological.douyin.service.DouYinService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description:订单任务
+ * @Author: mimang
+ * @Date: 2023/8/18
+ */
+@Slf4j
+@Component
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class DouYinOrderTask {
+
+    @Autowired
+    private DouYinService douYinService;
+
+    @Scheduled(cron = "0/59 * * * * ?")
+    public void taskQueryOrder() throws Exception {
+        douYinService.checkOrderStatus();
+    }
+}

+ 146 - 0
src/main/java/com/rf/psychological/douyin/util/SignUtil.java

@@ -0,0 +1,146 @@
+/**
+ * Copyright 2022 Beijing Douyin Information Service Co., Ltd.
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Package com.bytedance.microapp Sign 签名算法
+ * <p>
+ * Package com.bytedance.microapp Sign implement the signature algorithm
+ */
+
+package com.rf.psychological.douyin.util;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
+public class SignUtil {
+
+    /**
+     * 担保支付请求不参与签名参数
+     * app_id 小程序appID
+     * thirdparty_id 代小程序进行该笔交易调用的第三方平台服务商id
+     * sign 签名
+     * other_settle_params 其他分账方参数
+     *
+     * Guaranteed payment requests do not participate in signature parameters
+     * app_id Applets appID
+     * thirdparty_id The id of the third-party platform service provider that calls the transaction on behalf of the Applets
+     * sign sign
+     * other_settle_params Other settle params
+     */
+    public final static List<String> REQUEST_NOT_NEED_SIGN_PARAMS = Arrays.asList("app_id", "thirdparty_id", "sign", "other_settle_params");
+
+    /**
+     * 支付密钥值,需要替换为自己的密钥(完成进件后,开发者可在字节开放平台-【某小程序】-【功能】-【支付】-【担保交易设置】中查看支付系统秘钥 SALT)
+     *
+     * Payment key value, you need to replace it with your own key
+     */
+    //private static final String SALT = "I9mmeXYF5lvXonBkvohpVnHOqm2LMJQhLZbrAFDK";
+    private static final String SALT = "YqZmSCq156ZfbM8Fg5QhhJhR1KQZiG4QCt9kayez";
+
+    /**
+     * callbackToken 是平台上配置的token
+     */
+    public static final String TOKEN = "XinLingZhaoXiangJiDouYin";
+
+    /**
+     * RequestSign 担保支付请求签名算法
+     * @param paramsMap {@code Map<String, Object>} 所有的请求参数
+     * @return:签名字符串
+     *
+     * RequestSign Guaranteed payment request signature algorithm
+     * @param paramsMap {@code Map<String, Object>} all request parameters
+     * @return: Signature string
+     */
+    public static String requestSign(Map<String, Object> paramsMap) {
+        List<String> paramsArr = new ArrayList<>();
+        for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
+            String key = entry.getKey();
+            if (REQUEST_NOT_NEED_SIGN_PARAMS.contains(key)) {
+                continue;
+            }
+            String value = entry.getValue().toString();
+
+            value = value.trim();
+            if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
+                value = value.substring(1, value.length() - 1);
+            }
+            value = value.trim();
+            if (value.equals("") || value.equals("null")) {
+                continue;
+            }
+            paramsArr.add(value);
+        }
+        paramsArr.add(SALT);
+        Collections.sort(paramsArr);
+        StringBuilder signStr = new StringBuilder();
+        String sep = "";
+        for (String s : paramsArr) {
+            signStr.append(sep).append(s);
+            sep = "&";
+        }
+        return md5FromStr(signStr.toString());
+    }
+
+    /**
+     * CallbackSign 担保支付回调签名算法
+     * @param params {@code List<String>} 所有字段(验证时注意不包含 sign 签名本身,不包含空字段与 type 常量字段)内容与平台上配置的 token
+     * @return:签名字符串
+     *
+     * CallbackSign Guaranteed payment callback signature algorithm
+     * @param params {@code List<String>} The content of all fields (note that the sign signature itself is not included during verification, and does not include empty fields and type constant fields) content and the token configured on the platform
+     * @return: signature string
+     */
+    public static String callbackSign(List<String> params) {
+        try {
+            String concat = params.stream().sorted().collect(Collectors.joining(""));
+            byte[] arrayByte = concat.getBytes(StandardCharsets.UTF_8);
+            MessageDigest mDigest = MessageDigest.getInstance("SHA1");
+            byte[] digestByte = mDigest.digest(arrayByte);
+
+            StringBuffer signBuilder = new StringBuffer();
+            for (byte b : digestByte) {
+                signBuilder.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
+            }
+            return signBuilder.toString();
+        } catch (Exception exp) {
+            return "";
+        }
+    }
+
+    /**
+     * md5FromStr md5算法对该字符串计算摘要
+     * @param inStr {@code String} 需要签名的字符串
+     * @return:签名字符串
+     *
+     * md5FromStr The md5 algorithm computes a digest of the string
+     * @param inStr {@code String} String to be signed
+     * @return: signature string
+     */
+    private static String md5FromStr(String inStr) {
+        MessageDigest md5;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return "";
+        }
+
+        byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8);
+        byte[] md5Bytes = md5.digest(byteArray);
+        StringBuilder hexValue = new StringBuilder();
+        for (byte md5Byte : md5Bytes) {
+            int val = ((int) md5Byte) & 0xff;
+            if (val < 16) {
+                hexValue.append("0");
+            }
+            hexValue.append(Integer.toHexString(val));
+        }
+        return hexValue.toString();
+    }
+}

+ 5 - 1
src/main/java/com/rf/psychological/enums/OrderStatus.java

@@ -40,7 +40,11 @@ public enum OrderStatus {
     /**
      * 退款异常
      */
-    REFUND_ABNORMAL("退款异常");
+    REFUND_ABNORMAL("退款异常"),
+
+    PROCESSING("处理中"),
+    TIMEOUT("超时未支付"),
+    FAIL("失败");
 
     /**
      * 类型

+ 22 - 9
src/main/java/com/rf/psychological/rest/DeviceController.java

@@ -12,6 +12,7 @@ import com.rf.psychological.security.DESede;
 import com.rf.psychological.utils.ExcelUtil;
 import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -63,15 +64,27 @@ public class DeviceController extends BaseController {
         File file = new File("C:\\Users\\Administrator\\Desktop\\标准情商测试.xlsx");
         try {
             List<List<List<Object>>> datas = ExcelUtil.getBankListByExcelSheet(new FileInputStream(file.getAbsolutePath()), file.getName());
-            List<ScaleMarksEntity> marksEntities = scaleMarksService.getScaleMarksByFlag("20210820143117");
-            List<AnswerEntity> answerEntities = answerService.getAnswerByFlag("20210820143117");
-            marksEntities.forEach(item ->{
-                log.info(item.toString());
-            });
-            answerEntities.forEach(item ->{
-                log.info(item.toString());
-            });
-            List<List<Object>> marksObj = datas.get(2);
+            List<ScaleEntity> scaleEntities = scaleService.getScaleByFlag("20210820143117");
+            List<List<Object>> an = datas.get(1);
+            for (ScaleEntity scaleEntity :scaleEntities){
+                log.info("------"+scaleEntity.getCheckItems());
+                String no = scaleEntity.getQuestionNo();
+                String item =null;
+                for (List<Object> objects :an){
+                    if (objects.get(0).equals(no)){
+                        if (StringUtils.isEmpty(item)){
+                            item = objects.get(1).toString();
+                        }else {
+                            item = item+";"+objects.get(1).toString();
+                        }
+                    }
+                }
+                scaleEntity.setCheckItems(item);
+                log.info("------"+scaleEntity.getCheckItems());
+                //scaleService.saveScale(scaleEntity);
+            }
+
+
 //            marksObj.forEach(item ->{
 //                ScaleMarksEntity entity = new ScaleMarksEntity();
 //                entity.setName("总分");

+ 2 - 2
src/main/java/com/rf/psychological/security/DESede.java

@@ -171,7 +171,7 @@ public class DESede {
 
     public static void main(String[] args) throws Exception {
         String name = "hahah";
-        List<String>  list = Arrays.asList(name.split(";"));
-        System.out.println(list);
+        System.out.println(decryptString("salBQk0H3j33EwObtXOHpcFqNTbECevLIzhweNpudteBDbN8JHb30EnLt6IPZn1hR9fD33n3rAovqwHw9P5JdQ0OywESJ8JOaA64JX/jup7P9j/2F8PssEVMh8QODyz3XGK0K0feQdfB/DSXTHdMPGxQUebcsvPu5sIp4i9XsEoLvc1z/sDvUDkqp5KLQ5IQ3owRyJPD3rXbrC7/2gRXonE98f5M9IwFiIgUjh5Xnjo="));
+        System.out.println(encryptString("我觉得我没有未来;几乎不对未来抱有希望;未来还是充满希望的;多数时间对未来还是充满希望;总是对未来还是充满希望"));
       }
 }

+ 4 - 0
src/main/java/com/rf/psychological/wxpay/utils/OrderNoUtils.java

@@ -33,6 +33,10 @@ public class OrderNoUtils {
         return "REFUND_" + getNo();
     }
 
+    public static String getDouYinOrderNo() {
+        return "ORDER_DOUYIN_" + getNo();
+    }
+
     /**
      * 获取编号
      * @return

BIN
src/main/resources/child.jue-ming.com.jks


+ 0 - 100
src/main/resources/config/application-dev.yml

@@ -1,100 +0,0 @@
-# 本地数据库
-server:
-  port: 8080
-  address: 0.0.0.0
-spring:
-  datasource:
-    type: com.alibaba.druid.pool.DruidDataSource
-    druid:
-      # 使用druid连接池
-      driver-class-name: com.mysql.cj.jdbc.Driver
-      url: jdbc:mysql://49.232.79.112:3306/psychological?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
-      username: root
-      password: Mysql@.2020
-      # 初始化连接大小
-      initial-size: 5
-      # 最小空闲连接数
-      min-idle: 5
-      max-active: 20
-      max-wait: 30000
-      # 可关闭的空闲连接间隔时间
-      time-between-eviction-runs-millis: 60000
-      # 配置连接在池中的最小生存时间
-      min-evictable-idle-time-millis: 300000
-      validation-query: select '1' from dual
-      test-while-idle: true
-      test-on-borrow: false
-      test-on-return: false
-      # 打开PSCache,并且指定每个连接上PSCache的大小
-      pool-prepared-statements: true
-      max-open-prepared-statements: 20
-      max-pool-prepared-statement-per-connection-size: 20
-      # 配置监控统计拦截的filters
-      filters: stat,wall
-      # 自己配置监控统计拦截的filter
-      filter:
-        # 开启druid datasource的状态监控
-        stat:
-          enabled: true
-          db-type: mysql
-          # 开启慢sql监控,超过2s 就认为是慢sql,记录到日志中
-          log-slow-sql: true
-          slow-sql-millis: 2000
-      ########## 配置StatViewServlet(监控页面),用于展示Druid的统计信息 ##########
-      stat-view-servlet:
-        url-pattern: /druid/*
-        reset-enable: false
-        login-username: testAdmin
-        login-password: asdcjiafh^&912834
-        enabled: true
-        allow:
-      ########## 配置WebStatFilter,用于采集web关联监控的数据 ##########
-      web-stat-filter:
-        url-pattern: /*
-        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
-        enabled: true
-        session-stat-enable: true
-  data:
-    redis:
-      repositories:
-        enabled: false
-  redis:
-    host: 49.232.26.44
-    port: 6379
-    password: bjjmtech&jsyx
-    timeout: 5000
-    jedis:
-      pool:
-        max-wait: -1
-        max-idle: 8
-        max-active: 8
-        min-idle: 0
-#微信支付
-wx.pay:
-  # 商户号
-  mch-id: 1627594233
-  #商户api证书序列号
-  mch-serial-no: 25BB4D9C58F3D9FFCBC0F882B57F7E842CBE5A23
-  # 商户私钥文件
-  private-key-path: apiclient_key.pem
-  # API秘钥
-  api-v3-key: MentalHealth20191025JuemingTest1
-  # APPID
-  app-id: wxfee6e2d1588e3f7f
-  # 微信服务器地址
-  domain: https://api.mch.weixin.qq.com
-  # 接受结果回调地址
-  #notify-domain: http://49.232.26.44:8090
-  # 小程序秘钥
-  ASPI_SECRET: b4edc4638f9182a1684dffdf7a1fa4c0
-  #小程序code2session
-  ASPI_URL: https://api.weixin.qq.com/sns/jscode2session
-  #小程序appid
-  ASPI_APPID: wx2f422a2a1cb24c3c
-  is_lan: true
-#swagger 显示隐藏配置
-swagger:
-  show: true
-
-
-

+ 0 - 56
src/main/resources/config/application-prod.yml

@@ -1,56 +0,0 @@
-#112正式版
-server:
-  port: 8848
-  address: 0.0.0.0
-  ssl:
-    key-store: classpath:org.jue-ming.com.jks
-    #key-store-password: zzr804oe997kw
-    key-store-password: u6f081g67l8
-    key-store-type: JKS
-  tomcat:
-    accept-count: 1000
-    max-connections: 10000
-    threads:
-      min-spare: 100
-      max: 1600
-
-spring:
-  datasource:
-    driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://49.232.79.112:3306/psychological_admin2?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
-
-    #url: jdbc:mysql://localhost:54027/psychological_admin?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
-    username: root
-    #112/44
-    password: Mysql@.2020
-    #username: root
-    #password: QazMysql@1921.Wsx
-    hikari:
-      max-lifetime: 30000
-
-  #redisson:
-    #address: redis://49.232.79.112:6379
-    #address: redis://49.232.26.44:6379
-    #password: bjjmtech&jsyx
-  data:
-    redis:
-      repositories:
-        enabled: false
-  redis:
-    host: 49.232.79.112
-    port: 6379
-    password: bjjmtech&jsyx
-    database: 0
-    timeout: 5000
-    jedis:
-      pool:
-        max-wait: -1
-        max-idle: 8
-        max-active: 8
-        min-idle: 0
-  # 小程序秘钥
-  ASPI_SECRET: b4edc4638f9182a1684dffdf7a1fa4c0
-  #小程序code2session
-  ASPI_URL: https://api.weixin.qq.com/sns/jscode2session
-  #小程序appid
-  ASPI_APPID: wx2f422a2a1cb24c3c

+ 18 - 4
src/main/resources/config/application-public.yml

@@ -3,10 +3,10 @@ server:
   port: 8445
   address: 0.0.0.0
 
-  ssl:
-    key-store: classpath:hnhong-duo.com.jks
-    key-store-password: pk4x5v3pz83va2
-    key-store-type: JKS
+#  ssl:
+#    key-store: classpath:hnhong-duo.com.jks
+#    key-store-password: pk4x5v3pz83va2
+#    key-store-type: JKS
 
 
 spring:
@@ -62,3 +62,17 @@ wx.pay:
   #小程序appid
   ASPI_APPID: wx2f422a2a1cb24c3c
 
+#抖音支付
+douyin:
+  appid: tt444a32f7db77627c01
+  appName: douyin
+  secret: d8a880ae1f5cf6e1588f4367e13f95c1d5b4be9b
+  sessionUrl: https://developer.toutiao.com/api/apps/v2/jscode2session
+  tokenUrl: https://developer.toutiao.com/api/apps/v2/token
+  createOrderUrl: https://developer.toutiao.com/api/apps/ecpay/v1/create_order
+  codeUrl: https://developer.toutiao.com/api/apps/qrcode
+  notifyUrl: https://hnhong-duo.com
+  queryOrderUrl: https://developer.toutiao.com/api/apps/ecpay/v1/query_order
+  pushOrderUrl: https://developer.toutiao.com/api/apps/order/v2/push
+  isDouYin: true
+

BIN
src/main/resources/org.jue-ming.com.jks


BIN
src/main/resources/server.jks


BIN
src/main/resources/test.jue-ming.com.jks