diff --git a/mall-account/src/main/java/com/suisung/mall/account/controller/mobile/WeiXinController.java b/mall-account/src/main/java/com/suisung/mall/account/controller/mobile/WeiXinController.java index 8bc409c0..adaf468a 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/controller/mobile/WeiXinController.java +++ b/mall-account/src/main/java/com/suisung/mall/account/controller/mobile/WeiXinController.java @@ -41,7 +41,7 @@ public class WeiXinController extends BaseControllerImpl { @RequestParam(name = "signature") String signature, @RequestParam(name = "nonce") String nonce, @RequestParam(name = "echostr") String echostr) { - return weiXinService.checkSignature(timestamp, nonce, signature) == true ? echostr : null; + return weiXinService.checkSignature(timestamp, nonce, signature) ? echostr : null; } @ApiOperation(value = "公众号登录 - 获取code请求") @@ -84,10 +84,16 @@ public class WeiXinController extends BaseControllerImpl { return CommonResult.success(weiXinService.jsCode2Session(code, encryptedData, iv, activity_id, user_info)); } - @ApiOperation(value = "小程序获取手机号") + @ApiOperation(value = "获取微信小程序用户授权手机号,并绑定登录用户") @RequestMapping(value = "/getUserPhoneNumber", method = RequestMethod.GET) public CommonResult getUserPhoneNumber(@RequestParam(name = "code") String code) { - return CommonResult.success(weiXinService.getUserPhoneNumber(code, getCurrentUser())); + return CommonResult.success(weiXinService.getUserPhoneNumberAndBindUser(code, getCurrentUser())); + } + + @ApiOperation(value = "登录前获取微信小程序用户授权手机号") + @RequestMapping(value = "/getWxUserPhoneNumber", method = {RequestMethod.GET, RequestMethod.POST}) + public CommonResult getWxUserPhoneNumber(@RequestParam(name = "code") String code) { + return weiXinService.getWxUserPhoneNumber(code); } @ApiOperation(value = "获取AccessToken-向外提供") diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/WeiXinService.java b/mall-account/src/main/java/com/suisung/mall/account/service/WeiXinService.java index e2f5492e..581f4faf 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/WeiXinService.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/WeiXinService.java @@ -1,5 +1,6 @@ package com.suisung.mall.account.service; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.domain.UserDto; import com.suisung.mall.common.modules.account.AccountUserBindConnect; @@ -36,7 +37,23 @@ public interface WeiXinService { Map jsCode2Session(String code, String encryptedData, String iv, String activity_id, String user_info); - Map getUserPhoneNumber(String code, UserDto user); + /** + * 登录后,获取微信用户授权的手机号码,并绑定用户和用户手机号码,注意:必须登录之后,才能获取手机号码 + * + * @param code + * @param user + * @return + */ + Map getUserPhoneNumberAndBindUser(String code, UserDto user); + + /** + * 未登录前,获取微信用户授权的手机号码 + * + * @param code + * @return + */ + CommonResult getWxUserPhoneNumber(String code); + Map wxConfig(String url); diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/impl/WeiXinServiceImpl.java b/mall-account/src/main/java/com/suisung/mall/account/service/impl/WeiXinServiceImpl.java index 1128a80c..6d679c9d 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/impl/WeiXinServiceImpl.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/impl/WeiXinServiceImpl.java @@ -405,7 +405,7 @@ public class WeiXinServiceImpl implements WeiXinService { } @Override - public Map getUserPhoneNumber(String code, UserDto userDto) { + public Map getUserPhoneNumberAndBindUser(String code, UserDto userDto) { String accessToken = getXcxAccessToken(true); String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken; Map params = new HashMap(); @@ -436,6 +436,38 @@ public class WeiXinServiceImpl implements WeiXinService { return userInfo; } + /** + * 未登录前,获取微信用户授权的手机号码 + * + * @param code + * @return + */ + @Override + public CommonResult getWxUserPhoneNumber(String code) { + String accessToken = getXcxAccessToken(true); + String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken; + Map params = new HashMap(); + params.put("code", code); + JSON parseParam = JSONUtil.parse(params); + String responseStr = WxHttpUtil.request(WxHttpUtil.MethodType.POST, WxHttpUtil.WxType.XCX, accessToken, url, null, Convert.toStr(parseParam)); + log.debug("获取用户手机号返回的数据:{}", responseStr); + + JSONObject jsonObject = JSONUtil.parseObj(responseStr); + Integer errcode = jsonObject.get("errcode", Integer.class); + if (ObjectUtil.isNull(errcode) || !errcode.equals(0)) { + logger.error("获取不到授权手机号:", responseStr); + return CommonResult.failed(I18nUtil._("获取不到授权手机号!")); + } + + Object phoneInfoObj = jsonObject.get("phone_info"); + if (ObjectUtil.isNull(phoneInfoObj)) { + logger.error("获取不到授权手机号:", responseStr); + return CommonResult.failed(I18nUtil._("获取不到授权手机号!")); + } + + return CommonResult.success(phoneInfoObj); + } + public AccountUserBindConnect getVxMiniAppUserBindConnect(String code, String encryptedData, String iv, String user_info) { //解析用户基本信息 JSONObject jsonObject = JSONUtil.parseObj(user_info); diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/UserInfoService.java b/mall-common/src/main/java/com/suisung/mall/common/utils/UserInfoService.java index 1ce57aa6..bb60a778 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/UserInfoService.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/UserInfoService.java @@ -47,7 +47,7 @@ public class UserInfoService { userStr = null; } - if (StrUtil.isBlank(userStr)) { + if (StrUtil.isNotBlank(userStr)) { // 将 JSON 字符串转换为 UserDto 对象 return JSONUtil.toBean(userStr, UserDto.class); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/distribution/service/impl/ShopDistributionStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/distribution/service/impl/ShopDistributionStoreBaseServiceImpl.java index 3fa76e14..e043557d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/distribution/service/impl/ShopDistributionStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/distribution/service/impl/ShopDistributionStoreBaseServiceImpl.java @@ -122,7 +122,7 @@ public class ShopDistributionStoreBaseServiceImpl extends BaseServiceImpl implements ShopDistributionUserService { + private static final Logger logger = LoggerFactory.getLogger(ShopDistributionUserServiceImpl.class); @Autowired private AccountService accountService; - @Autowired private AccountBaseConfigService accountBaseConfigService; - @Autowired private ShopBaseDistrictService shopBaseDistrictService; - @Autowired private ShopDistributionPlantformUserService plantformUserServicel; - @Autowired private ShopDistributionUserCommissionService userCommissionService; - @Autowired private ShopDistributionUserOrderService userOrderService; - @Autowired private ShopDistributionUserOrderService shopDistributionUserOrderService; - @Autowired private ShopDistributionPlantformUserService shopDistributionPlantformUserService; - @Autowired private ShopDistributionUserCommissionService shopDistributionUserCommissionService; - @Autowired private WxQrCodeService wxQrCodeService; - @Autowired private OssService ossService; - @Value("${url.h5}") private String base_ip; - @Value("${static.file.path}") private String static_file_path; - @Value("${static.file.url}") private String static_file_url; - @Value("${aliyun.oss.dir.prefix}") private String ALIYUN_OSS_DIR_PREFIX; - @Value("#{accountBaseConfigService.getConfig('aliyun_endpoint')}") private String ALIYUN_OSS_ENDPOINT; - @Value("#{accountBaseConfigService.getConfig('aliyun_bucket')}") private String ALIYUN_OSS_BUCKET_NAME; - @Value("#{accountBaseConfigService.getConfig('tengxun_default_dir')}") private String TENGXUN_DEFAULT_DIR; - @Autowired private ThreadPoolExecutor executor; - @Autowired private RedisService redisService; - private static Logger logger = LoggerFactory.getLogger(ShopDistributionUserServiceImpl.class); + public static File getFile(String url) throws Exception { + //对本地文件命名 + URL aURL = new URL(url); + String fileName = Md5Utils.getMD5(aURL.getFile(), "utf-8"); + + File file = null; + + URL urlfile; + InputStream inStream = null; + OutputStream os = null; + try { + file = File.createTempFile("net_url", fileName); + //下载 + urlfile = new URL(url); + inStream = urlfile.openStream(); + os = new FileOutputStream(file); + + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + throw new ApiException(I18nUtil._("图片不存在!")); + } finally { + try { + if (null != os) { + os.close(); + } + if (null != inStream) { + inStream.close(); + } + + } catch (Exception e) { + throw new ApiException(I18nUtil._("图片不存在!")); + } + } + + return file; + } @Override public Map index() { @@ -709,7 +730,7 @@ public class ShopDistributionUserServiceImpl extends BaseServiceImpl respMap = new HashMap<>(); - respMap.put("order_page_list", shopOrderBaseService.selectMchOrderPageList(params.getInt("storeId"), params.getStr("keyword"), params.getInt("delivery"), params.getInt("status"), 25, params.getInt("pageNum"), params.getInt("pageSize"))); + // 订单分页数据 + Long expireSeconds = 1200L; // 60秒*20分钟 = 1200秒 + respMap.put("order_page_list", shopOrderBaseService.selectMchOrderPageList(params.getInt("storeId"), params.getStr("keyword"), params.getInt("delivery"), params.getInt("status"), expireSeconds, params.getInt("pageNum"), params.getInt("pageSize"))); + // 订单数量 respMap.put("order_count", shopOrderBaseService.mchOrderCountByStoreId(params.getInt("storeId"))); return CommonResult.success(respMap); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java index 28352e09..8f2d6d23 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java @@ -68,5 +68,5 @@ public interface ShopOrderBaseMapper extends BaseMapper { * @param status 订单状态 * @return */ - IPage selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("expiredMinute") Integer expiredMinute, IPage page); + IPage selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("expireSeconds") Long expireSeconds, IPage page); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java index 1d207078..c609d53e 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java @@ -542,12 +542,12 @@ public interface ShopOrderBaseService extends IBaseService { * @param keyword 订单搜索关键字 * @param delivery 配送方式:1-同城配送;2-物流配送 * @param status 查询状态:1-进行中(时效内);2-异常订单(已超时的);3-退款订单 - * @param expiredMinute 配送超时的分钟数,单位分钟 + * @param expireSeconds 配送超时的秒数,单位秒 * @param pageNum 页码 * @param pageSize 页大小 * @return */ - IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer expiredMinute, Integer pageNum, Integer pageSize); + IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Long expireSeconds, Integer pageNum, Integer pageSize); /** * 商家订单各个分类和状态的订单数量 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 718437f6..8aab1d5f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -8492,21 +8492,17 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer expiredMinute, Integer pageNum, Integer pageSize) { + public IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Long expireSeconds, Integer pageNum, Integer pageSize) { // order_state_id 订单状态(LIST):2011-待订单审核;2013-待财务审核;2020-待配货/待出库审核;2030-待发货;2040-已发货/待收货确认;2060-已完成/已签收;2070-已取消/已作废; Page page = new Page<>(pageNum, pageSize); - if (expiredMinute == null || expiredMinute <= 0) { - expiredMinute = 20; - } - - IPage pageList = shopOrderBaseMapper.selectMchOrderPageList(storeId, keyword, delivery, status, expiredMinute, page); + IPage pageList = shopOrderBaseMapper.selectMchOrderPageList(storeId, keyword, delivery, status, expireSeconds, page); if (pageList != null && CollUtil.isNotEmpty(pageList.getRecords())) { pageList.getRecords().forEach(mchOrderInfoDTO -> { if ((StateCode.DELIVERY_TYPE_EXP == mchOrderInfoDTO.getDelivery_type_id() @@ -8538,148 +8534,98 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl() {{ - add(StateCode.DELIVERY_TYPE_SAME_CITY); - }}, + jsonObject.put("same_city_order_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, null, + Collections.singletonList(StateCode.DELIVERY_TYPE_SAME_CITY), null )); // 同城配送进行中订单数量 jsonObject.putByPath("same_city_order.progress_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_WAIT_REVIEW); - add(StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW); - add(StateCode.ORDER_STATE_WAIT_PAID); - add(StateCode.ORDER_STATE_PICKING); - add(StateCode.ORDER_STATE_WAIT_SHIPPING); - add(StateCode.ORDER_STATE_SHIPPED); - }}, - - new ArrayList() {{ - add(0); - }}, - - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_SAME_CITY); - }}, + Arrays.asList(StateCode.ORDER_STATE_WAIT_REVIEW, StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW, + StateCode.ORDER_STATE_WAIT_PAID, StateCode.ORDER_STATE_PICKING, + StateCode.ORDER_STATE_WAIT_SHIPPING, StateCode.ORDER_STATE_SHIPPED), + Collections.singletonList(0), + Collections.singletonList(StateCode.DELIVERY_TYPE_SAME_CITY), null )); // 同城配送超时订单数量 jsonObject.putByPath("same_city_order.overtime_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_WAIT_REVIEW); - add(StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW); - add(StateCode.ORDER_STATE_WAIT_PAID); - add(StateCode.ORDER_STATE_PICKING); - add(StateCode.ORDER_STATE_WAIT_SHIPPING); - add(StateCode.ORDER_STATE_SHIPPED); - }}, + Arrays.asList(StateCode.ORDER_STATE_WAIT_REVIEW, + StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW, + StateCode.ORDER_STATE_WAIT_PAID, + StateCode.ORDER_STATE_PICKING, + StateCode.ORDER_STATE_WAIT_SHIPPING, + StateCode.ORDER_STATE_SHIPPED), - new ArrayList() {{ - add(0); - }}, - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_SAME_CITY); - }}, + Collections.singletonList(0), + Collections.singletonList(StateCode.DELIVERY_TYPE_SAME_CITY), 120L )); // 同城配送退款订单数量 jsonObject.putByPath("same_city_order.refund_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, - new ArrayList() {{ - add(1); - add(2); - }}, - - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_SAME_CITY); - }}, + Arrays.asList(1, 2), + Collections.singletonList(StateCode.DELIVERY_TYPE_SAME_CITY), null )); // 普通物流订单总数量 - jsonObject.put("logistics_order_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, null, new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_EXPRESS); - add(StateCode.DELIVERY_TYPE_EXP); - }}, + jsonObject.put("logistics_order_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, null, + Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP), null )); // 普通物流待支付订单数量 jsonObject.putByPath("logistics_order.wait_pay_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_WAIT_PAY); - }}, + Collections.singletonList(StateCode.ORDER_STATE_WAIT_PAY), - new ArrayList() {{ - add(0); - }}, + Collections.singletonList(0), - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_EXPRESS); - add(StateCode.DELIVERY_TYPE_EXP); - }}, + Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP), null )); // 普通物流待发货订单数量 jsonObject.putByPath("logistics_order.wait_shipping_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_WAIT_REVIEW); - add(StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW); - add(StateCode.ORDER_STATE_WAIT_PAID); - add(StateCode.ORDER_STATE_PICKING); - add(StateCode.ORDER_STATE_WAIT_SHIPPING); - }}, + Arrays.asList(StateCode.ORDER_STATE_WAIT_REVIEW, + StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW, + StateCode.ORDER_STATE_WAIT_PAID, + StateCode.ORDER_STATE_PICKING, + StateCode.ORDER_STATE_WAIT_SHIPPING), - new ArrayList() {{ - add(0); - }}, + Collections.singletonList(0), - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_EXPRESS); - add(StateCode.DELIVERY_TYPE_EXP); - }}, + Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP), null )); // 普通物流待收货订单数量 jsonObject.putByPath("logistics_order.receiving_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_SHIPPED); - }}, + Collections.singletonList(StateCode.ORDER_STATE_SHIPPED), - new ArrayList() {{ - add(0); - }}, + Collections.singletonList(0), - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_EXPRESS); - add(StateCode.DELIVERY_TYPE_EXP); - }}, + Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP), null )); // 普通物流已完成订单数量 jsonObject.putByPath("logistics_order.finished_count", shopOrderInfoService.getOrderCountByStoreId(storeId, - new ArrayList() {{ - add(StateCode.ORDER_STATE_RECEIVED); - add(StateCode.ORDER_STATE_FINISH); - }}, + Arrays.asList(StateCode.ORDER_STATE_RECEIVED, StateCode.ORDER_STATE_FINISH), - new ArrayList() {{ - add(0); - }}, - new ArrayList() {{ - add(StateCode.DELIVERY_TYPE_EXPRESS); - add(StateCode.DELIVERY_TYPE_EXP); - }}, + Collections.singletonList(0), + Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP), null )); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java index 59712064..3362cb99 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java @@ -151,4 +151,13 @@ public interface ShopStoreBaseService extends IBaseService { * @return */ Boolean isExistsByStoreName(String storeName); + + /** + * 更新店铺微信二维码(太阳码) + * + * @param storeId + * @param wxQrCode + * @return + */ + Boolean updateStoreBaseQrCode(Integer storeId, String wxQrCode); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java index 7f33c577..fce2e75f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreBaseServiceImpl.java @@ -13,6 +13,7 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.suisung.mall.common.api.BindCode; @@ -62,6 +63,7 @@ import com.suisung.mall.shop.product.service.ShopProductIndexService; import com.suisung.mall.shop.store.mapper.ShopStoreBaseMapper; import com.suisung.mall.shop.store.service.*; import com.suisung.mall.shop.user.service.ShopUserFavoritesStoreService; +import com.suisung.mall.shop.wechat.service.WxQrCodeService; import io.seata.spring.annotation.GlobalTransactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -176,6 +178,10 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl resp = wxQrCodeService.genUnlimitedWxQrCode("pagesub/index/store", "store_id=" + store_id); + if (StrUtil.isNotBlank(resp.getFirst())) { + updateStoreBaseQrCode(store_id, resp.getFirst()); + } + + // 初始化默认公司信息,避免商家编辑不了 ShopStoreCompany company_column = new ShopStoreCompany(); company_column.setUser_id(store_row.getUser_id()); @@ -2503,6 +2516,15 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl resp = wxQrCodeService.genUnlimitedWxQrCode("pagesub/index/store", "store_id=" + store_id); + if (StrUtil.isNotBlank(resp.getFirst())) { + base.setWx_qrcode(resp.getFirst()); + } + } + if (!saveOrUpdate(base)) { throw new ApiException(ResultCode.FAILED); } @@ -3298,6 +3320,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0; } + /** + * 更新店铺微信二维码(太阳码) + * + * @param storeId + * @param wxQrCode + * @return + */ + @Override + public Boolean updateStoreBaseQrCode(Integer storeId, String wxQrCode) { + if (ObjectUtil.isEmpty(storeId) || StrUtil.isBlank(wxQrCode)) { + return false; + } + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("store_id", storeId).eq("wx_qrcode", "").set("wx_qrcode", wxQrCode); + return update(updateWrapper); + } + /** * 处理 store_slide 字段 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxQrCodeContorller.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxQrCodeContorller.java index 6e3ca3d6..a77097ba 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxQrCodeContorller.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/controller/WxQrCodeContorller.java @@ -2,6 +2,7 @@ package com.suisung.mall.shop.wechat.controller; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.utils.I18nUtil; @@ -23,9 +24,9 @@ public class WxQrCodeContorller { @ApiOperation(value = "获取小程序码", notes = "获取小程序码") @RequestMapping(value = "/getWxQrCode", method = RequestMethod.POST) - public CommonResult getWxQrCode(@RequestParam(name = "path") String path, + public CommonResult getWxQrCode(@RequestParam(value = "preparedUrl") String preparedUrl, @RequestBody Map params) { - Map unlimited = wxQrCodeService.getUnlimited(path, params); + Map unlimited = wxQrCodeService.genUnlimitedWxQrCode(preparedUrl, params); String wxQrcode = Convert.toStr(unlimited.get("floder")); if (StrUtil.isEmpty(wxQrcode)) { throw new ApiException(I18nUtil._("小程序码生成错误")); @@ -33,4 +34,10 @@ public class WxQrCodeContorller { return CommonResult.success(wxQrcode); } + @ApiOperation(value = "获取小程序码2", notes = "获取小程序码") + @RequestMapping(value = "/getWxQrCode2", method = RequestMethod.POST) + public CommonResult getWxQrCode2(@RequestBody JSONObject params) { + return wxQrCodeService.genUnlimitedWxQrCode2(params.getStr("page"), params.getStr("scene")); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java index c167e2f3..1c54fcfd 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/WxQrCodeService.java @@ -1,5 +1,8 @@ package com.suisung.mall.shop.wechat.service; +import com.suisung.mall.common.api.CommonResult; +import org.springframework.data.util.Pair; + import java.util.Map; /** @@ -12,8 +15,31 @@ import java.util.Map; */ public interface WxQrCodeService { + /** + * 获取微信的 accessToken + * + * @return + */ String getAccessToken(); - Map getUnlimited(String preparedUrl, Map param); + /** + * 生成(永久)小程序太阳码 + * + * @param page + * @param scene + * @return + */ + CommonResult genUnlimitedWxQrCode2(String page, String scene); + + Map genUnlimitedWxQrCode(String preparedUrl, Map param); + + /** + * 生成(永久)小程序太阳码 (内部调用) + * + * @param page + * @param scene + * @return + */ + Pair genUnlimitedWxQrCode(String page, String scene); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java index 11fec19d..958515be 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/wechat/service/impl/WxQrCodeServiceImpl.java @@ -11,6 +11,7 @@ import cn.hutool.json.JSON; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.nacos.common.util.Md5Utils; +import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.api.StateCode; import com.suisung.mall.common.constant.ConfigConstant; import com.suisung.mall.common.exception.ApiException; @@ -21,13 +22,20 @@ import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.page.service.OssService; import com.suisung.mall.shop.wechat.service.WxQrCodeService; import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClients; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; @@ -71,6 +79,55 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { @Value("#{accountBaseConfigService.getConfig('tengxun_default_dir')}") private String TENGXUN_DEFAULT_DIR; + @Value("${spring.profiles.active}") + private String profile; + + static Map parseUrl(String preparedUrl) throws MalformedURLException { + URL url = new URL(preparedUrl); + String urlPath = url.getPath(); + + Map resultMap = new HashMap(); + urlPath = urlPath.replace("/wap", ""); + urlPath = urlPath.replaceFirst("/", "").replaceAll("h5/", ""); + resultMap.put("lastUrl", urlPath); + String query = url.getQuery(); + + if (StrUtil.isNotEmpty(query)) { + String[] params = query.split("&"); + List paramList = Convert.toList(String.class, params); + Iterator it = paramList.iterator(); + while (it.hasNext()) { + String next = it.next(); + if (next.startsWith("source_ucc_code")) { + it.remove(); + } + } + + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < paramList.size(); i++) { + sb.append(paramList.get(i)); + if (i + 1 < paramList.size()) { + sb.append("&"); + } + } + query = sb.toString(); + // 如果参数长度超过32位 + if (query.length() > 32) { + StringBuffer longStr = new StringBuffer(); + for (int i = 0; i < paramList.size(); i++) { + String[] split = paramList.get(i).split("="); + longStr.append(split[1]); + if (i + 1 < paramList.size()) { + longStr.append("-"); + } + } + query = "longUrl=" + longStr; + } + } + + resultMap.put("query", query); + return resultMap; + } public String getAccessToken() { if (!redisService.hasKey(StateCode.WX_XCX_ACCESSTOKEN)) { @@ -105,15 +162,111 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { } /** - * 生成小程序太阳码 + * 生成(永久)小程序太阳码 * - * @param preparedUrl - * @param param + * @param page + * @param scene * @return - * @throws IOException */ @Override - public Map getUnlimited(String preparedUrl, Map param) { + public CommonResult genUnlimitedWxQrCode2(String page, String scene) { + // 小程序店铺主页:pagesub/index/store?store_id=3 + Pair resp = genUnlimitedWxQrCode(page, scene); + if (resp == null || StrUtil.isBlank(resp.getFirst())) { + return CommonResult.failed(resp.getSecond()); + } + + Map resultMap = new HashMap(); + resultMap.put("wxQrCodeUrl", resp.getFirst()); + return CommonResult.success(resultMap); + } + + public Pair genUnlimitedWxQrCode(String page, String scene) { + + // 小程序店铺主页:pagesub/index/store?store_id=3 + try { + boolean check_path = StrUtil.isNotBlank(profile) && profile.equals("prod"); + String env_version = "trial"; + if (check_path) { + env_version = "release"; + } + + String reqUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + getAccessToken(); + Map params = new HashMap(); + params.put("scene", scene); + params.put("page", page); + params.put("is_hyaline", true); + params.put("check_path", check_path); + params.put("env_version", env_version); + params.put("auto_color", true); + String paramStr = JSONUtil.parse(params).toString(); + String fileName = Md5Utils.getMD5(paramStr, "UTF-8") + "_qrcode.png"; + + HttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(reqUrl); + httpPost.setEntity(new StringEntity(paramStr, "UTF-8")); + httpPost.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpPost); + HttpEntity codeEntity = response.getEntity(); + InputStream inputStream = codeEntity.getContent(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] bytes = outputStream.toByteArray(); + if (bytes.length < 9999) { + return Pair.of("", I18nUtil._("图片生成失败,参数有误!")); +// return CommonResult.failed(I18nUtil._("图片生成失败,参数有误!")); + } + + + Map resultMap = new HashMap(); + + if (!ConfigConstant.FILE_STORAGE_DISK) { + // 存入第三方文件存储服务 + InputStream stream = new ByteArrayInputStream(bytes); + String dir = "/media/plantform"; + + String wxQrCodeUrl = null; + Integer uploadType = accountBaseConfigService.getConfig("upload", 1); + + if (uploadType.equals(1)) { + wxQrCodeUrl = ConfigConstant.URL_BASE + "/admin/oss/upload" + dir + "/" + fileName; // 文件本地路径 + } else if (uploadType.equals(2)) { + // oss 服务 + String floder = ALIYUN_OSS_DIR_PREFIX.concat("/") + dir + "/poster/2/"; + wxQrCodeUrl = ossService.uploadObject2OSS(null, floder + fileName, stream, fileName, Convert.toLong(bytes.length)); + } else if (uploadType.equals(4)) { + String poster_path = String.format("%s/media/plantform/poster/%s/", ConfigConstant.STATIC_FILE_PATH, 2); + IoUtil.write(FileUtil.getOutputStream(poster_path + fileName), true, bytes); + File posterFile = FileUtil.file(poster_path + fileName); + wxQrCodeUrl = ossService.uploadObject4OSS(posterFile, TENGXUN_DEFAULT_DIR.concat(dir).concat("/").concat(fileName)); + } + + resultMap.put("wxQrCodeUrl", wxQrCodeUrl); + resultMap.put("fileName", fileName); + return Pair.of(wxQrCodeUrl, ""); +// return CommonResult.success(resultMap); + } + + // 存入本地文件 + String poster_path = String.format("%s/media/plantform/poster/%s/", ConfigConstant.STATIC_FILE_PATH, 2); + IoUtil.write(FileUtil.getOutputStream(poster_path + fileName), true, bytes); + resultMap.put("wxQrCodeUrl", poster_path + fileName); + resultMap.put("fileName", fileName); + return Pair.of(poster_path + fileName, ""); + } catch (Exception e) { +// return CommonResult.failed(I18nUtil._("图片生成错误!")); + return Pair.of("", I18nUtil._("图片生成错误")); + } + } + + + @Override + public Map genUnlimitedWxQrCode(String preparedUrl, Map param) { try { String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="; String reqUrl = url + getAccessToken(); @@ -187,51 +340,4 @@ public class WxQrCodeServiceImpl implements WxQrCodeService { return null; } - static Map parseUrl(String preparedUrl) throws MalformedURLException { - URL url = new URL(preparedUrl); - String urlPath = url.getPath(); - - Map resultMap = new HashMap(); - urlPath = urlPath.replace("/wap", ""); - urlPath = urlPath.replaceFirst("/", "").replaceAll("h5/", ""); - resultMap.put("lastUrl", urlPath); - String query = url.getQuery(); - - if (StrUtil.isNotEmpty(query)) { - String[] params = query.split("&"); - List paramList = Convert.toList(String.class, params); - Iterator it = paramList.iterator(); - while (it.hasNext()) { - String next = it.next(); - if (next.startsWith("source_ucc_code")) { - it.remove(); - } - } - - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < paramList.size(); i++) { - sb.append(paramList.get(i)); - if (i + 1 < paramList.size()) { - sb.append("&"); - } - } - query = sb.toString(); - // 如果参数长度超过32位 - if (query.length() > 32) { - StringBuffer longStr = new StringBuffer(); - for (int i = 0; i < paramList.size(); i++) { - String[] split = paramList.get(i).split("="); - longStr.append(split[1]); - if (i + 1 < paramList.size()) { - longStr.append("-"); - } - } - query = "longUrl=" + longStr; - } - } - - resultMap.put("query", query); - return resultMap; - } - } diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml index 3397c8da..ccf371b2 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml @@ -616,11 +616,13 @@ +