给店铺增加了太阳码二维码

This commit is contained in:
Jack 2025-04-01 00:13:48 +08:00
parent c096bf4334
commit c3c155735b
16 changed files with 428 additions and 252 deletions

View File

@ -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-向外提供")

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -122,7 +122,7 @@ public class ShopDistributionStoreBaseServiceImpl extends BaseServiceImpl<ShopDi
} else {
if (poster_type == 2) {
// 生成小程序 URL
Map unlimitedMap = wxQrCodeService.getUnlimited(wap_url, posterMap);
Map unlimitedMap = wxQrCodeService.genUnlimitedWxQrCode(wap_url, posterMap);
String qrcode = Convert.toStr(unlimitedMap.get("floder"));
if (StrUtil.isNotEmpty(qrcode)) {
invite_info.put("qrcode", qrcode);

View File

@ -84,67 +84,88 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
@Service
public class ShopDistributionUserServiceImpl extends BaseServiceImpl<ShopDistributionUserMapper, ShopDistributionUser> 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<ShopDistrib
} else if (poster_type == 2) {
// 生成小程序 URL
Map unlimitedMap = wxQrCodeService.getUnlimited(wap_url, params);
Map unlimitedMap = wxQrCodeService.genUnlimitedWxQrCode(wap_url, params);
qrcode = Convert.toStr(unlimitedMap.get("floder"));
if (!ConfigConstant.FILE_STORAGE_DISK) {
String qr_filename = (String) unlimitedMap.get("qr_filename");
@ -1015,46 +1036,5 @@ public class ShopDistributionUserServiceImpl extends BaseServiceImpl<ShopDistrib
return items;
}
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;
}
}

View File

@ -221,7 +221,10 @@ public class UserOrderController extends BaseControllerImpl {
@RequestMapping(value = "/mch/order/list", method = RequestMethod.POST)
public CommonResult selectMchOrderPageList(@RequestBody JSONObject params) {
Map<String, Object> 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);
}

View File

@ -68,5 +68,5 @@ public interface ShopOrderBaseMapper extends BaseMapper<ShopOrderBase> {
* @param status 订单状态
* @return
*/
IPage<MchOrderInfoDTO> selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("expiredMinute") Integer expiredMinute, IPage<MchOrderInfoDTO> page);
IPage<MchOrderInfoDTO> selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("expireSeconds") Long expireSeconds, IPage<MchOrderInfoDTO> page);
}

View File

@ -542,12 +542,12 @@ public interface ShopOrderBaseService extends IBaseService<ShopOrderBase> {
* @param keyword 订单搜索关键字
* @param delivery 配送方式1-同城配送2-物流配送
* @param status 查询状态1-进行中时效内2-异常订单已超时的3-退款订单
* @param expiredMinute 配送超时的分钟数单位分钟
* @param expireSeconds 配送超时的秒数单位秒
* @param pageNum 页码
* @param pageSize 页大小
* @return
*/
IPage<MchOrderInfoDTO> selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer expiredMinute, Integer pageNum, Integer pageSize);
IPage<MchOrderInfoDTO> selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Long expireSeconds, Integer pageNum, Integer pageSize);
/**
* 商家订单各个分类和状态的订单数量

View File

@ -8492,21 +8492,17 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
* @param keyword 订单搜索关键字
* @param delivery 配送方式1-同城配送2-物流配送
* @param status 查询状态1-进行中时效内2-异常订单已超时的3-退款订单
* @param expiredMinute 配送超时的分钟数单位分钟
* @param expireSeconds 配送超时的秒数单位秒
* @param pageNum 页码
* @param pageSize 页大小
* @return
*/
@Override
public IPage<MchOrderInfoDTO> selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer expiredMinute, Integer pageNum, Integer pageSize) {
public IPage<MchOrderInfoDTO> 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<MchOrderInfoDTO> page = new Page<>(pageNum, pageSize);
if (expiredMinute == null || expiredMinute <= 0) {
expiredMinute = 20;
}
IPage<MchOrderInfoDTO> pageList = shopOrderBaseMapper.selectMchOrderPageList(storeId, keyword, delivery, status, expiredMinute, page);
IPage<MchOrderInfoDTO> 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<ShopOrderBaseMappe
JSONObject jsonObject = new JSONObject();
// refundstatus 退款状态:0-是无退款;1-是部分退款;2-是全部退款
// orderstatus 订单状态2010-ORDER_STATE_WAIT_PAY待付款;2011-ORDER_STATE_WAIT_REVIEW待订单审核;
// 2013-ORDER_STATE_WAIT_FINANCE_REVIEW待财务审核;2014-待配货/待出库审核;
// 2020-ORDER_STATE_PICKING待配货;2030-ORDER_STATE_WAIT_SHIPPING待发货/待收货确认;
// 2040-已发货/待收货确认;2050-ORDER_STATE_RECEIVED已签收;2060-ORDER_STATE_FINISH已完成/已签收;
// orderstatus 订单状态2010-ORDER_STATE_WAIT_PAY 待付款;
// 2011-ORDER_STATE_WAIT_REVIEW 待订单审核;
// 2013-ORDER_STATE_WAIT_FINANCE_REVIEW 待财务审核;
// 2014-待配货/待出库审核;
// 2020-ORDER_STATE_PICKING 待配货;
// 2030-ORDER_STATE_WAIT_SHIPPING 待发货/待收货确认;
// 2040-已发货/待收货确认;
// 2050-ORDER_STATE_RECEIVED 已签收;
// 2060-ORDER_STATE_FINISH 已完成/已签收;
// 2070-ORDER_STATE_CANCEL已取消/已作废;2080-ORDER_STATE_SELF_PICKUP自提
// 全部订单总数量
jsonObject.put("all_order_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, null, null, null));
// 同城配送订单总数量
jsonObject.put("same_city_order_count", shopOrderInfoService.getOrderCountByStoreId(storeId, null, null, new ArrayList<Integer>() {{
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<Integer>() {{
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<Integer>() {{
add(0);
}},
new ArrayList<Integer>() {{
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<Integer>() {{
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<Integer>() {{
add(0);
}},
new ArrayList<Integer>() {{
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<Integer>() {{
add(1);
add(2);
}},
new ArrayList<Integer>() {{
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<Integer>() {{
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<Integer>() {{
add(StateCode.ORDER_STATE_WAIT_PAY);
}},
Collections.singletonList(StateCode.ORDER_STATE_WAIT_PAY),
new ArrayList<Integer>() {{
add(0);
}},
Collections.singletonList(0),
new ArrayList<Integer>() {{
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<Integer>() {{
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<Integer>() {{
add(0);
}},
Collections.singletonList(0),
new ArrayList<Integer>() {{
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<Integer>() {{
add(StateCode.ORDER_STATE_SHIPPED);
}},
Collections.singletonList(StateCode.ORDER_STATE_SHIPPED),
new ArrayList<Integer>() {{
add(0);
}},
Collections.singletonList(0),
new ArrayList<Integer>() {{
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<Integer>() {{
add(StateCode.ORDER_STATE_RECEIVED);
add(StateCode.ORDER_STATE_FINISH);
}},
Arrays.asList(StateCode.ORDER_STATE_RECEIVED, StateCode.ORDER_STATE_FINISH),
new ArrayList<Integer>() {{
add(0);
}},
new ArrayList<Integer>() {{
add(StateCode.DELIVERY_TYPE_EXPRESS);
add(StateCode.DELIVERY_TYPE_EXP);
}},
Collections.singletonList(0),
Arrays.asList(StateCode.DELIVERY_TYPE_EXPRESS, StateCode.DELIVERY_TYPE_EXP),
null
));

View File

@ -151,4 +151,13 @@ public interface ShopStoreBaseService extends IBaseService<ShopStoreBase> {
* @return
*/
Boolean isExistsByStoreName(String storeName);
/**
* 更新店铺微信二维码太阳码
*
* @param storeId
* @param wxQrCode
* @return
*/
Boolean updateStoreBaseQrCode(Integer storeId, String wxQrCode);
}

View File

@ -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<ShopStoreBaseMappe
@Autowired
private BaiduMapServiceImpl baiduMapService;
@Lazy
@Autowired
private WxQrCodeService wxQrCodeService;
/**
* 读取分页列表
@ -1651,7 +1657,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
}
Integer user_id = store_row.getUser_id();
Integer store_id = store_row.getStore_id();
Integer store_id;
if (CheckUtil.isNotEmpty(user_id)) {
AccountUserBase user_base_row = accountService.getUserBase(user_id);
@ -1692,6 +1698,13 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
}
store_id = store_row.getStore_id();
// 生成店铺的太阳码 2025-03-31
Pair<String, String> 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<ShopStoreBaseMappe
ShopProductIndex shopProductIndex = new ShopProductIndex();
if (BeanUtil.isNotEmpty(base)) {
base.setStore_id(store_id);
// 生成店铺的太阳码 2025-03-31
if (StrUtil.isBlank(base.getWx_qrcode())) {
Pair<String, String> 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<ShopStoreBaseMappe
throw new ApiException(ResultCode.FAILED);
}
// 添加默认客户等级
InvoicingCustomerLevel invoicingCustomerLevel = new InvoicingCustomerLevel();
invoicingCustomerLevel.setCustomer_level_name(I18nUtil._("普通(系统默认,不可删除)"));
invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal("100"));
@ -3327,6 +3350,24 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
return count(queryWrapper) > 0;
}
/**
* 更新店铺微信二维码太阳码
*
* @param storeId
* @param wxQrCode
* @return
*/
@Override
public Boolean updateStoreBaseQrCode(Integer storeId, String wxQrCode) {
if (ObjectUtil.isEmpty(storeId) || StrUtil.isBlank(wxQrCode)) {
return false;
}
UpdateWrapper<ShopStoreBase> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("store_id", storeId).eq("wx_qrcode", "").set("wx_qrcode", wxQrCode);
return update(updateWrapper);
}
/**
* 处理 store_slide 字段
*

View File

@ -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<String, Object> 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"));
}
}

View File

@ -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<String, String> genUnlimitedWxQrCode(String page, String scene);
}

View File

@ -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<String> paramList = Convert.toList(String.class, params);
Iterator<String> 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<String, String> 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<String, String> 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<String> paramList = Convert.toList(String.class, params);
Iterator<String> 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;
}
}

View File

@ -616,11 +616,13 @@
</collection>
</resultMap>
<!--// refundstatus 退款状态:0-是无退款;1-是部分退款;2-是全部退款
// orderstatus 订单状态2010-待付款;2011-待订单审核;2012-待发货;2013-待财务审核;2014-待配货/待出库审核;2020-待发货;2030-待发货/待收货确认;2040-已发货/待收货确认;2050-已签收;2060-已完成/已签收;2070-已取消/已作废;2080-自提-->
<select id="selectMchOrderPageList" resultMap="MchOrderResult">
SELECT
ob.order_id,
ob.order_time,
UNIX_TIMESTAMP(ob.order_time) as arrival_time,
oi.order_time + #{expireSeconds}*1000 as arrival_time,
ob.order_product_amount,
ob.order_payment_amount,
ob.currency_id,
@ -633,7 +635,8 @@
oi.order_pickup_num,
oi.delivery_type_id,
oi.buyer_user_id,
IF((SELECT count(*) FROM shop_order_base WHERE buyer_user_id = oi.buyer_user_id AND order_state_id>=2020)>1,2,1)
IF((SELECT count(*) FROM shop_order_base WHERE buyer_user_id = oi.buyer_user_id AND order_state_id IN (2011,
2013, 2014, 2020, 2030, 2040))>1,2,1)
AS is_new_buyer,
oi.payment_time,
od.order_shipping_fee,
@ -701,28 +704,28 @@
<!--配送方式1-同城配送2-物流配送-->
<if test="delivery!=null and delivery==1">
and oi.delivery_type_id IN (16, 5)
and ob.order_state_id IN (2011, 2013, 2014, 2020, 2030, 2040)
and oi.delivery_type_id = 16
<!--进行中-->
<if test="status!=null and status==1 and expireSeconds!=null and expireSeconds>0">
and arrival_time <![CDATA[>=]]> UNIX_TIMESTAMP() * 1000
</if>
<!--超时异常-->
<if test="status!=null and status==2 and expireSeconds!=null and expireSeconds>0">
and arrival_time <![CDATA[<]]> UNIX_TIMESTAMP() * 1000
</if>
<!--退款订单-->
<if test="status!=null and status==3">
and od.order_refund_status IN (1, 2)
</if>
</if>
<if test="delivery!=null and delivery==2">
and oi.delivery_type_id NOT IN (16,5)
</if>
<!--进行中-->
<if test="status!=null and status==1">
and ob.order_state_id IN (2020, 2030, 2040)
and TIMESTAMPADD(MINUTE, #{expiredMinute}, oi.order_time) &gt;= NOW()
</if>
<!--超时异常-->
<if test="status!=null and status==2">
and ob.order_state_id IN (2020, 2030, 2040)
and TIMESTAMPADD(MINUTE, #{expiredMinute}, oi.order_time) &lt;= NOW()
</if>
<!--退款订单-->
<if test="status!=null and status==3">
and od.order_refund_status IN (1, 2)
and ob.order_state_id IN (2011, 2013, 2014, 2020, 2030, 2040)
and oi.delivery_type_id NOT IN (1,2,3,4,10)
</if>
</where>
order by ob.order_time desc