Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product_new

# Conflicts:
#	yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/service/recharge/RechargeOrderServiceImpl.java
pull/2/head
perry 2023-05-24 16:03:33 +08:00
commit b87a5d35a7
41 changed files with 1078 additions and 597 deletions

View File

@ -24,4 +24,5 @@ public interface ApiConfigApi {
* </pre>
*/
CommonResult<String> getConfigKey( String key);
String getConfigKeyValue( String key);
}

View File

@ -50,4 +50,16 @@ public class ApiConfigImpl implements ApiConfigApi{
}
return success(config.getValue());
}
@Override
public String getConfigKeyValue(String key) {
ConfigDO config = configService.getConfigByKey(key);
if (config == null) {
return null;
}
if (!config.getVisible()) {
throw exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE);
}
return config.getValue();
}
}

View File

@ -40,10 +40,10 @@ public class CreateOrderRequest implements Serializable {
private Integer shippingType;
@Schema(description = "收货地址id")
private Integer addressId;
private Long addressId;
@Schema(description = "优惠券编号")
private Integer couponId;
private Long couponId;
@Schema(description = "支付类型:weixin-微信支付yue-余额支付,alipay-支付宝支付")
@NotBlank(message = "支付类型不能为空")

View File

@ -32,10 +32,10 @@ public class OrderComputedPriceRequest {
private String preOrderNo;
@Schema(description = "地址id")
private Integer addressId;
private Long addressId;
@Schema(description = "优惠券id")
private Integer couponId;
private Long couponId;
@Schema(description = "快递类型: 1-快递配送2-到店自提")
@NotNull(message = "快递类型不能为空")

View File

@ -72,6 +72,9 @@ public class StoreProductAttrValueAddRequest implements Serializable {
@DecimalMin(value = "0", message = "原价不能小于0")
private BigDecimal otPrice;
@Schema(description= "商品条码(一维码)")
private String barCode;
@Schema(description= "重量", required = true)
@NotNull(message = "规格属性重量不能为空")
@DecimalMin(value = "0", message = "重量不能小于0")

View File

@ -54,6 +54,9 @@ public class AttrValueResponse implements Serializable {
@Schema(description= "原价")
private BigDecimal otPrice;
@Schema(description= "商品条码(一维码)")
private String barCode;
@Schema(description= "重量")
private BigDecimal weight;

View File

@ -45,7 +45,7 @@ public class OrderInfoVo {
private BigDecimal payFee;
@Schema(description = "地址id")
private Integer addressId;
private Long addressId;
@Schema(description = "收货人姓名(前端用)")
private String realName;

View File

@ -48,4 +48,7 @@ public class ShippingTemplatesFreeRespVO implements Serializable {
@NotNull(message = "请填写包邮金额")
@DecimalMin(value = "0", message = "包邮金额不能低于0")
private BigDecimal price;
@Schema(description = "分组唯一值", required = true)
private String uniqid;
}

View File

@ -34,7 +34,8 @@ public class ShippingTemplatesNoDeliveryRespVO implements Serializable {
@NotNull(message = "请选择城市")
private String cityId;
@Schema(description = "分组唯一值", required = true)
private String uniqid;
@Schema(description = "省ID, 多个逗号分割。 全国 all", required = true, example = "1,2,3,4")
private String provinceId;

View File

@ -55,4 +55,7 @@ public class ShippingTemplatesRegionRespVO implements Serializable {
@DecimalMin(value = "0.1", message = "续件运费金额不能低于0.1")
private BigDecimal renewalPrice;
@Schema(description = "分组唯一值", required = true)
private String uniqid;
}

View File

@ -57,7 +57,7 @@ public class ShippingTemplatesReqVO implements Serializable {
private Boolean noDelivery;
@Schema(description = "指定不送设置", required = true)
private List<ShippingTemplatesNoDeliveryRespVO> shippingTemplatesNoDeliveryRespVOS;
private ShippingTemplatesNoDeliveryRespVO shippingTemplatesNoDeliveryRespVOS;
@Schema(description = "排序", example = "0")
@NotNull(message = "排序数字必须填写")

View File

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.shop.dal.dataobject.express;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

View File

@ -45,5 +45,10 @@ public class ShippingTemplatesNoDeliveryDO implements Serializable {
private Integer provinceId;
/**
*
*/
private String uniqid;
}

View File

@ -43,6 +43,11 @@ public class ShippingTemplatesRegionDO implements Serializable {
*/
private Integer cityId;
/**
*
*/
private String uniqid;
private Integer provinceId;

View File

@ -74,7 +74,7 @@ public class StoreOrder implements Serializable {
private BigDecimal deductionPrice;
@Schema(description = "优惠券id")
private Integer couponId;
private Long couponId;
@Schema(description = "优惠券金额")
private BigDecimal couponPrice;

View File

@ -25,7 +25,7 @@ import java.util.List;
@Validated
public interface ShippingTemplatesNoDeliveryService extends IService<ShippingTemplatesNoDeliveryDO> {
void saveAll(List<ShippingTemplatesNoDeliveryRespVO> shippingTemplatesFreeRespVOList, Integer id);
void saveAll(ShippingTemplatesNoDeliveryRespVO shippingTemplatesFreeRespVOList, Integer id);
List<ShippingTemplatesNoDeliveryRespVO> getListGroup(Integer tempId);

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.shop.dal.mysql.express.ShippingTemplatesNoDeliver
import cn.iocoder.yudao.module.shop.service.express.ShippingTemplatesNoDeliveryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -36,22 +37,22 @@ public class ShippingTemplatesNoDeliveryServiceImpl extends ServiceImpl<Shipping
* @since 2020-05-20
*/
@Override
public void saveAll(List<ShippingTemplatesNoDeliveryRespVO> shippingTemplatesNoDeliveryRespVOS, Integer tempId) {
public void saveAll(ShippingTemplatesNoDeliveryRespVO shippingTemplatesNoDeliveryRespVOS, Integer tempId) {
ArrayList<ShippingTemplatesNoDeliveryDO> shippingTemplatesNoDeliveryDOS = new ArrayList<>();
delete(tempId);
for (ShippingTemplatesNoDeliveryRespVO shippingTemplatesNoDeliveryRespVO : shippingTemplatesNoDeliveryRespVOS) {
if(shippingTemplatesNoDeliveryRespVO.getCityId().equals("all") || shippingTemplatesNoDeliveryRespVO.getCityId().equals("0")){
cityIdList = getCityIdList();
}else{
cityIdList = StrUtils.stringToArray(shippingTemplatesNoDeliveryRespVO.getCityId());
}
for (Integer cityId: cityIdList) {
ShippingTemplatesNoDeliveryDO shippingTemplatesNoDeliveryDO = new ShippingTemplatesNoDeliveryDO();
shippingTemplatesNoDeliveryDO.setCityId(cityId);
shippingTemplatesNoDeliveryDO.setTempId(tempId);
shippingTemplatesNoDeliveryDOS.add(shippingTemplatesNoDeliveryDO);
}
String uniqueKey = DigestUtils.md5Hex(shippingTemplatesNoDeliveryRespVOS.toString());
if(shippingTemplatesNoDeliveryRespVOS.getCityId().equals("all") || shippingTemplatesNoDeliveryRespVOS.getCityId().equals("0")){
cityIdList = getCityIdList();
}else{
cityIdList = StrUtils.stringToArray(shippingTemplatesNoDeliveryRespVOS.getCityId());
}
for (Integer cityId: cityIdList) {
ShippingTemplatesNoDeliveryDO shippingTemplatesNoDeliveryDO = new ShippingTemplatesNoDeliveryDO();
shippingTemplatesNoDeliveryDO.setCityId(cityId);
shippingTemplatesNoDeliveryDO.setUniqid(uniqueKey);
shippingTemplatesNoDeliveryDO.setTempId(tempId);
shippingTemplatesNoDeliveryDOS.add(shippingTemplatesNoDeliveryDO);
}
//批量保存模板数据
saveBatch(shippingTemplatesNoDeliveryDOS);

View File

@ -78,6 +78,7 @@ public class ShippingTemplatesRegionServiceImpl extends ServiceImpl<ShippingTemp
for (Integer cityId: cityIdList) {
ShippingTemplatesRegionDO shippingTemplatesRegionDO = new ShippingTemplatesRegionDO();
shippingTemplatesRegionDO.setCityId(cityId);
shippingTemplatesRegionDO.setUniqid(uniqueKey);
// shippingTemplatesRegionDO.setTitle(shippingTemplatesRegionRespVO.getTitle());
shippingTemplatesRegionDO.setRenewal(shippingTemplatesRegionRespVO.getRenewal());
shippingTemplatesRegionDO.setRenewalPrice(shippingTemplatesRegionRespVO.getRenewalPrice());

View File

@ -109,12 +109,11 @@ public class ShippingTemplatesServiceImpl extends ServiceImpl<ShippingTemplatesM
shippingTemplatesFreeService.saveAll(shippingTemplatesFreeRespVOList, request.getType(), shippingTemplatesDO.getId());
}
List<ShippingTemplatesNoDeliveryRespVO> shippingTemplatesNoDeliveryRespVOList = request.getShippingTemplatesNoDeliveryRespVOS();
if(null != shippingTemplatesNoDeliveryRespVOList && shippingTemplatesNoDeliveryRespVOList.size() > 0){
shippingTemplatesNoDeliveryService.saveAll(shippingTemplatesNoDeliveryRespVOList, shippingTemplatesDO.getId());
ShippingTemplatesNoDeliveryRespVO shippingTemplatesNoDeliveryRespVO = request.getShippingTemplatesNoDeliveryRespVOS();
if(!ObjectUtil.isNull(shippingTemplatesNoDeliveryRespVO)){
shippingTemplatesNoDeliveryService.saveAll(shippingTemplatesNoDeliveryRespVO, shippingTemplatesDO.getId());
}
return true;
}
@ -169,9 +168,9 @@ public class ShippingTemplatesServiceImpl extends ServiceImpl<ShippingTemplatesM
if(CollUtil.isNotEmpty(shippingTemplatesFreeRespVOList) && request.getAppoint()){
shippingTemplatesFreeService.saveAll(shippingTemplatesFreeRespVOList, request.getType(), shippingTemplatesDO.getId());
}
List<ShippingTemplatesNoDeliveryRespVO> shippingTemplatesNoDeliveryRespVOList = request.getShippingTemplatesNoDeliveryRespVOS();
if(CollUtil.isNotEmpty(shippingTemplatesNoDeliveryRespVOList)){
shippingTemplatesNoDeliveryService.saveAll(shippingTemplatesNoDeliveryRespVOList, shippingTemplatesDO.getId());
ShippingTemplatesNoDeliveryRespVO shippingTemplatesNoDeliveryRespVO= request.getShippingTemplatesNoDeliveryRespVOS();
if(ObjectUtil.isNotNull(shippingTemplatesNoDeliveryRespVO)){
shippingTemplatesNoDeliveryService.saveAll(shippingTemplatesNoDeliveryRespVO, shippingTemplatesDO.getId());
}
return true;

View File

@ -6,7 +6,9 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.member.api.address.AddressApi;
import cn.iocoder.yudao.module.member.api.address.UserAddressApi;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.member.api.address.dto.UserAddressRespDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.shop.constants.PayConstants;
@ -19,14 +21,21 @@ import cn.iocoder.yudao.module.shop.constants.SysConfigConstants;
import cn.iocoder.yudao.module.shop.convert.order.StoreOrderConvert;
import cn.iocoder.yudao.module.shop.convert.order.StoreOrderOneConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.cat.StoreCart;
import cn.iocoder.yudao.module.shop.dal.dataobject.express.ShippingTemplatesDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.express.ShippingTemplatesFreeDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.express.ShippingTemplatesRegionDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrder;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.StoreOrderInfo;
import cn.iocoder.yudao.module.shop.dal.dataobject.product.StoreProduct;
import cn.iocoder.yudao.module.shop.dal.dataobject.product.StoreProductAttrValue;
import cn.iocoder.yudao.module.shop.dal.mysql.express.ShippingTemplatesMapper;
import cn.iocoder.yudao.module.shop.dal.mysql.order.StoreOrderMapper;
import cn.iocoder.yudao.module.shop.request.order.*;
import cn.iocoder.yudao.module.shop.request.product.StoreProductReplyAddRequest;
import cn.iocoder.yudao.module.shop.response.order.*;
import cn.iocoder.yudao.module.shop.service.express.ShippingTemplatesFreeService;
import cn.iocoder.yudao.module.shop.service.express.ShippingTemplatesRegionService;
import cn.iocoder.yudao.module.shop.service.express.ShippingTemplatesService;
import cn.iocoder.yudao.module.shop.service.order.OrderService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderInfoService;
import cn.iocoder.yudao.module.shop.service.order.StoreOrderService;
@ -110,16 +119,18 @@ public class OrderServiceImpl implements OrderService {
@Autowired
private AddressApi addressApi;
@Autowired
private UserAddressApi userAddressApi;
// @Autowired
// private ShippingTemplatesApi shippingTemplatesApi;
//
// @Autowired
// private ShippingTemplatesFreeApi shippingTemplatesFreeApi;
//
// @Autowired
// private ShippingTemplatesRegionApi shippingTemplatesRegionApi;
@Autowired
private ShippingTemplatesService shippingTemplatesApi;
@Autowired
private ShippingTemplatesFreeService shippingTemplatesFreeApi;
@Autowired
private ShippingTemplatesRegionService shippingTemplatesRegionApi;
@Autowired
private StoreProductService storeProductService;
@ -601,116 +612,116 @@ public class OrderServiceImpl implements OrderService {
/**
*
*/
private void getFreightFee(OrderInfoVo orderInfoVo, AddressRespDTO userAddress) {
// // 判断是否满额包邮 type=1按件数 2按重量 3按体积
// // 全场满额包邮开关
// String postageSwitchString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE_SWITCH).toString();
// // 全场满额包邮金额
// String storeFreePostageString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE).toString();
// BigDecimal storePostage = BigDecimal.ZERO;
// if (postageSwitchString.equals("true") && (storeFreePostageString.equals("0") || orderInfoVo.getProTotalFee().compareTo(new BigDecimal(storeFreePostageString)) >= 0)) {
// storePostage = BigDecimal.ZERO;
// } else if (ObjectUtil.isNull(userAddress) || userAddress.getCityId() <= 0) {
// // 用户地址不存在默认运费为0元
// storePostage = BigDecimal.ZERO;
// } else {
// // 有用户地址的情况下
// // 运费根据商品计算
// Map<Integer, MyRecord> proMap = new HashMap<>();
// orderInfoVo.getOrderDetailList().forEach(e -> {
// Integer proId = e.getProductId();
// if (proMap.containsKey(proId)) {
// MyRecord record = proMap.get(proId);
// record.set("totalPrice", record.getBigDecimal("totalPrice").add(e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum()))));
// record.set("totalNum", record.getInt("totalNum") + e.getPayNum());
// BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
// record.set("weight", record.getBigDecimal("weight").add(weight));
// BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
// record.set("volume", record.getBigDecimal("volume").add(volume));
// } else {
// MyRecord record = new MyRecord();
// record.set("totalPrice", e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum())));
// record.set("totalNum", e.getPayNum());
// record.set("tempId", e.getTempId());
// record.set("proId", proId);
// BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
// record.set("weight", weight);
// BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
// record.set("volume", volume);
//
// proMap.put(proId, record);
// }
// });
//
// // 指定包邮(单品运费模板)> 指定区域配送(单品运费模板)
// int cityId = userAddress.getCityId();
//
// for (Map.Entry<Integer, MyRecord> m : proMap.entrySet()) {
// MyRecord value = m.getValue();
// Integer tempId = value.getInt("tempId");
// ShippingTemplatesDO shippingTemplatesDO = shippingTemplatesApi.getById(tempId);
// if (shippingTemplatesDO.getAppoint()) {// 指定包邮
// // 判断是否在指定包邮区域内
// // 必须满足件数 + 金额 才能包邮
// ShippingTemplatesFreeDO shippingTemplatesFree = shippingTemplatesFreeApi.getByTempIdAndCityId(tempId, cityId);
// if (ObjectUtil.isNotNull(shippingTemplatesFree)) { // 在包邮区域内
// BigDecimal freeNum = shippingTemplatesFree.getNumber();
// BigDecimal multiply = value.getBigDecimal("totalPrice");
// if (new BigDecimal(value.getInt("totalNum")).compareTo(freeNum) >= 0 && multiply.compareTo(shippingTemplatesFree.getPrice()) >= 0) {
// // 满足件数 + 金额 = 包邮
// continue;
// }
// }
// }
// // 不满足指定包邮条件,走指定区域配送
// ShippingTemplatesRegionDO shippingTemplatesRegion = shippingTemplatesRegionApi.getByTempIdAndCityId(tempId, cityId);
// if (ObjectUtil.isNull(shippingTemplatesRegion)) {
// throw new ServiceException("计算运费时,未找到全国运费配置");
// }
//
// // 判断计费方式:件数、重量、体积
// switch (shippingTemplatesDO.getType()) {
// case 1: // 件数
// // 判断件数是否超过首件
// Integer num = value.getInt("totalNum");
// if (num <= shippingTemplatesRegion.getFirst().intValue()) {
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
// } else {// 超过首件的需要计算续件
// int renewalNum = num - shippingTemplatesRegion.getFirst().intValue();
// // 剩余件数/续件 = 需要计算的续件费用的次数
// BigDecimal divide = new BigDecimal(renewalNum).divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
// BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
// }
// break;
// case 2: // 重量
// BigDecimal weight = value.getBigDecimal("weight");
// if (weight.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
// } else {// 超过首件的需要计算续件
// BigDecimal renewalNum = weight.subtract(shippingTemplatesRegion.getFirst());
// // 剩余件数/续件 = 需要计算的续件费用的次数
// BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
// BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
// }
// break;
// case 3: // 体积
// BigDecimal volume = value.getBigDecimal("volume");
// if (volume.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
// } else {// 超过首件的需要计算续件
// BigDecimal renewalNum = volume.subtract(shippingTemplatesRegion.getFirst());
// // 剩余件数/续件 = 需要计算的续件费用的次数
// BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
// BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
// storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
// }
// break;
// }
// }
// }
// orderInfoVo.setFreightFee(storePostage);
private void getFreightFee(OrderInfoVo orderInfoVo, UserAddressRespDTO userAddress) {
// 判断是否满额包邮 type=1按件数 2按重量 3按体积
// 全场满额包邮开关
String postageSwitchString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE_SWITCH).toString();
// 全场满额包邮金额
String storeFreePostageString = apiConfigApi.getConfigKey(SysConfigConstants.STORE_FEE_POSTAGE).toString();
BigDecimal storePostage = BigDecimal.ZERO;
if (postageSwitchString.equals("true") && (storeFreePostageString.equals("0") || orderInfoVo.getProTotalFee().compareTo(new BigDecimal(storeFreePostageString)) >= 0)) {
storePostage = BigDecimal.ZERO;
} else if (ObjectUtil.isNull(userAddress) || userAddress.getCityId() <= 0) {
// 用户地址不存在默认运费为0元
storePostage = BigDecimal.ZERO;
} else {
// 有用户地址的情况下
// 运费根据商品计算
Map<Integer, MyRecord> proMap = new HashMap<>();
orderInfoVo.getOrderDetailList().forEach(e -> {
Integer proId = e.getProductId();
if (proMap.containsKey(proId)) {
MyRecord record = proMap.get(proId);
record.set("totalPrice", record.getBigDecimal("totalPrice").add(e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum()))));
record.set("totalNum", record.getInt("totalNum") + e.getPayNum());
BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
record.set("weight", record.getBigDecimal("weight").add(weight));
BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
record.set("volume", record.getBigDecimal("volume").add(volume));
} else {
MyRecord record = new MyRecord();
record.set("totalPrice", e.getPrice().multiply(BigDecimal.valueOf(e.getPayNum())));
record.set("totalNum", e.getPayNum());
record.set("tempId", e.getTempId());
record.set("proId", proId);
BigDecimal weight = e.getWeight().multiply(BigDecimal.valueOf(e.getPayNum()));
record.set("weight", weight);
BigDecimal volume = e.getVolume().multiply(BigDecimal.valueOf(e.getPayNum()));
record.set("volume", volume);
proMap.put(proId, record);
}
});
// 指定包邮(单品运费模板)> 指定区域配送(单品运费模板)
int cityId = userAddress.getCityId();
for (Map.Entry<Integer, MyRecord> m : proMap.entrySet()) {
MyRecord value = m.getValue();
Integer tempId = value.getInt("tempId");
ShippingTemplatesDO shippingTemplatesDO = shippingTemplatesApi.getById(tempId);
if (shippingTemplatesDO.getAppoint()) {// 指定包邮
// 判断是否在指定包邮区域内
// 必须满足件数 + 金额 才能包邮
ShippingTemplatesFreeDO shippingTemplatesFree = shippingTemplatesFreeApi.getByTempIdAndCityId(tempId, cityId);
if (ObjectUtil.isNotNull(shippingTemplatesFree)) { // 在包邮区域内
BigDecimal freeNum = shippingTemplatesFree.getNumber();
BigDecimal multiply = value.getBigDecimal("totalPrice");
if (new BigDecimal(value.getInt("totalNum")).compareTo(freeNum) >= 0 && multiply.compareTo(shippingTemplatesFree.getPrice()) >= 0) {
// 满足件数 + 金额 = 包邮
continue;
}
}
}
// 不满足指定包邮条件,走指定区域配送
ShippingTemplatesRegionDO shippingTemplatesRegion = shippingTemplatesRegionApi.getByTempIdAndCityId(tempId, cityId);
if (ObjectUtil.isNull(shippingTemplatesRegion)) {
throw new ServiceException("计算运费时,未找到全国运费配置");
}
// 判断计费方式:件数、重量、体积
switch (shippingTemplatesDO.getType()) {
case 1: // 件数
// 判断件数是否超过首件
Integer num = value.getInt("totalNum");
if (num <= shippingTemplatesRegion.getFirst().intValue()) {
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
} else {// 超过首件的需要计算续件
int renewalNum = num - shippingTemplatesRegion.getFirst().intValue();
// 剩余件数/续件 = 需要计算的续件费用的次数
BigDecimal divide = new BigDecimal(renewalNum).divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
}
break;
case 2: // 重量
BigDecimal weight = value.getBigDecimal("weight");
if (weight.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
} else {// 超过首件的需要计算续件
BigDecimal renewalNum = weight.subtract(shippingTemplatesRegion.getFirst());
// 剩余件数/续件 = 需要计算的续件费用的次数
BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
}
break;
case 3: // 体积
BigDecimal volume = value.getBigDecimal("volume");
if (volume.compareTo(shippingTemplatesRegion.getFirst()) <= 0) {
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice());
} else {// 超过首件的需要计算续件
BigDecimal renewalNum = volume.subtract(shippingTemplatesRegion.getFirst());
// 剩余件数/续件 = 需要计算的续件费用的次数
BigDecimal divide = renewalNum.divide(shippingTemplatesRegion.getRenewal(), 0, BigDecimal.ROUND_UP);
BigDecimal renewalPrice = shippingTemplatesRegion.getRenewalPrice().multiply(divide);
storePostage = storePostage.add(shippingTemplatesRegion.getFirstPrice()).add(renewalPrice);
}
break;
}
}
}
orderInfoVo.setFreightFee(storePostage);
}
/**
@ -740,22 +751,22 @@ public class OrderServiceImpl implements OrderService {
int orderProNum = orderInfoVo.getOrderDetailList().stream().mapToInt(OrderInfoDetailVo::getPayNum).sum();
orderInfoVo.setOrderProNum(orderProNum);
// 获取默认地址
AddressRespDTO userAddress = addressApi.getDefaultByUid(user.getId());
UserAddressRespDTO userAddress = userAddressApi.getDefaultByUid(user.getId());
if (ObjectUtil.isNotNull(userAddress)) {
// 计算运费
getFreightFee(orderInfoVo, userAddress);
orderInfoVo.setAddressId(userAddress.getId());
orderInfoVo.setRealName(userAddress.getName());
orderInfoVo.setPhone(userAddress.getMobile());
orderInfoVo.setRealName(userAddress.getRealName());
orderInfoVo.setPhone(userAddress.getPhone());
orderInfoVo.setProvince(userAddress.getProvince());
orderInfoVo.setCity(userAddress.getCity());
orderInfoVo.setDistrict(userAddress.getDistrict());
orderInfoVo.setDetail(userAddress.getDetailAddress());
orderInfoVo.setDetail(userAddress.getDetail());
} else {
orderInfoVo.setFreightFee(BigDecimal.ZERO);
}
// 实际支付金额
orderInfoVo.setPayFee(orderInfoVo.getProTotalFee().add(orderInfoVo.getFreightFee()));
orderInfoVo.setPayFee(orderInfoVo.getProTotalFee().add(BigDecimal.ZERO));
//用户剩余积分
//用户剩余经验
// 缓存订单
@ -1033,7 +1044,7 @@ public class OrderServiceImpl implements OrderService {
// 快递配送,无地址
priceResponse.setFreightFee(BigDecimal.ZERO);
} else {// 快递配送,有地址
AddressRespDTO userAddress = addressApi.getById(request.getAddressId());
UserAddressRespDTO userAddress = userAddressApi.getById(request.getAddressId());
if (ObjectUtil.isNull(userAddress)) {
priceResponse.setFreightFee(BigDecimal.ZERO);
} else {
@ -1041,7 +1052,7 @@ public class OrderServiceImpl implements OrderService {
priceResponse.setFreightFee(orderInfoVo.getFreightFee());
}
}
// 计算优惠券金额
// 计算优惠券金额 现在不开启优惠卷功能
// if (orderInfoVo.getProTotalFee().compareTo(storeCouponUser.getMoney()) <= 0) {
// priceResponse.setCouponFee(orderInfoVo.getProTotalFee());
@ -1056,6 +1067,7 @@ public class OrderServiceImpl implements OrderService {
// priceResponse.setCouponFee(storeCouponUser.getMoney());
// }
priceResponse.setProTotalFee(orderInfoVo.getProTotalFee());
// 积分部分
// 使用积分
@ -1118,13 +1130,13 @@ public class OrderServiceImpl implements OrderService {
String userAddressStr = "";
if (orderRequest.getShippingType() == 1) { // 快递配送
if (orderRequest.getAddressId() <= 0) throw new ServiceException("请选择收货地址");
AddressRespDTO userAddress = addressApi.getById(orderRequest.getAddressId());
if (ObjectUtil.isNull(userAddress) || userAddress.getDeleted()) {
UserAddressRespDTO userAddress = userAddressApi.getById(orderRequest.getAddressId());
if (ObjectUtil.isNull(userAddress)) {
throw new ServiceException("收货地址有误");
}
orderRequest.setRealName(userAddress.getName());
orderRequest.setPhone(userAddress.getMobile());
userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetailAddress();
orderRequest.setRealName(userAddress.getRealName());
orderRequest.setPhone(userAddress.getPhone());
userAddressStr = userAddress.getProvince() + userAddress.getCity() + userAddress.getDistrict() + userAddress.getDetail();
}else if (orderRequest.getShippingType() == 2) { // 到店自提
if (StringUtils.isBlank(orderRequest.getRealName()) || StringUtils.isBlank(orderRequest.getPhone())) {
throw new ServiceException("请填写姓名和电话");
@ -1249,7 +1261,7 @@ public class OrderServiceImpl implements OrderService {
storeOrder.setStoreId(orderRequest.getStoreId());
}
storeOrder.setTotalNum(orderInfoVo.getOrderProNum());
storeOrder.setCouponId(Optional.ofNullable(orderRequest.getCouponId()).orElse(0));
storeOrder.setCouponId(Optional.ofNullable(orderRequest.getCouponId()).orElse(0L));
// 订单总价
BigDecimal totalPrice = computedOrderPriceResponse.getProTotalFee().add(computedOrderPriceResponse.getFreightFee());

View File

@ -62,14 +62,16 @@ public class RechargeOrderServiceImpl implements RechargeOrderService {
RechargeOrderDO updateObj = RechargeOrderConvert.INSTANCE.convert(updateReqVO);
rechargeOrderMapper.updateById(updateObj);
}
@Override
public void updateRechargeOrderStatus(RechargeOrderUpdateReqVO updateReqVO) {
// 校验存在
validateRechargeOrderExists(updateReqVO.getId());
// 更新
RechargeOrderDO updateObj = RechargeOrderConvert.INSTANCE.convert(updateReqVO);
RechargeOrderDO updateObj = RechargeOrderConvert.INSTANCE.convert(updateReqVO);
rechargeOrderMapper.updateById(updateObj);
}
@Override
public void deleteRechargeOrder(Long id) {
// 校验存在
@ -97,7 +99,7 @@ public class RechargeOrderServiceImpl implements RechargeOrderService {
@Override
public PageResult<RechargeOrderRespVO> getRechargeOrderPage(RechargeOrderPageReqVO pageReqVO) {
Page<RechargeOrderRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
rechargeOrderMapper.findListPage(page,pageReqVO);
rechargeOrderMapper.findListPage(page, pageReqVO);
return new PageResult<>(page.getRecords(), page.getTotal());
}
@ -148,23 +150,22 @@ public class RechargeOrderServiceImpl implements RechargeOrderService {
public MemberHeadResponse memberHeadInfo() {
MemberHeadResponse response = new MemberHeadResponse();
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if(loginUser!=null){
List<RechargeOrderDO> orderDOS = rechargeOrderMapper.selectList(Wrappers.<RechargeOrderDO>lambdaQuery().eq(RechargeOrderDO::getUid, loginUser.getId()));
if (!CollectionUtils.isEmpty(orderDOS)) {
BigDecimal amount = new BigDecimal("0");
for (RechargeOrderDO orderDO : orderDOS) {
amount = amount.add(orderDO.getPayPrice());
}
if (amount.compareTo(new BigDecimal("640")) < 0) {
response.setGrade("普通会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "640");
} else if (amount.compareTo(new BigDecimal("640")) >= 0) {
response.setGrade("高级会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "1040");
} else {
response.setGrade("中级会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "1040");
}
Assert.notNull(loginUser, "登录失效,请重新登录!");
List<RechargeOrderDO> orderDOS = rechargeOrderMapper.selectList(Wrappers.<RechargeOrderDO>lambdaQuery().eq(RechargeOrderDO::getUid, loginUser.getId()).eq(RechargeOrderDO::getPaid, 1));
if (!CollectionUtils.isEmpty(orderDOS)) {
BigDecimal amount = new BigDecimal("0");
for (RechargeOrderDO orderDO : orderDOS) {
amount = amount.add(orderDO.getPayPrice());
}
if (amount.compareTo(new BigDecimal("640")) < 0) {
response.setGrade("普通会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "640");
} else if (amount.compareTo(new BigDecimal("1040")) >= 0) {
response.setGrade("高级会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "1040");
} else {
response.setGrade("中级会员");
response.setIntegral(amount.stripTrailingZeros().toPlainString() + "/" + "1040");
}
}
return response;

View File

@ -106,13 +106,13 @@ public class OrderUtil {
payType = payType.toLowerCase();
switch (payType){
case PayConstants.PAY_TYPE_WE_CHAT:
result = apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_PAY_WEIXIN_OPEN).equals("1");
result = apiConfigApi.getConfigKeyValue(SysConfigConstants.CONFIG_PAY_WEIXIN_OPEN).equals("1");
break;
case PayConstants.PAY_TYPE_YUE:
result = (apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_YUE_PAY_STATUS).equals("1"));
result = (apiConfigApi.getConfigKeyValue(SysConfigConstants.CONFIG_YUE_PAY_STATUS).equals("1"));
break;
case PayConstants.PAY_TYPE_ALI_PAY:
result = (apiConfigApi.getConfigKey(SysConfigConstants.CONFIG_ALI_PAY_STATUS).equals("1"));
result = (apiConfigApi.getConfigKeyValue(SysConfigConstants.CONFIG_ALI_PAY_STATUS).equals("1"));
break;
}
return result;

View File

@ -3,6 +3,6 @@
<mapper namespace="cn.iocoder.yudao.module.shop.dal.mysql.express.ShippingTemplatesFreeMapper">
<select id="getListGroup" resultType="cn.iocoder.yudao.module.shop.controller.admin.express.vo.ShippingTemplatesFreeRespVO" parameterType="integer">
SELECT group_concat(`city_id`) AS city_id, province_id, `number`, price FROM eb_shipping_templates_free where temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `id` ORDER BY id ASC
SELECT group_concat(`city_id`) AS city_id, province_id, `number`, price, uniqid FROM eb_shipping_templates_free where temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `uniqid`,id ORDER BY id ASC
</select>
</mapper>

View File

@ -3,6 +3,6 @@
<mapper namespace="cn.iocoder.yudao.module.shop.dal.mysql.express.ShippingTemplatesNoDeliveryMapper">
<select id="getList" resultType="cn.iocoder.yudao.module.shop.controller.admin.express.vo.ShippingTemplatesNoDeliveryRespVO" parameterType="integer">
SELECT group_concat(`city_id`) AS city_id, province_id FROM eb_shipping_templates_no_delivery WHERE temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `id` ORDER BY id ASC
SELECT group_concat(`city_id`) AS city_id, province_id, uniqid FROM eb_shipping_templates_no_delivery WHERE temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `uniqid`,id ORDER BY id ASC
</select>
</mapper>

View File

@ -3,6 +3,6 @@
<mapper namespace="cn.iocoder.yudao.module.shop.dal.mysql.express.ShippingTemplatesRegionMapper">
<select id="getListGroup" resultType="cn.iocoder.yudao.module.shop.controller.admin.express.vo.ShippingTemplatesRegionRespVO" parameterType="integer">
SELECT group_concat(`city_id`) AS city_id, `first`, first_price, `renewal`, renewal_price FROM eb_shipping_templates_region where temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `id` ORDER BY id ASC
SELECT group_concat(`city_id`) AS city_id, province_id, `first`, first_price, `renewal`, renewal_price, uniqid FROM eb_shipping_templates_region where temp_id = #{tempId, jdbcType=INTEGER} GROUP BY `uniqid`,id ORDER BY id ASC
</select>
</mapper>

View File

@ -19,7 +19,7 @@ public interface AddressApi {
AddressRespDTO getAddress(Long id, Long userId);
AddressRespDTO getById(Integer addressId);
AddressRespDTO getById(Long addressId);
/**
*

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.member.api.address;
import cn.iocoder.yudao.module.member.api.address.dto.UserAddressRespDTO;
/**
* @Title:UserAddressApi
* @Description: TODO
* @author: tangqian
* @date: 2023/5/24 14:39
* @version: V1.0.0
*/
public interface UserAddressApi {
UserAddressRespDTO getById(Long addressId);
/**
*
* @return UserAddress
*/
UserAddressRespDTO getDefaultByUid(Long uid);
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.member.api.address.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
/**
* @Title:UserAddressRespDTO
* @Description: TODO
* @author: tangqian
* @date: 2023/5/24 14:46
* @version: V1.0.0
*/
@Data
public class UserAddressRespDTO {
private Long id;
private Long userId;
private String realName;
private String phone;
private String province;
private String city;
private Integer cityId;
private String district;
private String detail;
private Integer postCode;
private String longitude;
private String latitude;
private Boolean isDefault;
}

View File

@ -36,7 +36,7 @@ public class AddressApiImpl implements AddressApi {
}
@Override
public AddressRespDTO getById(Integer addressId) {
public AddressRespDTO getById(Long addressId) {
LambdaQueryWrapper<AddressDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(AddressDO::getId, addressId);
return AddressConvert.INSTANCE.convert02(addressMapper.selectOne(lambdaQueryWrapper));

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.member.api.address;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.member.api.address.dto.UserAddressRespDTO;
import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
import cn.iocoder.yudao.module.member.dal.dataobject.address.UserAddress;
import cn.iocoder.yudao.module.member.dal.mysql.address.UserAddressMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
/**
* @Title:UserAddressApiImpl
* @Description: TODO
* @author: tangqian
* @date: 2023/5/24 14:40
* @version: V1.0.0
*/
@Service
@Validated
public class UserAddressApiImpl implements UserAddressApi{
@Autowired
private UserAddressMapper addressMapper;
@Override
public UserAddressRespDTO getById(Long addressId) {
UserAddressRespDTO respDTO = new UserAddressRespDTO();
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserAddress::getId, addressId);
UserAddress userAddress = addressMapper.selectOne(lambdaQueryWrapper);
BeanUtils.copyProperties(userAddress,respDTO);
return respDTO;
}
@Override
public UserAddressRespDTO getDefaultByUid(Long uid) {
UserAddressRespDTO respDTO = new UserAddressRespDTO();
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(UserAddress::getIsDefault, true);
lambdaQueryWrapper.eq(UserAddress::getUserId, uid);
UserAddress userAddress = addressMapper.selectOne(lambdaQueryWrapper);
if (null != userAddress) {
BeanUtils.copyProperties(userAddress,respDTO);
}
return respDTO;
}
}

View File

@ -134,7 +134,7 @@ public class MemberUserApiImpl implements MemberUserApi {
throw new ServiceException("用户信息不存在!");
}
if (user.getStatus() == 0) {
if (user.getStatus() == 1) {
throw new ServiceException("用户已经被禁用!");
}
return user;

View File

@ -6,7 +6,7 @@ VUE_APP_TITLE = 创盈商户管理系统
# 芋道管理系统/开发环境
#VUE_APP_BASE_API = 'https://cmx.bskies.cc:8000/cyywl-api'
VUE_APP_BASE_API = 'http://192.168.1.188:48080'
VUE_APP_BASE_API = 'http://api.cyywl.top'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -355,7 +355,7 @@ const defaultObj = {
isGood: false,
isHot: false,
isBest: false,
tempId: '111',
tempId: '',
attrValue: [{
image: '',
price: 0,
@ -819,7 +819,7 @@ export default {
//
getShippingList() {
shippingTemplatesList(this.tempData).then(res => {
this.shippingList = res.list
this.shippingList = res.data.list
})
},
showInput(item) {

View File

@ -59,13 +59,11 @@
/>
<el-table-column label="商品图" min-width="80">
<template slot-scope="scope">
<div class="demo-image__preview">
<el-image
style="width: 36px; height: 36px"
:src="scope.row.image"
:preview-src-list="[scope.row.image]"
/>
</div>
</template>
</el-table-column>
<el-table-column label="商品名称"

View File

@ -1,14 +1,14 @@
// let domain = 'http://yuxy.perrymake.com'
let domain = 'http://192.168.1.188:48080'
let domain = 'http://api.cyywl.top'
// let domain = 'http://192.168.1.188:48080'
module.exports = {
// 请求域名 格式: https://您的域名
// #ifdef MP
HTTP_REQUEST_URL: domain,
// #endif
// HTTP_ADMIN_URL:'http://yuxy.perrymake.com', //PC后台的API请求地址上传图片用
HTTP_ADMIN_URL:'http://192.168.1.188:48080', //PC后台的API请求地址上传图片用
HTTP_ADMIN_URL:'http://api.cyywl.top', //PC后台的API请求地址上传图片用
// HTTP_ADMIN_URL:'http://192.168.1.188:48080', //PC后台的API请求地址上传图片用
// #ifdef H5
//H5接口是浏览器地址
// HTTP_REQUEST_URL: window.location.protocol+"//"+window.location.host,

View File

@ -1,9 +1,353 @@
{
"name": "yudao-ui-app",
"version": "1.0.0",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "yudao-ui-app",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"clipboard": "^2.0.11",
"html-to-image": "^1.11.11",
"qrcode": "^1.5.3"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"engines": {
"node": ">=6"
}
},
"node_modules/clipboard": {
"version": "2.0.11",
"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
"integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
"dependencies": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
},
"node_modules/dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/encode-utf8": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
"dependencies": {
"delegate": "^3.1.2"
}
},
"node_modules/html-to-image": {
"version": "1.11.11",
"resolved": "https://registry.npmmirror.com/html-to-image/-/html-to-image-1.11.11.tgz",
"integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA=="
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"engines": {
"node": ">=8"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"engines": {
"node": ">=8"
}
},
"node_modules/pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/qrcode": {
"version": "1.5.3",
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
"dependencies": {
"dijkstrajs": "^1.0.1",
"encode-utf8": "^1.0.3",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"bin": {
"qrcode": "bin/qrcode"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"node_modules/select": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
}
},
"dependencies": {
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"clipboard": {
"version": "2.0.11",
"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
@ -14,11 +358,68 @@
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
},
"dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"encode-utf8": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
@ -27,15 +428,155 @@
"delegate": "^3.1.2"
}
},
"html-to-image": {
"version": "1.11.11",
"resolved": "https://registry.npmmirror.com/html-to-image/-/html-to-image-1.11.11.tgz",
"integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"requires": {
"p-locate": "^4.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"requires": {
"p-limit": "^2.2.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
},
"pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
},
"qrcode": {
"version": "1.5.3",
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
"requires": {
"dijkstrajs": "^1.0.1",
"encode-utf8": "^1.0.3",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
},
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
}
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
}

View File

@ -10,6 +10,8 @@
"author": "",
"license": "ISC",
"dependencies": {
"clipboard": "^2.0.11"
"clipboard": "^2.0.11",
"html-to-image": "^1.11.11",
"qrcode": "^1.5.3"
}
}

View File

@ -251,22 +251,9 @@
if (!that.orderId) return that.$util.Tips({
title: '请选择要支付的订单'
});
if (paytype == 'yue' && parseFloat(number) < parseFloat(that.payPriceShow)) return that.$util.Tips({
title: `余额不足`
});
uni.showLoading({
title: `支付中`
});
if (paytype == 'friend' && that.orderId) {
uni.hideLoading();
return uni.navigateTo({
url: '/pages/users/payment_on_behalf/index?order_id=' + that.orderId + '&spread=' +
this.$store.state.app.uid,
success: res => {},
fail: () => {},
complete: () => {}
});
}
orderPay({
uni: that.orderId,
paytype: paytype,

View File

@ -92,7 +92,7 @@
<u-icon slot="icon" size="45" name="/static/images/user_icon1.png"></u-icon>
</u-cell>
<u-cell title="分销中心" v-if="userInfo.userType === 'PROMOTER'" isLink
@click="jumpPage('/pages/users/user_spread_user/index')">
@click="jumpPage('/pages/users/user_spread_code/index')">
<u-icon slot="icon" size="45" name="/static/images/user_icon2.png"></u-icon>
</u-cell>
<u-cell title="热线电话" value="023-12948338" :value="tenantInfo.serviceMobile" isLink>
@ -255,8 +255,8 @@
})
},
kefuClick() {
if (tenantInfo.wxKfUrl) {
location.href = tenantInfo.wxKfUrl
if (this.tenantInfo.wxKfUrl) {
location.href = this.tenantInfo.wxKfUrl
}
},
getOrderData() {

View File

@ -1,430 +1,222 @@
<template>
<view style="height: 100%;">
<view class='distribution-posters'>
<swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :circular="circular" :interval="interval"
:duration="duration" @change="bindchange" previous-margin="40px" next-margin="40px">
<block v-for="(item,index) in spreadList" :key="index">
<swiper-item>
<image :src="item.pic" class="slide-image" :class="swiperIndex == index ? 'active' : 'quiet'"
mode='aspectFill' />
</swiper-item>
</block>
</swiper>
<!-- #ifdef MP -->
<view class='keep bg-color' @click='savePosterPath'>保存海报</view>
<!-- #endif -->
<!-- #ifndef MP -->
<div class="preserve acea-row row-center-wrapper">
<div class="line"></div>
<div class="tip">长按保存图片</div>
<div class="line"></div>
</div>
<!-- #endif -->
</view>
<!-- #ifdef MP -->
<!-- <authorize @onLoadFun="onLoadFun" :isAuto="isAuto" :isShowAuth="isShowAuth" @authColse="authColse"></authorize> -->
<!-- #endif -->
<view class="canvas" v-if="canvasStatus">
<canvas style="width:750px;height:1190px;" canvas-id="canvasOne"></canvas>
<canvas canvas-id="qrcode" :style="{width: `${qrcodeSize}px`, height: `${qrcodeSize}px`}" />
<view class="main-page">
<image :src="posterUrl" style="width:100%;height:100%;" mode="scaleToFill" v-show="posterUrl"></image>
<view class="spread-wrap" id="poster-wrap" v-show="!posterUrl">
<view class="logo-wrap">
<image :src="tenantInfo.logo" class="logo-image"></image>
</view>
<view class="activity-wrap" v-show="activityList.length > 0">
<view class="item-wrap" :key="index" v-for="(item, index) in activityList">
<view class="text">办理会员{{item.gearAmount}}</view>
<view class="text">可享一年返回<span>{{item.refundAmount}}</span>话费</view>
</view>
<view class="tips">
三个活动可同时参与每个手机号仅限一次最高可反1920元话费
</view>
<view class="service-phone">{{tenantInfo.serviceMobile}}</view>
<view class="tenant-info-wrap">
<view class="info-wrap">
<view class="info">
<view class="name">{{userInfo.nickname}}</view>
<view class="phone">{{userInfo.mobile}}</view>
<view class="address">
{{userInfo.parentDeptName}}
</view>
</view>
<view class="qrcode-wrap">
<canvas id="qrcode" style="width:132rpx;height:132rpx;"></canvas>
</view>
</view>
<u-button class="logon" @click="downImage" v-show="!isHideBtn"></u-button>
</view>
</view>
</view>
</view>
</template>
<script>
// #ifdef H5
import uQRCode from '@/js_sdk/Sansnn-uQRCode/uqrcode.js'
// #endif
import {
getUserInfo,
spreadBanner
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
memberGradeInfo
} from '@/api/member.js';
import {
mapGetters
} from "vuex";
// #ifdef MP
import {
base64src
} from '@/utils/base64src.js'
import authorize from '@/components/Authorize';
import {
getQrcode
} from '@/api/api.js';
// #endif
import home from '@/components/home';
import {
imageBase64
} from "@/api/public";
import appConfig from '@/config/app.js'
import QRCode from 'qrcode'
import * as htmlToImage from 'html-to-image'
export default {
components: {
// #ifdef MP
authorize,
// #endif
home
},
data() {
return {
imgUrls: [],
indicatorDots: false,
circular: false,
autoplay: false,
interval: 3000,
duration: 500,
swiperIndex: 0,
spreadList: [],
poster: '',
isAuto: false, //
isShowAuth: false, //
qrcodeSize: 3000,
PromotionCode: '',
base64List: [],
canvasStatus: true //
activityList: [],
posterUrl: '',
isHideBtn: false
};
},
computed: mapGetters(['isLogin', 'uid', 'userInfo','tenantId']),
// watch: {
// isLogin: {
// handler: function(newV, oldV) {
// if (newV) {
// this.userSpreadBannerList();
// }
// },
// deep: true
// }
// },
computed: mapGetters(['isLogin', 'uid', 'userInfo', 'tenantId', 'tenantInfo']),
onLoad() {
if (this.isLogin) {
this.userSpreadBannerList();
if (!this.isLogin) {
toLogin()
} else {
toLogin();
this.getActivityInfo()
}
},
/**
* 用户点击右上角分享
*/
// #ifdef MP
onShareAppMessage: function() {
return {
title: this.userInfo.nickname + '-分销海报',
imageUrl: this.spreadList[0].pic,
path: '/pages/index/index?spid=' + this.uid,
};
},
// #endif
onReady() {},
methods: {
userSpreadBannerList: function() {
let that = this;
downImage() {
const that = this
uni.showLoading({
title: '获取中',
mask: true,
})
spreadBanner({
page: 1,
limit: 5
}).then(res => {
uni.hideLoading();
const list = res.data.map((item) => item.pic)
that.$set(that, 'spreadList', res.data);
that.$set(that, 'base64List', list);
that.make();
// that.getImageBase64(res.data);
}).catch(err => {
uni.hideLoading();
});
},
getImageBase64: function(images) {
uni.showLoading({
title: '海报生成中',
title: '生成海报中',
mask: true
});
let that = this;
// #ifdef H5
let spreadList = []
// Promise
images.forEach(item => {
const oneApi = imageBase64(item.pic).then(res => {
return res.data.code;
that.isHideBtn = true
htmlToImage.toJpeg(document.getElementById('poster-wrap'), {
quality: 0.95,
cacheBust: true
})
spreadList.push(oneApi)
})
Promise.all(spreadList).then(result => {
console.log('result', result)
that.$set(that, 'base64List', result);
that.make();
that.setShareInfoStatus();
})
// #endif
// #ifdef MP
that.base64List = images.map(item => {
return item.pic
});
// #endif
// #ifdef MP
that.getQrcode();
// #endif
},
//
getQrcode() {
let that = this;
let data = {
pid: that.uid,
path: 'pages/index/index'
}
let arrImagesUrl = "";
uni.downloadFile({
url: this.base64List[0],
success: (res) => {
arrImagesUrl = res.tempFilePath;
}
});
getQrcode(data).then(res => {
base64src(res.data.code, res => {
that.PromotionCode = res;
.then(function(dataUrl) {
console.log('dataUrl', dataUrl)
uni.hideLoading()
that.posterUrl = dataUrl
that.$util.Tips({
title: '生成成功,长按保存图片'
})
});
setTimeout(() => {
that.PosterCanvas(arrImagesUrl, that.PromotionCode, that.userInfo.nickname, 0);
}, 300);
}).catch(err => {
uni.hideLoading();
that.$util.Tips({
title: err
});
that.$set(that, 'canvasStatus', false);
});
},
//
make() {
let that = this;
let href = '';
// href = window.location.href.split('/pages')[0];
const url =`${appConfig.SPREAD_DOMAIN}${appConfig.SPREAD_LINK}?redirectUrl=${appConfig.SPREAD_DOMAIN}&tenantId=${that.tenantId}&spreadId=${that.uid}`
const url =
`${appConfig.SPREAD_DOMAIN}${appConfig.SPREAD_LINK}?redirectUrl=${appConfig.SPREAD_DOMAIN}&tenantId=${that.tenantId}&spreadId=${that.uid}`
console.log('url', url)
uQRCode.make({
canvasId: 'qrcode',
// text: href + '/pages/index/index?spreadId=' + that.uid,
text: url,
size: this.qrcodeSize,
margin: 10,
success: res => {
that.PromotionCode = res;
setTimeout(() => {
that.PosterCanvas(this.base64List[0], that.PromotionCode, that.userInfo
.nickname, 0);
}, 300);
},
complete: (res) => {},
fail: res => {
uni.hideLoading();
that.$util.Tips({
title: '海报二维码生成失败!'
});
}
QRCode.toCanvas(document.getElementById('qrcode').querySelector('canvas'), url, {
scale: 1.5
}, function(error) {
console.log(error)
})
},
PosterCanvas: function(arrImages, code, nickname, index) {
let context = uni.createCanvasContext('canvasOne')
context.clearRect(0, 0, 0, 0);
let that = this;
console.log('arrImages', arrImages)
uni.getImageInfo({
src: arrImages,
success: function(res) {
context.drawImage(arrImages, 0, 0, 750, 1190);
context.save();
context.drawImage(code, 110, 700, 300, 300);
context.restore();
context.setFontSize(28);
context.fillText(nickname, 270, 980);
context.fillText('邀请您加入', 270, 1020);
setTimeout(() => {
context.draw(true, function() {
uni.canvasToTempFilePath({
destWidth: 750,
destHeight: 1190,
canvasId: 'canvasOne',
fileType: 'jpg',
success: function(res) {
// H5tempFilePath base64
uni.hideLoading();
that.spreadList[index].pic = res
.tempFilePath;
that.$set(that, 'poster', res
.tempFilePath);
that.$set(that, 'canvasStatus', false);
}
})
})
}, 100);
},
fail: function(err) {
uni.hideLoading();
that.$util.Tips({
title: '无法获取图片信息'
});
}
});
},
onLoadFun: function(e) {
this.$set(this, 'userInfo', e);
this.userSpreadBannerList();
},
//
authColse: function(e) {
this.isShowAuth = e
},
bindchange(e) {
let base64List = this.base64List;
let index = e.detail.current;
this.swiperIndex = index;
let arrImagesUrl = "";
uni.downloadFile({
url: base64List[index],
success: (res) => {
arrImagesUrl = res.tempFilePath;
setTimeout(() => {
this.$set(this, 'canvasStatus', true);
this.PosterCanvas(arrImagesUrl, this.PromotionCode, this.userInfo.nickname,
index);
}, 300);
}
});
},
//
savePosterPath: function() {
let that = this;
uni.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
uni.saveImageToPhotosAlbum({
filePath: that.poster,
success: function(res) {
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
});
} else {
uni.saveImageToPhotosAlbum({
filePath: that.poster,
success: function(res) {
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
}
});
},
setShareInfoStatus: function() {
if (this.$wechat.isWeixin()) {
let configAppMessage = {
desc: '分销海报',
title: this.userInfo.nickname + '-分销海报',
link: '/pages/index/index?spread=' + this.uid,
imgUrl: this.spreadList[0].pic
};
this.$wechat.wechatEvevt(["updateAppMessageShareData", "updateTimelineShareData"],
configAppMessage)
//
async getActivityInfo() {
try {
uni.showLoading({
title: '加载中',
mask: true
});
const res = await memberGradeInfo()
this.activityList = res.data
//
setTimeout(() => {
this.make()
}, 500)
} catch (e) {
this.$util.Tips({
title: '获取活动信息失败'
})
} finally {
uni.hideLoading()
}
}
}
}
</script>
<style lang="scss" scoped>
page {
background-color: #a3a3a3 !important;
height: 100% !important;
background-color: #F8EEEF !important;
height: 100vh;
overflow: auto;
}
.main-page{
height: 100%;
overflow: auto;
}
.spread-wrap {
height: 100%;
background: url('@/static/images/spread_bg.png') center 0 no-repeat;
background-size: 100% auto;
position: relative;
background-color: #F8EEEF;
}
.logo-wrap {
text-align: center;
padding-top: 53rpx;
.logo-image {
width: 160rpx;
height: 141rpx;
}
}
.activity-wrap {
position: absolute;
top: 460rpx;
left: 104rpx;
right: 110rpx;
.tenant-info-wrap {
position: absolute;
left: 0;
right: 0;
top: 656rpx;
.info-wrap {
display: flex;
justify-content: space-between;
}
.qrcode-wrap {
margin-left: 40rpx;
}
.address {
margin-top: 18rpx;
}
.logon {
width: 100%;
height: 70rpx;
margin: 30rpx 0;
color: #FFFFFF;
font-size: 28rpx;
background: linear-gradient(0deg, #E63163 0%, #FF819F 100%);
border-radius: 44rpx;
}
}
.service-phone {
position: absolute;
bottom: -114rpx;
right: 48rpx;
font-size: 30rpx;
color: #ED387C;
font-style: italic;
font-weight: bold;
}
.tips {
font-size: 28rpx;
color: #000;
}
.item-wrap {
font-size: 26rpx;
font-style: italic;
color: #010101;
font-weight: bold;
margin-bottom: 54rpx;
padding-left: 227rpx;
.text span {
color: #C80D00;
}
}
}
.canvas {
position: relative;
}
.distribution-posters {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.distribution-posters swiper {
width: 100%;
height: 1000rpx;
position: relative;
margin-top: 40rpx;
}
.distribution-posters .slide-image {
width: 100%;
height: 100%;
margin: 0 auto;
border-radius: 15rpx;
}
.distribution-posters .slide-image.active {
transform: none;
transition: all 0.2s ease-in 0s;
}
.distribution-posters .slide-image.quiet {
transform: scale(0.8333333);
transition: all 0.2s ease-in 0s;
}
.distribution-posters .keep {
font-size: 30rpx;
color: #fff;
width: 600rpx;
height: 80rpx;
border-radius: 50rpx;
text-align: center;
line-height: 80rpx;
margin: 38rpx auto;
}
.distribution-posters .preserve {
color: #fff;
text-align: center;
margin-top: 38rpx;
}
.distribution-posters .preserve .line {
width: 100rpx;
height: 1px;
background-color: #fff;
}
.distribution-posters .preserve .tip {
margin: 0 30rpx;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB