jiangqs
2023-07-18 79f8fc87c9c9e4866a477dfe4485eedda5976209
bug和企业微信同步
5个文件已添加
22个文件已修改
968 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/constant/SecurityConstant.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/resources/bootstrap.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-gateway/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-file/pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/activity/ActivityServiceImpl.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/GoodsMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/util/HttpUtils.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MgtEditShopDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MgtShopAuthDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/pojo/shop/ShopAuthentication.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/MgtShopInfoVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopServiceImpl.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/WxShopUtils.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/ContactInfo.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/IdCardInfo.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/SalesSceneInfo.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/SubmitInfo.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/UboInfo.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/scheduler/SchedulerUtils.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/scheduler/SystemScheduler.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/staff/SysStaffServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/staff/SysStaffService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/HttpUtils.java 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/QiYeUtils.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/constant/SecurityConstant.java
@@ -56,4 +56,9 @@
     */
    String PAY_MONEY_INTEGRAL = "PAY_MONEY_INTEGRAL";
    /**
     * 用户验证码前缀key
     */
    String QY_TOKEN = "QY_TOKEN";
}
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java
@@ -37,8 +37,11 @@
    @Autowired
    private TokenService tokenService;
    @Value("${h5.redirectUriBase}")
    private String redirectUriBase;
    @Value("${h5.redirectMerchantUriBase}")
    private String redirectMerchantUriBase;
    @Value("${h5.redirectEmployeeUriBase}")
    private String redirectEmployeeUriBase;
    /**
@@ -51,7 +54,17 @@
    @ApiOperation("构造网页授权链接")
    public R<OauthUrlVo> oauthUrl(@ApiParam(value = "授权重定向地址", required = true) @RequestParam("redirectUri") String redirectUri) throws UnsupportedEncodingException {
        // 普通应用
        redirectUri = redirectUriBase + redirectUri;
        redirectUri = redirectMerchantUriBase + redirectUri;
        String oauthRedirectUrl =  URLEncoder.encode(redirectUri,"utf-8");
        String oauthUrl = qywxInnerService.getOauthUrl(oauthRedirectUrl);
        return R.ok(new OauthUrlVo(oauthUrl));
    }
    @GetMapping({"/h5/oauthStaffUrl"})
    @ApiOperation("构造网页授权链接")
    public R<OauthUrlVo> oauthStaffUrl(@ApiParam(value = "授权重定向地址", required = true) @RequestParam("redirectUri") String redirectUri) throws UnsupportedEncodingException {
        // 普通应用
        redirectUri = redirectEmployeeUriBase + redirectUri;
        String oauthRedirectUrl =  URLEncoder.encode(redirectUri,"utf-8");
        String oauthUrl = qywxInnerService.getOauthUrl(oauthRedirectUrl);
        return R.ok(new OauthUrlVo(oauthUrl));
ruoyi-auth/src/main/resources/bootstrap.yml
@@ -34,3 +34,5 @@
  suiteSecret: ""
  token: ""
  encodingAESKey: ""
ruoyi-gateway/src/main/resources/bootstrap.yml
@@ -13,7 +13,7 @@
  cloud:
    nacos:
      discovery:
        # 服务注册地址cd ../a
        # 服务注册地址
        #server-addr: 47.109.78.184:5000
        server-addr: 127.0.0.1:8848
      config:
ruoyi-modules/ruoyi-file/pom.xml
@@ -73,6 +73,13 @@
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.15.1</version>
        </dependency>
        <!-- 微信图片上传 -->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.4.9</version>
        </dependency>
        
    </dependencies>
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java
@@ -5,6 +5,19 @@
import com.ruoyi.file.service.ISysFileService;
import com.ruoyi.file.utils.OBSUploadUtils;
import com.ruoyi.system.api.domain.poji.sys.SysFile;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.WechatPayUploadHttpPost;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +26,10 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URI;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;
@@ -25,6 +42,15 @@
public class SysFileController
{
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
    private final static String PRIVATE_KEY = "";
    private final static String MCH_ID = "";
    private final static String MCH_SERIAL_NO = "";
    private final static String API_V3_KEY = "";
    @Autowired
    private ISysFileService sysFileService;
@@ -85,4 +111,51 @@
        }
        return R.ok(urls);
    }
    /**
     * @description  创建httpClient
     * @author  jqs
     * @date    2023/6/19 12:50
     * @param
     * @return  CloseableHttpClient
     */
    private CloseableHttpClient createHttpClient() throws Exception {
        String privateKey = PRIVATE_KEY;
        String mchId = MCH_ID;
        String mchSerialNo = MCH_SERIAL_NO;
        String apiV3Key = API_V3_KEY;
        // 加载商户私钥(privateKey:私钥字符串)
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
        // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
        // 初始化httpClient
        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier)).build();
        return httpClient;
    }
    @PostMapping("uploadWXFile")
    public R<String> uploadWXFile(@RequestPart("file")MultipartFile file) throws Exception {
        URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload");
        CloseableHttpClient httpClient = createHttpClient();
        InputStream inputStream = file.getInputStream();
        String sha256 = DigestUtils.sha256Hex(inputStream);
        HttpPost request = new WechatPayUploadHttpPost.Builder(uri)
                .withImage(file.getName(), sha256, inputStream)
                .build();
        CloseableHttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        String s = EntityUtils.toString(entity);
        System.out.println(s);
        return R.ok(s);
    }
}
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/activity/ActivityServiceImpl.java
@@ -179,8 +179,8 @@
        if(checkTime.compareTo(activityStartTime)>0){
            String activityId = activity.getActivityId();
            long currentTimeMillis = System.currentTimeMillis();
            long startTimeDifference = currentTimeMillis - activityStartTime.getTime();
            long endTimeDifference = currentTimeMillis - activityEndTime.getTime();
            long startTimeDifference = activityStartTime.getTime() - currentTimeMillis;
            long endTimeDifference = activityEndTime.getTime() - currentTimeMillis;
            // 查询延时任务
            DelayTask startDelayTask = remoteConfigService.getDelayTask(DelayTaskEnum.ACTIVITY_START_TASK.getCode() + "-" + activityId).getData();
            // 如果延时任务为空,创建延时任务控制活动定时开始和结束
@@ -194,7 +194,7 @@
                remoteConfigService.addDelayTask(startDelayTask);
            }
            // 查询延时任务
            DelayTask endDelayTask = remoteConfigService.getDelayTask(DelayTaskEnum.ACTIVITY_START_TASK.getCode() + "-" + activityId).getData();
            DelayTask endDelayTask = remoteConfigService.getDelayTask(DelayTaskEnum.ACTIVITY_END_TASK.getCode() + "-" + activityId).getData();
            // 如果延时任务为空,创建延时任务控制活动定时开始和结束
            if (endDelayTask == null) {
                redisService.setCacheObject(DelayTaskEnum.ACTIVITY_END_TASK.getCode() + "-" + activityId, activityEndTime, endTimeDifference, TimeUnit.MILLISECONDS);
@@ -427,8 +427,8 @@
                Date activityStartTime = activity.getActivityStartTime();
                Date activityEndTime = activity.getActivityEndTime();
                long currentTimeMillis = System.currentTimeMillis();
                long startTimeDifference = currentTimeMillis - activityStartTime.getTime();
                long endTimeDifference = currentTimeMillis - activityEndTime.getTime();
                long startTimeDifference = activityStartTime.getTime() - currentTimeMillis;
                long endTimeDifference = activityEndTime.getTime() - currentTimeMillis;
                // 查询延时任务
                DelayTask startDelayTask = remoteConfigService.getDelayTask(DelayTaskEnum.ACTIVITY_START_TASK.getCode() + "-" + activityId).getData();
                // 如果延时任务为空,创建延时任务控制活动定时开始和结束
ruoyi-modules/ruoyi-goods/src/main/resources/mapper/goods/GoodsMapper.xml
@@ -189,7 +189,7 @@
        INNER JOIN t_goods tg ON tag.goods_id = tg.goods_id
        LEFT JOIN t_goods_file tgf ON tg.goods_id = tgf.goods_id AND tgf.del_flag = 0 AND tgf.file_type = 1
        LEFT JOIN t_shop_goods tsg ON tg.goods_id = tsg.goods_id AND tsg.shop_id = #{shopId}
        WHERE tag.activity_id = #{activityId} AND tg.del_flag = 0 AND tg.goods_status = 1
        WHERE tag.del_flag = 0 AND tag.activity_id = #{activityId} AND tg.del_flag = 0 AND tg.goods_status = 1
        ORDER BY tag.sales_number DESC, tg.create_time DESC LIMIT 6
    </select>
ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/util/HttpUtils.java
@@ -22,7 +22,6 @@
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
@@ -41,8 +40,6 @@
public class HttpUtils {
    public static void main(String[] args) {
        BigDecimal payMoney = BigDecimal.valueOf(0.73);
        System.out.println(BigDecimal.ZERO.compareTo(payMoney));
    }
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -267,6 +267,9 @@
        FROM t_order toc
        INNER JOIN t_order_goods tog ON tog.order_id = toc.order_id
        WHERE toc.del_flag = 0
        <if test="param.userId != null">
            AND toc.user_id = #{param.userId}
        </if>
        <if test="param.orderStatus != null">
            AND toc.order_status = #{param.orderStatus}
        </if>
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MgtEditShopDto.java
@@ -45,6 +45,12 @@
    @ApiModelProperty(value="店主联系方式")
    private String shopownerPhone;
    @ApiModelProperty(value="签约省区域")
    private String signProvinceCode;
    @ApiModelProperty(value="签约市区域")
    private String signCityCode;
    @ApiModelProperty(value="签约区域")
    private String signAreaCode;
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/dto/MgtShopAuthDto.java
@@ -99,6 +99,12 @@
     */
    @ApiModelProperty(value = "法人身份证背面")
    private String lpIcBack;
    @ApiModelProperty(value = "法人手机号")
    private String lpMobilePhone;
    @ApiModelProperty(value = "法人邮箱")
    private String lpContactEmail;
    /**
     * 结算账户类型1对公2对私
     */
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/pojo/shop/ShopAuthentication.java
@@ -126,6 +126,14 @@
     */
    @TableField("lp_ic_back")
    private String lpIcBack;
    @TableField("lp_mobile_phone")
    private String lpMobilePhone;
    @TableField("lp_contact_email")
    private String lpContactEmail;
    /**
     * 结算账户类型1对公2对私
     */
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/domain/vo/MgtShopInfoVo.java
@@ -40,6 +40,12 @@
    @ApiModelProperty(value="店主联系方式")
    private String shopownerPhone;
    @ApiModelProperty(value="签约省区域")
    private String signProvinceCode;
    @ApiModelProperty(value="签约市区域")
    private String signCityCode;
    @ApiModelProperty(value="签约区域")
    private String signAreaCode;
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/service/impl/shop/ShopServiceImpl.java
@@ -19,6 +19,8 @@
import com.ruoyi.shop.service.task.MemberTaskService;
import com.ruoyi.shop.service.task.ShopFileService;
import com.ruoyi.shop.service.task.ShopTaskService;
import com.ruoyi.shop.util.WxShopUtils;
import com.ruoyi.shop.util.dto.*;
import com.ruoyi.system.api.constant.AppErrorConstant;
import com.ruoyi.system.api.domain.dto.*;
import com.ruoyi.system.api.domain.poji.config.SysTag;
@@ -918,9 +920,91 @@
    @Override
    public void mgtShopAuth(MgtShopAuthDto mgtShopAuthDto){
        ShopAuthentication shopAuthentication = shopAuthenticationService.getById(mgtShopAuthDto.getAuthId());
        Shop shop = this.getByShopId(shopAuthentication.getShopId());
        String applyNumber = IdUtils.simpleUUID();
        BeanUtils.copyProperties(mgtShopAuthDto , shopAuthentication);
        shopAuthentication.setApplyNumber(applyNumber);
        shopAuthentication.setAuditStatus(3);
        shopAuthenticationService.saveOrUpdate(shopAuthentication);
        //生成提交类
        SubmitInfo submitInfo = new SubmitInfo();
        submitInfo.setOut_request_no(applyNumber);
        if(shopAuthentication.getMainType()==2){
            submitInfo.setOrganization_type("2");
        }else{
            submitInfo.setOrganization_type("4");
        }
        //营业执照
        BusinessLicenseInfo business_license_info = new BusinessLicenseInfo();
        business_license_info.setBusiness_license_copy(shopAuthentication.getBlImage());
        business_license_info.setBusiness_license_number(shopAuthentication.getBlNumber());
        business_license_info.setMerchant_name(shopAuthentication.getBlShopName());
        business_license_info.setLegal_person(shopAuthentication.getBlCorporateName());
        business_license_info.setCompany_address(shopAuthentication.getBlRegisteredAddress());
        business_license_info.setBusiness_time(shopAuthentication.getBlBusinessDeanline());
        submitInfo.setBusiness_license_info(business_license_info);
        //法人证件
        submitInfo.setId_doc_type("IDENTIFICATION_TYPE_MAINLAND_IDCARD");
        IdCardInfo id_card_info = new IdCardInfo();
        id_card_info.setId_card_copy(shopAuthentication.getLpIcFront());
        id_card_info.setId_card_national(shopAuthentication.getLpIcBack());
        id_card_info.setId_card_name(shopAuthentication.getLpCorporateName());
        id_card_info.setId_card_number(shopAuthentication.getLpIdCard());
        id_card_info.setId_card_valid_time_begin(shopAuthentication.getLpIcStartDate());
        id_card_info.setId_card_valid_time(shopAuthentication.getLpIcEndDate());
        submitInfo.setId_card_info(id_card_info);
        //企业填写
        if(shopAuthentication.getMainType()==2){
            submitInfo.setOwner(true);
            List<UboInfo> ubo_info_list = new ArrayList<>();
            UboInfo uboInfo = new UboInfo();
            uboInfo.setUbo_id_doc_type("IDENTIFICATION_TYPE_MAINLAND_IDCARD");
            uboInfo.setUbo_id_doc_copy(shopAuthentication.getUboIcFront());
            uboInfo.setUbo_id_doc_copy_back(shopAuthentication.getUboIcBack());
            uboInfo.setUbo_id_doc_name(shopAuthentication.getUboName());
            uboInfo.setUbo_id_doc_number(shopAuthentication.getUboIdCard());
            uboInfo.setUbo_id_doc_address(shopAuthentication.getUboIcAddress());
            uboInfo.setUbo_id_doc_period_begin(shopAuthentication.getUboIcStartDate());
            uboInfo.setUbo_id_doc_period_end(shopAuthentication.getUboIcEndDate());
            ubo_info_list.add(uboInfo);
            submitInfo.setUbo_info_list(ubo_info_list);
        }
        //结算账户信息
        AccountInfo accountInfo = new AccountInfo();
        if(shopAuthentication.getSettlementAccountType().equals("1")){
            accountInfo.setBank_account_type("74");
        }else{
            accountInfo.setBank_account_type("75");
        }
        accountInfo.setAccount_bank(shopAuthentication.getSaBank());
        accountInfo.setAccount_name(shopAuthentication.getSaAccountName());
        accountInfo.setBank_address_code(shopAuthentication.getSaBankCityCode());
        accountInfo.setBank_name(shopAuthentication.getSaBankName());
        accountInfo.setAccount_number(shopAuthentication.getSaNumber());
        submitInfo.setAccount_info(accountInfo);
        ContactInfo contactInfo = new ContactInfo();
        contactInfo.setContact_type("65");
        contactInfo.setContact_name(shopAuthentication.getLpCorporateName());
        contactInfo.setContact_id_card_number(shopAuthentication.getLpIdCard());
        contactInfo.setMobile_phone(shopAuthentication.getLpMobilePhone());
        contactInfo.setContact_email(shopAuthentication.getLpContactEmail());
        submitInfo.setContact_info(contactInfo);
        //店铺信息
        SalesSceneInfo salesSceneInfo = new SalesSceneInfo();
        salesSceneInfo.setStore_name(shop.getShopName());
        salesSceneInfo.setStore_url("");
        salesSceneInfo.setStore_qr_code("");
        submitInfo.setSales_scene_info(salesSceneInfo);
        submitInfo.setMerchant_shortname(shop.getShopName());
        submitInfo.setBusiness_addition_pics(shopAuthentication.getBaPics());
        submitInfo.setBusiness_addition_desc(shopAuthentication.getBaDesc());
        //提交审核
        try {
            WxShopUtils.ApplymentSubMch(submitInfo);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/WxShopUtils.java
@@ -6,12 +6,15 @@
import com.ruoyi.shop.util.dto.IdCardInfo;
import com.ruoyi.shop.util.dto.SubmitInfo;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.*;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -19,7 +22,6 @@
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
@@ -40,84 +42,57 @@
public class WxShopUtils {
    public void ApplymentSubMch() throws Exception {
    private final static String PRIVATE_KEY = "";
    private final static String MCH_ID = "";
    private final static String MCH_SERIAL_NO = "";
    private final static String API_V3_KEY = "";
    /**
     * @description  创建httpClient
     * @author  jqs
     * @date    2023/6/19 12:50
     * @param
     * @return  CloseableHttpClient
     */
    private static CloseableHttpClient createHttpClient() throws NotFoundException, IOException, GeneralSecurityException, HttpCodeException {
        String privateKey = PRIVATE_KEY;
        String mchId = MCH_ID;
        String mchSerialNo = MCH_SERIAL_NO;
        String apiV3Key = API_V3_KEY;
        // 加载商户私钥(privateKey:私钥字符串)
        PrivateKey merchantPrivateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
        // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
        // 初始化httpClient
        CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier)).build();
        return httpClient;
    }
    public static void ApplymentSubMch(SubmitInfo submitInfo) throws Exception {
        // 初始化httpClient
        CloseableHttpClient httpClient = createHttpClient();
        //请求URL
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/");
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/ecommerce/applyments/");
        // 请求body参数
        String reqdata = "{"
                + "\"business_info\": {"
                + "\"merchant_shortname\":\"上海XXX有限公司\","
                + "\"service_phone\":\"139XXXX\","
                + "\"sales_info\": {"
                + "\"mini_program_info\": {"
                + "\"mini_program_pics\": ["
                + "\"0\":\"F8O5MNAOlYZyxZcLnWXkyk72coZ3CVX3XobPZng-xepKPTrcH_XMfrGGYLi1XFogMG9P25LSUX6gjXU5iPI74YqiRUDfORyw2d76wK3vzuQ\""
                + "],"
                + "\"mini_program_sub_appid\":\"wx76c3f74c108876c2\""
                + "},"
                + "\"mp_info\": {"
                + "\"mp_pics\": ["
                + "\"0\":\"F8O5MNAOlYZyxZcLnWXkys5TBxf0dyfesnyfNuquBMArHRfgCq8hDRdscDpblCcEgvgV5MkVch9IBEX7aatZCmI8k5Wdb_M8a4bYcmlg6V8\""
                + "],"
                + "\"mp_sub_appid\":\"wx85c88c63bd22651f\""
                + "},"
                + "\"sales_scenes_type\": ["
                + "\"0\":\"SALES_SCENES_MP\","
                + "\"1\":\"SALES_SCENES_MINI_PROGRAM\""
                + "]"
                + "}"
                + "},"
                + "\"subject_info\": {"
                + "\"business_license_info\": {"
                + "\"legal_person\":\"江XX\","
                + "\"license_copy\":\"F8O5MNAOlYZyxZcLnWXkysZ5xo8fE3SHJ1pHUe6OJKmNIWtqUVyv4aY2-JLTgjDOSovWaKkBu3AbkjGuQXhesDzREu2pT_Yf_hxlFKPJMwQ\","
                + "\"merchant_name\":\"上海XXX有限公司\","
                + "\"license_number\":\"91310118MA1JXXXX\""
                + "},"
                + "\"subject_type\":\"SUBJECT_TYPE_ENTERPRISE\","
                + "\"identity_info\": {"
                + "\"owner\":true,"
                + "\"id_doc_type\":\"IDENTIFICATION_TYPE_IDCARD\","
                + "\"id_card_info\": {"
                + "\"id_card_copy\":\"F8O5MNAOlYZyxZcLnWXkyvLpqoz7MNRULxju0NqUCtLGBl_vm8Bhj9uAyuLyDART9UsA10spF9gbT3DEoM85HxPQOhMuilK0zLtOxAjPx58\","
                + "\"card_period_end\":\"2035-12-28\","
                + "\"card_period_begin\":\"2015-12-28\","
                + "\"id_card_name\":\"JRMJGA7B7oSVS+krFeaQn4AvYZE2LL9tTwA+XXa9lYJU4AhS+Qheb7fhgo+D+hfa0v+ykU1BVvVo7NpCfgOYQqmYDyYF27Q/p4hB7IoqZLhJUE+hTG45VNoa9ASaKG79Hg+eGz4YTIHFGMFm1ljyg4fd5lGJixCqn38/gCfwm5x6vDOMVkFpqbUdR7klQwReGoG7iSlEpr4gZPqzItcBHiuXidMToKZTX1Lol1Lx52DHk0blcdh1CMRhv+wxQzF0lJMy/WtVyjKuB8daDbLJKTEwDx5KfkTZGHmGiaJnWY0qFX03sXsufvfB0Wj6Z37+nJnV16fplPmdr1/KEHamLw==\","
                + "\"id_card_national\":\"F8O5MNAOlYZyxZcLnWXkyvcmQrkBXCIo2vZGUoM6ER-skL5k6IOhzeJ34tNNUggQIPfJbM_pzdg9jM4pQbkIm84_bKfi2JKNn99xIurNgwI\","
                + "\"id_card_number\":\"V0quwnIu/PLbdQQ3/nzMqjvHtChDqed4Jpc3Iy2lgnFoWVNXguRWBHMYKHaLgLvnxLvO6TciMnrSw13QzUJD4ZnEIiks8gGTd+OCzl5Jl3F+sneQ+Js4akBnCSBQso/SERvi6vUqCeRhX1vtiFsmKtqlL8r/ssrFev4FoJEka5gGME1osTgcpMMTIR8rolIO1oXbl3e8z5RDics5xKH2Ogjzis73yq9M18ap0uRRdLWoX/cxeG3tbU1bi5jZsAU9hGHXs4BKTaHfrslsKIkqXR0f2Jpk7H5qtwAyP8glcALN7gB5DIOmBEIZ5zx2PrDm38CsZHstu0hF8beXV/PG2w==\""
                + "}"
                + "}"
                + "},"
                + "\"business_code\":\"20201126100507000003\","
                + "\"contact_info\": {"
                + "\"contact_name\":\"AD2jwe8eYFYfeoSmBpyRYUawyQgQkUoAajOlHnQM/JzproDF7hikLDouMr5Mb1W5otvdJZYEipG0HzwLpG9NXbqP6SXSpzQFb8fY5cpuXZsIbDy70lAybF0bbxJiJw1PHSd7KpMbu0XHqwlicePLUOw7HCNV6euQsKEvtusiWsaVrNNdKXpj3ONhyAg2ws4ibc56GUVoNll3osmGLPi6/bIn3pD6sjNThgPE9UzRQax0XPwgIpafIewQiVy0GNtv5P33wqPa9pAsdEmaLXNtQr2Ddjw5SYMInen1qbVO8NP0VhuWmYiAjd1WbkNnR+gbwsilBCYYeRuFbKfqatASnA==\","
                + "\"mobile_phone\":\"GLc5+TuqJbxLeQO+CrKeDWF+7lZq9IsidIU4zcMpus4qsE8r1qNyvVMjrZfWLrjOItiQhXqkiKZs0B4M0UWAviWwmBhNWW0BJrauBjZbGZU+pLHC/2eOetdDC4sQqHN7Xw0N4tizqeQNu49n+DbSiv0TL09EcmNUUV9rImfjpVyo77MxKhPvdg3ODwS+IVvY2Tc9q11iBgaPIQ+XwoBaJGth1wdw0GLgEFUmX02TWxjHxq7f5O1RU3LjBlt1O+56ZZYpA+zr+IjQ/TwrIDp+4nk9v1oW2wtHuwrdqKrlLyJ1/zdoqwSddLuGxp8PwSM8CKobQP8TXhJu0S9pwLbNyg==\","
                + "\"contact_id_number\":\"iC35X6SaOx4A4BEJ4fmM2oOkYRO5rEzRh2QRdrxFD3+HwmNjxddsm1LoqfhSiV34DAO2x3Ded3q2c1LJ7NHqa3/IGCDss4FKlgIyiu5AmzQTTYwsobmvVFxeSUXA4PnH/tUTfatJOuj+9Emt7fmnpO9uWeCLIn5CXaaABrXpO4mUu8qPBaoF2jTfbwBm6QiYX58kATyRrIvBRs6VorHJydXkz3P1hCejh8sAYoJXlNHnoajI+NEwiWX9RhwUadYLbMwww68cc7Yzehp3s6an0NWuC76Y4e7FQ/i5D9ZpUvLKUoYfFsZMnHrv/PhLxmv5l8gQs9/IkmOdYfRujKZJwQ==\","
                + "\"contact_email\":\"ggK2ABtJ8bBiBo1iM7I6R2yEvhD6WC96d07gthnPGajc4lBCKpIqXjyNX8B97vc0OilyLRNUcySbT/KUejPyu4x9W6Ok6iS4zcerfKfIQkKs+3JXIMo0bu+GyI5O0fzRrPg1Mek2okfIjVK9wiTNJTzoGyz9twMXEaqqrOTbysyhnkqfrol5dad/TPg8qNWaBO3+Ma/hr1Tr0xeHWkKX3mBySC3NW49HM51x0PvFAwnStHr/8hiGzGpqAA3yJuYdlEwey3Lv+/bMmbTq+AyrYq9xX3q+n0VHuiSnzgICPwQiP4zXsoivA0bm7DSgcP1Oa6MjpGqMOS7AU1dHyak2GQ==\""
                + "},"
                + "\"bank_account_info\": {"
                + "\"account_number\":\"Bfu6CzrRWlVTLZwjEK2CCXG0KRfGoIsbYs9IYmtFcV9FTEVLCcVCRGW6DVE2hMMr7U9tSdo7QqsptXZ7Zhciandyx9kRkY/VmPywurySvCbqpOLbx3AgmQY7H6/Ye542R0uloi6Pdp5FjqY/TdnlDcTS4cqv9iqU0DqKAUt7q+L6jZ8lrSlGFPI/1RkXCGAhlTSZ/iAJYDWzcN/E0cno9BQPYCmEIWldzj7W3Tmhi1eaZYX5mlLWnTOuVmMsRXIehb4y6LCi6T0kS7/c3GOFwlTzHVaaUgFqZhOL00h2G4Cl94uZfuVNO7KTiFaWtV61muEN6JfaSnFwRDSHxhtsRg==\","
                + "\"bank_address_code\":\"310101\","
                + "\"account_name\":\"RVBRWZKlmzrjkDmz4uEkaLQLU5q5xErXGoWhzDNdnQjRlfn1NVHL2EtIE+B0BULFNOHrX61q13lcgo9CDal9YJ/LjZkzAAsivwJZpNSRZbAsNNjqbYiiVhdnxYpwMqtukVgZAFgx0XMovOeSGX1+Dosc2vKJSsxtUw6wJXcZbMjvsX5/xamFTvRIx1J2a/q3ODBJ9URO5O2FDhGwLx8LQnFIv7xUDM3JXw7c6+eNy1OYTVwlj3/MIDQVw2eiPjpG1vC6K6PRwCI4wFZk1QwH99Xa3Wwvf+ek54j7FQTh0N703dK6jjonL5L6Lh9ZsckLx45InkARlPnU0KQpoK5g9w==\","
                + "\"bank_account_type\":\"BANK_ACCOUNT_TYPE_CORPORATE\","
                + "\"account_bank\":\"招商银行\""
                + "},"
                + "\"settlement_info\": {"
                + "\"settlement_id\":\"716\","
                + "\"qualification_type\":\"零售批发/生活娱乐/网上商城/其他\""
                + "}"
                + "}";
        String reqdata = convertToStr(submitInfo);
        StringEntity entity = new StringEntity(reqdata,"utf-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Wechatpay-Serial", "XXXXXXXXXXXXXX");
        //完成签名并执行请求
        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) { //处理成功
@@ -129,48 +104,36 @@
                throw new IOException("request failed");
            }
        } finally {
            httpClient.close();
            response.close();
        }
        httpClient.close();
    }
    /**
     * @description  创建httpClient
     * @author  jqs
     * @date    2023/6/19 12:50
     * @param
     * @return  CloseableHttpClient
     */
    private CloseableHttpClient createHttpClient() throws NotFoundException, IOException, GeneralSecurityException, HttpCodeException {
        String merchantId = "";
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new FileInputStream("/path/to/apiclient_key.pem"));
        String merchantSerialNumber = "";
        String apiV3Key = "";
    public static void QueryApplyments(String applymentId) throws Exception{
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(merchantId, new WechatPay2Credentials(merchantId,
                new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));
        // ... 若有多个商户号,可继续调用putMerchant添加商户信息
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(merchantId);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));
        CloseableHttpClient httpClient = builder.build();
        return httpClient;
        // 初始化httpClient
        CloseableHttpClient httpClient = createHttpClient();
        //请求URL
        HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/ecommerce/applyments/out-request-no/"+applymentId);
        httpGet.setHeader("Accept", "application/json");
        //完成签名并执行请求
        CloseableHttpResponse response = httpClient.execute(httpGet);
        try {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) { //处理成功
                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
            } else if (statusCode == 204) { //处理成功,无返回Body
                System.out.println("success");
            } else {
                System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
                throw new IOException("request failed");
            }
        } finally {
            httpClient.close();
            response.close();
        }
    }
    //提交申请
    /*public static String apply(SubmitInfo submitInfo) throws Exception {
        String bodyStr=convertToStr(submitInfo);
        HttpResponse response = HttpUtils.v3HttpExecute("POST",EcommerceUrl.APPLYMENTS,
                "自己系统的应用名称","服务商商户号","商户API证书序列号","平台证书序列号",requestParam,"商户API证书位置.pem",null);
    }*/
    //加密申请信息
@@ -178,6 +141,7 @@
        rsaEncryptSubmitInfo(submitInfo);
        return JSONObject.toJSONString(submitInfo);
    }
    private static void rsaEncryptSubmitInfo(SubmitInfo submitInfo) throws Exception {
        IdCardInfo idCardInfo=submitInfo.getId_card_info();
@@ -197,7 +161,7 @@
    }
    private static String rsaEncryptByCert(String content) throws Exception {
        String platPrivateKey = "";
        String platPrivateKey = PRIVATE_KEY;
        InputStream inStream=new ByteArrayInputStream(platPrivateKey.getBytes(StandardCharsets.UTF_8));
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate)cf.generateCertificate(inStream);
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/ContactInfo.java
@@ -23,9 +23,8 @@
    /**超级管理员姓名*/
    private String contact_name;
    /**超级管理员身份证件号码*/
    private String contact_id_doc_type;
    private String contact_id_card_number;
    /**超级管理员手机*/
    private String mobile_phone;
    /**超级管理员邮箱*/
    private String contact_email;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/IdCardInfo.java
@@ -27,5 +27,6 @@
    /**身份证号码*/
    private String id_card_number;
    /**身份证有效期限*/
    private String id_card_valid_time_begin;
    private String id_card_valid_time;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/SalesSceneInfo.java
@@ -24,6 +24,5 @@
    private String store_url;
    /**店铺二维码*/
    private String store_qr_code;
    /**小程序AppID*/
    private String mini_program_sub_appid;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/SubmitInfo.java
@@ -11,6 +11,7 @@
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 进件信息
@@ -32,6 +33,8 @@
    private IdCardInfo id_card_info;
    /**经营者/法人其他类型证件信息*/
    private IdDocInfo id_doc_info;
    /**经营者/法人是否为受益人*/
    private Boolean owner;
    /**是否填写结算银行账户*/
    private Boolean need_account_info;
    /**结算银行账户*/
@@ -48,4 +51,6 @@
    private String business_addition_pics;
    /**补充说明*/
    private String business_addition_desc;
    private List<UboInfo> ubo_info_list;
}
ruoyi-modules/ruoyi-shop/src/main/java/com/ruoyi/shop/util/dto/UboInfo.java
New file
@@ -0,0 +1,33 @@
package com.ruoyi.shop.util.dto;
import lombok.Data;
import java.io.Serializable;
/**
 * @ClassName UboInfo
 * @Description TODO
 * @Author jqs
 * @Date 2023/7/18 15:57
 * @Version 1.0
 */
@Data
public class UboInfo implements Serializable {
    private static final long serialVersionUID=1L;
    private String ubo_id_doc_type;
    private String ubo_id_doc_copy;
    private String ubo_id_doc_copy_back;
    private String ubo_id_doc_name;
    private String ubo_id_doc_number;
    private String ubo_id_doc_address;
    private String ubo_id_doc_period_begin;
    private String ubo_id_doc_period_end;
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/scheduler/SchedulerUtils.java
New file
@@ -0,0 +1,48 @@
package com.ruoyi.system.scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
@Component
public class SchedulerUtils {
    @Autowired
    private StringRedisTemplate redisTemplate;
    public boolean getSchedulerRun() {
        String localIpAddress = getLocalIpAddress();
        return true;
    }
    public static String getLocalIpAddress() {
        String localIpAddress = "";
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip = null;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    continue;
                } else {
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip != null && ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return localIpAddress;
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/scheduler/SystemScheduler.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.system.scheduler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class SystemScheduler {
    @Autowired
    private SchedulerUtils schedulerUtils;
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/staff/SysStaffServiceImpl.java
@@ -1,13 +1,16 @@
package com.ruoyi.system.service.impl.staff;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.IdUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.constant.AppErrorConstant;
import com.ruoyi.system.api.constant.SecurityConstant;
import com.ruoyi.system.api.domain.dto.MgtBaseGetDto;
import com.ruoyi.system.api.domain.poji.sys.SysUser;
import com.ruoyi.system.domain.dto.MgtStaffEditDto;
@@ -18,10 +21,12 @@
import com.ruoyi.system.mapper.staff.SysStaffMapper;
import com.ruoyi.system.service.staff.SysStaffService;
import com.ruoyi.system.service.sys.ISysUserService;
import com.ruoyi.system.util.QiYeUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * <p>
@@ -39,6 +44,10 @@
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private RedisService redisService;
    /**
     * @description  获取部门员工列表
@@ -195,4 +204,50 @@
        queryWrapper.eq(SysStaff::getStaffMobile,mobile);
        return this.getOne(queryWrapper,false);
    }
    /**
     * @description  同步组织架构
     * @author  jqs
     * @date    2023/7/18 19:06
     * @param
     * @return  void
     */
    @Override
    public void synchronizeOrganizationalStructure(){
        String accessToken = getQYToken();
    }
    /**
     * @description  获取企业微信token
     * @author  jqs
     * @date    2023/7/18 19:35
     * @param
     * @return  String
     */
    private String getQYToken(){
        String accessToken = redisService.getCacheObject(SecurityConstant.QY_TOKEN);
        if(StringUtils.isBlank(accessToken)){
            try {
                accessToken = QiYeUtils.getAccessTokenByQY();
                JSONObject jsonAccessToken = JSONObject.parseObject(accessToken);
                String errcode = jsonAccessToken.getString("errcode");
                String errmsg = jsonAccessToken.getString("errmsg");
                if(errcode.equals("0")){
                    accessToken = jsonAccessToken.getString("access_token");
                    Long expiresIn = jsonAccessToken.getLong("expires_in");
                    expiresIn = expiresIn -100;
                    redisService.setCacheObject(SecurityConstant.QY_TOKEN,accessToken,expiresIn, TimeUnit.SECONDS);
                }else{
                    throw new ServiceException(errmsg);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return accessToken;
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/staff/SysStaffService.java
@@ -84,4 +84,14 @@
     * @return  SysStaff
     */
    SysStaff getByMobile(String mobile);
    /**
     * @description  同步组织架构
     * @author  jqs
     * @date    2023/7/18 19:06
     * @param
     * @return  void
     */
    void synchronizeOrganizationalStructure();
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/HttpUtils.java
New file
@@ -0,0 +1,337 @@
package com.ruoyi.system.util;
import com.ruoyi.common.core.utils.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @ClassName HttpUtils
 * @Description TODO
 * @Author zhanglin
 * @Date 2020/2/11 10:30
 * @Version 1.0
 **/
public class HttpUtils {
    public static void main(String[] args) {
    }
    /**
     * get
     *
     * @param host
     * @return
     * @throws Exception
     */
    public static HttpResponse doGet(String host)throws Exception {
        return doGet(host, "", "GET", null, null);
    }
    /**
     * get
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doGet(String host, String path, String method, Map<String, String> headers, Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpGet request = new HttpGet(buildUrl(host, path, querys));
        if(null != headers) {
            for (Map.Entry<String, String> e : headers.entrySet()) {
                request.addHeader(e.getKey(), e.getValue());
            }
        }
        return httpClient.execute(request);
    }
    /**
     * post form
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param bodys
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (bodys != null) {
            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
            for (String key : bodys.keySet()) {
                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }
        return httpClient.execute(request);
    }
    /**
     * Post String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }
        return httpClient.execute(request);
    }
    /**
     * Post stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }
        return httpClient.execute(request);
    }
    /**
     * Put String
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }
        return httpClient.execute(request);
    }
    /**
     * Put stream
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }
        return httpClient.execute(request);
    }
    /**
     * Delete
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        return httpClient.execute(request);
    }
    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }
    private static HttpClient wrapClient(String host) {
        HttpClient httpClient = new DefaultHttpClient();
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }
        return httpClient;
    }
    private static void sslClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                @Override
                public void checkClientTrusted(X509Certificate[] xcs, String str) {
                }
                @Override
                public void checkServerTrusted(X509Certificate[] xcs, String str) {
                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/QiYeUtils.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.system.util;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName QiYeUtils
 * @Description TODO
 * @Author jqs
 * @Date 2023/7/18 19:07
 * @Version 1.0
 */
public class QiYeUtils {
    private final static String ACCESS_TOKEN_HOST = "https://qyapi.weixin.qq.com/cgi-bin/";
    public static void main(String[] args) throws Exception {
        String accessToken = getAccessTokenByQY();
        System.out.println(accessToken);
    }
    public static String getAccessTokenByQY() throws Exception {
        String host = ACCESS_TOKEN_HOST + "gettoken?corpid=ww11400938eb1b91bc&corpsecret=-wuQ2EBxNT9BJa40LdpFqyxI_8RqrZTCUNiabzBasi8";
        Map<String, String> headers = new HashMap<>(8);
        HttpResponse response = HttpUtils.doGet(host, "", "GET", headers, null);
        return EntityUtils.toString(response.getEntity());
    }
    public static String getDepartmentList(String accessToken) throws Exception {
        String host = ACCESS_TOKEN_HOST + "department/list?access_token="+accessToken;
        Map<String, String> headers = new HashMap<>(8);
        HttpResponse response = HttpUtils.doGet(host, "", "GET", headers, null);
        return EntityUtils.toString(response.getEntity());
    }
}