Merge remote-tracking branch 'origin/master'

pull/1/head
wqy 1 year ago
commit cce5c23778

@ -10,6 +10,7 @@
## B站讲解视频
https://www.bilibili.com/video/BV16N4y1d7MM
## 若依视频教程
对若依框架不了解不知道怎么部署、修改密码等操作的请参考https://www.bilibili.com/video/BV1Fi4y1q74p/
## 本地运行文档
https://docs.ichengle.top/mall/run.html
@ -31,9 +32,6 @@ http://mall.ichengle.top
<img src="doc/小程序演示.jpg" width="200px">
<img src="doc/h5演示.png" width="200px">
### 给大家一个便宜寄快递的福利大件5折小件6折
<img src="doc/express.jpg" width="200px">
## 若依技术专栏
- 常见问题https://blog.csdn.net/qq_27575627/category_12336113.html
- 后端技术https://blog.csdn.net/qq_27575627/category_12331868.html
@ -42,11 +40,25 @@ http://mall.ichengle.top
## 若依mall功能
1. 首页:
![img.png](doc/首页.png)
2. PMS商品管理
![img.png](doc/商品.png)
![img.png](doc/商品列表.png)
3. UMS会员管理
会员列表:
![img.png](doc/会员列表.png)
购物车:
![img.png](doc/会员购物车.png)
4. OMS订单管理
订单列表:
![img.png](doc/订单.png)
售后列表:
![img.png](doc/售后.png)
5. SMS营销管理
![img.png](doc/优惠券.png)
![img.png](doc/积分.png)
6. CMS内容管理
![img.png](doc/内容管理.png)
## 交流群/技术支持
| 公众号 |

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

@ -22,7 +22,7 @@
<kaptcha.version>2.3.2</kaptcha.version>
<mybatis-spring-boot.version>2.1.4</mybatis-spring-boot.version>
<pagehelper.boot.version>1.3.1</pagehelper.boot.version>
<fastjson.version>1.2.78</fastjson.version>
<fastjson.version>2.0.43</fastjson.version>
<oshi.version>5.8.0</oshi.version>
<jna.version>5.8.0</jna.version>
<commons.io.version>2.11.0</commons.io.version>

@ -44,15 +44,15 @@ aliyun:
bucketName: 你的bucketName # bucket 名称
wechat:
enabled: false
appId: 你的微信服务号信息
secret: 你的微信服务号信息
appId: 你的微信服务号信息h5的时候需要小程序的时候不需要
secret: 你的微信服务号信息h5的时候需要小程序的时候不需要
merchantId: 微信支付商户号
privateKeyPath: 微信支付密钥地址相对地址
merchantSerialNumber: 微信支付密钥对应的序列号
apiV3key: 微信支付apiV3key
notifyUrl: 微信支付回调地址
miniProgramAppId: 小程序apppid
miniProgramSecret:
miniProgramAppId: 小程序apppidh5的时候不需要
miniProgramSecret: 小程序Secreth5的时候不需要
sms:
enabled: true
# 阿里云 dysmsapi.aliyuncs.com

@ -14,12 +14,8 @@ import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Timestamp;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -36,6 +32,21 @@ public class CommonTest {
log.info("end {}", System.currentTimeMillis() - start);
}*/
@Test
public void testEquals(){
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1 == num2); // true因为对于 Integer 类型,-128 到 127 之间的值会被缓存
System.out.println(num1.equals(num2)); // true因为它们的值相同
Integer num3 = 200;
Integer num4 = 200;
System.out.println(num3 == num4); // false因为超出了缓存范围会创建新的对象实例
System.out.println(num3.equals(num4)); // true因为它们的值相同
}
@Test
public void test4() throws IOException {
String f1 = "D:/build/tt.jpg";

@ -255,4 +255,10 @@ public class Constants
public static final Integer REFUSE = 2;
public static final Integer GIVING = 3;
}
/**
* json
*/
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi","com.cyl" };
}

@ -1,5 +1,6 @@
package com.ruoyi.common.core.redis;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -8,6 +9,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class RedisService {
@Autowired
private RedisCache redisCache;
@ -69,7 +71,8 @@ public class RedisService {
public void lock(String key, String jobInfo, Integer lockSecond) throws Exception {
String existJobInfo = redisCache.getCacheObject(key);
if (StringUtils.isNotEmpty(existJobInfo)) {
throw new Exception(String.format("获取锁失败: redisKey: %s, existJobInfo: %s", key, existJobInfo));
log.info("获取锁失败: redisKey: {}, existJobInfo: {}", key, existJobInfo);
throw new Exception("请不要反复提交订单!");
}
redisCache.setCacheObject(key, jobInfo, lockSecond, TimeUnit.SECONDS);
}

@ -1,34 +1,27 @@
package com.ruoyi.framework.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;
import com.ruoyi.common.constant.Constants;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.util.Assert;
import java.nio.charset.Charset;
/**
* Redis使FastJson
*
*
* @author ruoyi
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
static
{
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
@ -43,7 +36,7 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
@ -55,17 +48,6 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper)
{
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz)
{
return TypeFactory.defaultInstance().constructType(clazz);
return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
}
}

@ -8,15 +8,10 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
/**
* redis
*
*
* @author ruoyi
*/
@Configuration
@ -32,11 +27,6 @@ public class RedisConfig extends CachingConfigurerSupport
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
serializer.setObjectMapper(mapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);

@ -2,16 +2,8 @@ package com.cyl.h5.controller;
import com.alibaba.fastjson.JSONObject;
import com.cyl.h5.domain.dto.DeliveryReq;
import com.cyl.h5.domain.form.ApplyRefundForm;
import com.cyl.h5.domain.form.OrderCreateForm;
import com.cyl.h5.domain.form.CancelOrderForm;
import com.cyl.h5.domain.form.OrderPayForm;
import com.cyl.h5.domain.vo.OrderPayVO;
import com.cyl.h5.domain.vo.AftersaleRefundInfoVO;
import com.cyl.h5.domain.vo.CountOrderVO;
import com.cyl.h5.domain.vo.H5OrderVO;
import com.cyl.h5.domain.vo.OrderCalcVO;
import com.cyl.h5.domain.form.OrderSubmitForm;
import com.cyl.h5.domain.form.*;
import com.cyl.h5.domain.vo.*;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.oms.domain.entity.Aftersale;
import com.cyl.manager.oms.domain.entity.Order;
@ -21,7 +13,6 @@ import com.cyl.manager.oms.service.OrderService;
import com.cyl.manager.ums.domain.entity.Member;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.enums.AftersaleStatus;
import com.ruoyi.common.enums.OrderStatus;
@ -61,7 +52,7 @@ public class H5OrderController {
return ResponseEntity.ok(service.submit(form));
}catch (Exception e){
log.info("创建订单方法异常", e);
throw new RuntimeException("服务繁忙,稍后再试");
throw new RuntimeException(e.getMessage());
}finally {
try {
redisService.unLock(redisKey, redisValue);

@ -8,23 +8,17 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.h5.config.SecurityUtil;
import com.cyl.h5.domain.form.ApplyRefundForm;
import com.cyl.h5.domain.form.OrderCreateForm;
import com.cyl.h5.domain.dto.OrderProductListDTO;
import com.cyl.h5.domain.dto.PayNotifyMessageDTO;
import com.cyl.h5.domain.form.CancelOrderForm;
import com.cyl.h5.domain.form.OrderPayForm;
import com.cyl.h5.domain.vo.OrderPayVO;
import com.cyl.h5.domain.form.*;
import com.cyl.h5.domain.vo.*;
import com.cyl.h5.domain.form.OrderSubmitForm;
import com.cyl.manager.act.domain.entity.MemberCoupon;
import com.cyl.manager.act.mapper.MemberCouponMapper;
import com.cyl.manager.act.service.IntegralHistoryService;
import com.cyl.manager.act.service.MemberCouponService;
import com.cyl.manager.oms.convert.AftersaleItemConvert;
import com.cyl.manager.oms.convert.OrderItemConvert;
import com.cyl.manager.oms.mapper.*;
import com.cyl.manager.oms.domain.entity.*;
import com.cyl.manager.oms.mapper.*;
import com.cyl.manager.oms.service.OrderItemService;
import com.cyl.manager.oms.service.OrderOperateHistoryService;
import com.cyl.manager.pms.domain.entity.Product;
@ -57,7 +51,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@ -584,9 +577,27 @@ public class H5OrderService {
QueryWrapper<MemberWechat> memberWechatQw = new QueryWrapper<>();
memberWechatQw.eq("member_id", req.getMemberId());
MemberWechat memberWechat = memberWechatMapper.selectOne(memberWechatQw);
if (memberWechat == null || StrUtil.isBlank(memberWechat.getOpenid())) {
if (memberWechat == null) {
throw new RuntimeException("获取用户openId失败");
}
String openId = null;
String appId = null;
//公众号支付流程
if (req.getWechatType() == 1) {
if (StrUtil.isBlank(memberWechat.getOpenid())) {
throw new RuntimeException("获取用户openId失败");
}
openId = memberWechat.getOpenid();
appId = WechatPayData.appId;
}
//小程序支付流程
if (req.getWechatType() == 2) {
if (StrUtil.isBlank(memberWechat.getRoutineOpenid())) {
throw new RuntimeException("获取用户openId失败");
}
openId = memberWechat.getRoutineOpenid();
appId = WechatPayData.miniProgramAppId;
}
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.eq("order_id", orderList.get(0).getId());
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
@ -617,12 +628,6 @@ public class H5OrderService {
}
//请开启微信支付 wechat.enabled=true
//调用wx的jsapi拿prepayId返回签名等信息
String openId = memberWechat.getOpenid();
String appId = WechatPayData.appId;
if (2 == req.getWechatType()) {
openId = memberWechat.getRoutineOpenid();
appId = WechatPayData.miniProgramAppId;
}
String prepayId = wechatPayService.jsapiPay(
String.valueOf(req.getPayId()),
orderDesc,

@ -1,14 +1,14 @@
package com.cyl.manager.act.domain.entity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* act_coupon_activity
*
@ -74,9 +74,11 @@ public class CouponActivity {
private LocalDateTime endTime;
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty("修改时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}

@ -1,14 +1,14 @@
package com.cyl.manager.act.domain.entity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* act_member_coupon
*
@ -82,6 +82,7 @@ public class MemberCoupon {
private LocalDateTime useTime;
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save