1.3.3新增 后台微信图文发送功能,小程序配置,增加小程序授权等,修复一些bug等

This commit is contained in:
hupeng
2019-11-29 19:03:46 +08:00
parent 8c4c9b0387
commit 33a592b833
57 changed files with 1726 additions and 170 deletions

View File

@ -11,7 +11,7 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
| | 后台系统 | 前端(公众号) |
|--- |--- | --- |
| | https://yshop.dayouqiantu.cn |g公众号YshopMall |
| | https://yshop.dayouqiantu.cn |H5:https://h5.dayouqiantu.cn 测试号hupeng/123456,也可以自行注册 |
| | 后台体验账号/密码admin/123456 | 公众号:![输入图片说明](https://images.gitee.com/uploads/images/2019/1116/060936_fd73496c_477893.jpeg "qrcode_for_gh_95df5a2881cc_258.jpg") |
@ -24,7 +24,6 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
#### 开源版本与VIP版本说明
### 开源版
1.包括整个商城系统后台、数据库、api(只是简单的配置好模块);
@ -41,7 +40,6 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
4、VIP为终身【[详情请查看](https://gitee.com/guchengwuyue/yshopmall/wikis/pages?sort_id=1715823&doc_id=441578)】
## 商城功能
* 一:商品模块:商品添加、规格设置,商品上下架等
@ -57,7 +55,6 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
- 可以具体查看演示地址查看当前版本已经完成的功能,不再絮叨啦
#### 项目结构
项目采用分模块开发方式
- yshop-api 公众号(H5)API模块
@ -84,7 +81,7 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2019/1121/230424_f01fca77_477893.png"/></td>
<td></td>
<td><img src="https://images.gitee.com/uploads/images/2019/1127/211402_4103f8e0_477893.png"/></td>
</tr>
</table>
<table>
@ -104,11 +101,11 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
## 技术选型
* 1 后端使用技术
* 1.1 SpringBoot
* 1.1 SpringBoot2
* 1.2 mybatis、MyBatis-Plus
* 1.3 SpringSecurity
* 1.4 JAP
* 1.5 Druid1
* 1.4 JPA
* 1.5 Druid
* 1.6 Slf4j
* 1.7 Fastjson
* 1.8 JWT
@ -120,6 +117,7 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
* 1.14 Lombok
* 1.15 Hutool
* 1.16 Mapstruct
* 1.17 Redisson
* 前端使用技术
* 2.1 Vue 全家桶
@ -133,7 +131,8 @@ yshop基于当前流行技术组合 SpringBoot2+Jpa+MybatisPlus+SpringSecurit
- 1.2版本分销功能已经发布
- 1.2.1增加了未付款订单取消功能库存销量退出、优惠券、积分功能,个人中心增加了积分流水
- 1.3版本新增拼团功能,已经发布
- 1.4版本规划补充公众号功能、新增redisson队列、发布mpvue小程序
- 1.3.1版本手机端新增商户管理、后台新增统计
- 1.4版本规划补充公众号功能、发布mpvue小程序
#### 反馈交流

19
pom.xml
View File

@ -42,6 +42,7 @@
<mapstruct.version>1.2.0.Final</mapstruct.version>
</properties>
<dependencies>
<!--Spring boot start-->
@ -201,6 +202,24 @@
<artifactId>redisson</artifactId>
<version>3.11.2</version>
</dependency>
<!--webservice-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web-services</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.cxf</groupId>-->
<!-- <artifactId>cxf-rt-frontend-jaxws</artifactId>-->
<!-- <version>3.1.6</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.cxf</groupId>-->
<!-- <artifactId>cxf-rt-transports-http</artifactId>-->
<!-- <version>3.1.6</version>-->
<!-- </dependency>-->
</dependencies>
<build>

File diff suppressed because one or more lines are too long

View File

@ -109,11 +109,6 @@
<artifactId>qcloudsms</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>3.3.1.B</version>
</dependency>
</dependencies>
<build>

View File

@ -10,6 +10,7 @@ package co.yixiang.common.api;
*/
public enum ApiCode {
FAIL_AUTH(410000, "没有权限"),
SUCCESS(200, "操作成功"),
UNAUTHORIZED(401, "非法访问"),

View File

@ -2,10 +2,16 @@ package co.yixiang.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import java.util.List;
/**
* WebMvcConfigurer
@ -41,4 +47,7 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
}
}

View File

@ -0,0 +1,161 @@
package co.yixiang.modules.manage.web.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.common.api.ApiResult;
import co.yixiang.common.web.controller.BaseController;
import co.yixiang.modules.manage.web.dto.OrderTimeDataDTO;
import co.yixiang.modules.manage.web.param.OrderDeliveryParam;
import co.yixiang.modules.manage.web.param.OrderPriceParam;
import co.yixiang.modules.manage.web.param.OrderRefundParam;
import co.yixiang.modules.manage.web.param.OrderRemarkParam;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.order.web.dto.OrderCountDTO;
import co.yixiang.modules.order.web.vo.YxStoreOrderQueryVo;
import co.yixiang.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @ClassName ShoperController
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(value = "商家管理", tags = "商家管理", description = "商家管理")
public class ShoperController extends BaseController {
private final YxStoreOrderService storeOrderService;
/**
* 订单数据统计
*/
@GetMapping("/admin/order/statistics")
@ApiOperation(value = "订单数据统计",notes = "订单数据统计")
public ApiResult<Object> statistics(){
int uid = SecurityUtils.getUserId().intValue();
OrderCountDTO orderCountDTO = storeOrderService.orderData(0);
OrderTimeDataDTO orderTimeDataDTO = storeOrderService.getOrderTimeData();
Map<String,Object> map = new LinkedHashMap<>();
map.put("orderCount",orderCountDTO);
map.put("orderTimeCount",orderTimeDataDTO);
return ApiResult.ok(map);
}
/**
* 订单每月统计数据
*/
@GetMapping("/admin/order/data")
@ApiOperation(value = "订单每月统计数据",notes = "订单每月统计数据")
public ApiResult<Object> data(@RequestParam(value = "page",defaultValue = "1") int page,
@RequestParam(value = "limit",defaultValue = "10") int limit){
int uid = SecurityUtils.getUserId().intValue();
return ApiResult.ok(storeOrderService.getOrderDataPriceCount(page,limit));
}
/**
* 订单列表
*/
@GetMapping("/admin/order/list")
@ApiOperation(value = "订单列表",notes = "订单列表")
public ApiResult<Object> orderList(@RequestParam(value = "status",defaultValue = "0") int type,
@RequestParam(value = "page",defaultValue = "1") int page,
@RequestParam(value = "limit",defaultValue = "10") int limit){
int uid = SecurityUtils.getUserId().intValue();
return ApiResult.ok(storeOrderService.orderList(0,type,page,limit));
}
/**
* 订单详情
*/
@GetMapping("/admin/order/detail/{key}")
@ApiOperation(value = "订单详情",notes = "订单详情")
public ApiResult<Object> orderDetail(@PathVariable String key){
int uid = SecurityUtils.getUserId().intValue();
if(StrUtil.isEmpty(key)) return ApiResult.fail("参数错误");
YxStoreOrderQueryVo storeOrder = storeOrderService.getOrderInfo(key,0);
if(ObjectUtil.isNull(storeOrder)){
return ApiResult.fail("订单不存在");
}
return ApiResult.ok(storeOrderService.handleOrder(storeOrder));
}
/**
* 订单改价
*/
@PostMapping("/admin/order/price")
@ApiOperation(value = "订单改价",notes = "订单改价")
public ApiResult<Object> orderPrice(@Validated @RequestBody OrderPriceParam param){
//if(ObjectUtil.isNotNull(param)) return ApiResult.fail("演示环境禁止操作");
int uid = SecurityUtils.getUserId().intValue();
storeOrderService.editOrderPrice(param);
return ApiResult.ok("ok");
}
/**
* 订单发货
*/
@PostMapping("/admin/order/delivery/keep")
@ApiOperation(value = "订单发货",notes = "订单发货")
public ApiResult<Object> orderDelivery(@Validated @RequestBody OrderDeliveryParam param){
//if(ObjectUtil.isNotNull(param)) return ApiResult.fail("演示环境禁止操作");
int uid = SecurityUtils.getUserId().intValue();
storeOrderService.orderDelivery(param);
return ApiResult.ok("ok");
}
/**
* 订单退款
*/
@PostMapping("/admin/order/refund")
@ApiOperation(value = "订单退款",notes = "订单退款")
public ApiResult<Object> orderRefund(@Validated @RequestBody OrderRefundParam param){
//if(ObjectUtil.isNotNull(param)) return ApiResult.fail("演示环境禁止操作");
int uid = SecurityUtils.getUserId().intValue();
storeOrderService.orderRefund(param);
return ApiResult.ok("ok");
}
/**
* 订单交易额/订单数量时间chart统计
*/
@GetMapping("/admin/order/time")
@ApiOperation(value = "chart统计",notes = "chart统计")
public ApiResult<Object> chartCount(@RequestParam(value = "cate",defaultValue = "1") int cate,
@RequestParam(value = "type",defaultValue = "1") int type){
int uid = SecurityUtils.getUserId().intValue();
return ApiResult.ok(storeOrderService.chartCount(cate,type));
}
}

View File

@ -0,0 +1,16 @@
package co.yixiang.modules.manage.web.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName ChartDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
@Data
public class ChartDataDTO implements Serializable {
private Double num;
private String time;
}

View File

@ -0,0 +1,17 @@
package co.yixiang.modules.manage.web.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName OrderDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
@Data
public class OrderDataDTO implements Serializable {
private Integer count;
private Double price;
private String time;
}

View File

@ -0,0 +1,20 @@
package co.yixiang.modules.manage.web.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName OrderTimeDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
@Data
public class OrderTimeDataDTO implements Serializable {
private Double todayPrice; //今日成交额
private Integer todayCount; //今日订单数
private Double proPrice; //昨日成交额
private Integer proCount;//昨日订单数
private Double monthPrice;//本月成交额
private Integer monthCount;//本月订单数
}

View File

@ -0,0 +1,23 @@
package co.yixiang.modules.manage.web.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* @ClassName OrderPriceParam
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/26
**/
@Data
public class OrderDeliveryParam implements Serializable {
@NotBlank(message = "订单编号错误")
private String orderId;
@NotBlank(message = "快递单号必填")
private String deliveryId;
@NotBlank(message = "快递公司必填")
private String deliveryName;
@NotBlank(message = "快递方式必填")
private String deliveryType;
}

View File

@ -0,0 +1,20 @@
package co.yixiang.modules.manage.web.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @ClassName OrderPriceParam
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/26
**/
@Data
public class OrderPriceParam implements Serializable {
@NotBlank(message = "订单编号错误")
private String orderId;
@NotNull(message = "修改价格必填")
private Double price;
}

View File

@ -0,0 +1,22 @@
package co.yixiang.modules.manage.web.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @ClassName OrderPriceParam
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/26
**/
@Data
public class OrderRefundParam implements Serializable {
@NotBlank(message = "订单编号错误")
private String orderId;
@NotNull(message = "退款金额必填")
private Double price;
@NotNull(message = "参数错误")
private Integer type;
}

View File

@ -0,0 +1,20 @@
package co.yixiang.modules.manage.web.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @ClassName OrderPriceParam
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/26
**/
@Data
public class OrderRemarkParam implements Serializable {
@NotBlank(message = "订单编号错误")
private String orderId;
@NotBlank(message = "备注必填")
private String remark;
}

View File

@ -1,6 +1,10 @@
package co.yixiang.modules.order.mapper;
import co.yixiang.modules.manage.web.dto.ChartDataDTO;
import co.yixiang.modules.manage.web.dto.OrderDataDTO;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import co.yixiang.modules.order.entity.YxStoreOrder;
@ -11,6 +15,7 @@ import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
/**
* <p>
@ -23,6 +28,33 @@ import java.io.Serializable;
@Repository
public interface YxStoreOrderMapper extends BaseMapper<YxStoreOrder> {
@Select("SELECT sum(pay_price) as num," +
"FROM_UNIXTIME(add_time, '%m-%d') as time " +
" FROM yx_store_order ${ew.customSqlSegment} " +
" GROUP BY FROM_UNIXTIME(add_time,'%Y-%m-%d') " +
" ORDER BY add_time ASC")
List<ChartDataDTO> chartList(@Param(Constants.WRAPPER) Wrapper<YxStoreOrder> wrapper);
@Select("SELECT count(id) as num," +
"FROM_UNIXTIME(add_time, '%m-%d') as time " +
" FROM yx_store_order ${ew.customSqlSegment} " +
" GROUP BY FROM_UNIXTIME(add_time,'%Y-%m-%d') " +
" ORDER BY add_time ASC")
List<ChartDataDTO> chartListT(@Param(Constants.WRAPPER) Wrapper<YxStoreOrder> wrapper);
@Select("SELECT sum(pay_price) as price,count(id) as count," +
"FROM_UNIXTIME(add_time, '%m-%d') as time FROM yx_store_order" +
" WHERE is_del = 0 AND paid = 1 AND refund_status = 0 " +
"GROUP BY FROM_UNIXTIME(add_time,'%Y-%m-%d') ORDER BY add_time DESC")
List<OrderDataDTO> getOrderDataPriceList(Page page);
@Select("SELECT IFNULL(sum(pay_price),0) " +
" FROM yx_store_order ${ew.customSqlSegment}")
Double todayPrice(@Param(Constants.WRAPPER) Wrapper<YxStoreOrder> wrapper);
@Select("select IFNULL(sum(pay_price),0) from yx_store_order " +
"where paid=1 and is_del=0 and refund_status=0 and uid=#{uid}")
double sumPrice(@Param("uid") int uid);

View File

@ -1,5 +1,10 @@
package co.yixiang.modules.order.service;
import co.yixiang.modules.manage.web.dto.OrderDataDTO;
import co.yixiang.modules.manage.web.dto.OrderTimeDataDTO;
import co.yixiang.modules.manage.web.param.OrderDeliveryParam;
import co.yixiang.modules.manage.web.param.OrderPriceParam;
import co.yixiang.modules.manage.web.param.OrderRefundParam;
import co.yixiang.modules.order.entity.YxStoreOrder;
import co.yixiang.common.service.BaseService;
import co.yixiang.modules.order.web.dto.*;
@ -13,8 +18,10 @@ import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* <p>
@ -24,8 +31,23 @@ import java.util.List;
* @author hupeng
* @since 2019-10-27
*/
//@WebService(serviceName = "YxStoreOrderService",
// targetNamespace = "http://service.order.modules.yixiang.co"
//)
public interface YxStoreOrderService extends BaseService<YxStoreOrder> {
Map<String,Object> chartCount(int cate,int type);
void orderRefund(OrderRefundParam param);
void orderDelivery(OrderDeliveryParam param);
void editOrderPrice(OrderPriceParam param);
List<OrderDataDTO> getOrderDataPriceCount(int page, int limit);
OrderTimeDataDTO getOrderTimeData();
YxStoreOrder getOrderPink(int pid,int uid,int type);
void regressionCoupon(YxStoreOrderQueryVo order);
@ -48,6 +70,7 @@ public interface YxStoreOrderService extends BaseService<YxStoreOrder> {
List<YxStoreOrderQueryVo> orderList(int uid,int type,int page,int limit);
//@WebMethod
OrderCountDTO orderData(int uid);
YxStoreOrderQueryVo handleOrder(YxStoreOrderQueryVo order);

View File

@ -1,11 +1,20 @@
package co.yixiang.modules.order.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.*;
import co.yixiang.common.constant.CacheKey;
import co.yixiang.common.constant.CommonConstant;
import co.yixiang.exception.ErrorRequestException;
import co.yixiang.modules.activity.service.YxStoreCombinationService;
import co.yixiang.modules.activity.service.YxStorePinkService;
import co.yixiang.modules.manage.web.dto.ChartDataDTO;
import co.yixiang.modules.manage.web.dto.OrderDataDTO;
import co.yixiang.modules.manage.web.dto.OrderTimeDataDTO;
import co.yixiang.modules.manage.web.param.OrderDeliveryParam;
import co.yixiang.modules.manage.web.param.OrderPriceParam;
import co.yixiang.modules.manage.web.param.OrderRefundParam;
import co.yixiang.modules.monitor.service.RedisService;
import co.yixiang.modules.order.entity.YxStoreOrder;
import co.yixiang.modules.order.entity.YxStoreOrderCartInfo;
@ -44,11 +53,13 @@ import co.yixiang.modules.user.web.vo.YxWechatUserQueryVo;
import co.yixiang.redisson.DelayJob;
import co.yixiang.redisson.DelayJobService;
import co.yixiang.utils.OrderUtil;
import co.yixiang.utils.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
@ -56,7 +67,9 @@ import lombok.extern.slf4j.Slf4j;
//import org.redisson.api.RDelayedQueue;
//import org.redisson.api.RQueue;
//import org.redisson.api.RedissonClient;
//import org.apache.webservice.config.annotation.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
@ -64,13 +77,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import javax.jws.WebService;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
@ -82,6 +95,7 @@ import java.util.concurrent.TimeUnit;
* @author hupeng
* @since 2019-10-27
*/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@ -147,6 +161,111 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
// @Value("${job.unpayorder}")
// private String overtime;
/**
* 订单退款
* @param param
*/
@Override
public void orderRefund(OrderRefundParam param) {
YxStoreOrderQueryVo orderQueryVo = getOrderInfo(param.getOrderId(),0);
if(ObjectUtil.isNull(orderQueryVo)) throw new ErrorRequestException("订单不存在");
YxUserQueryVo userQueryVo = userService.getYxUserById(orderQueryVo.getUid());
if(ObjectUtil.isNull(userQueryVo)) throw new ErrorRequestException("用户不存在");
if(param.getPrice() > orderQueryVo.getPayPrice().doubleValue()) throw new ErrorRequestException("退款金额不正确");
YxStoreOrder storeOrder = new YxStoreOrder();
//修改状态
storeOrder.setId(orderQueryVo.getId());
storeOrder.setRefundStatus(2);
storeOrder.setRefundPrice(BigDecimal.valueOf(param.getPrice()));
yxStoreOrderMapper.updateById(storeOrder);
//退款到余额
userService.incMoney(orderQueryVo.getUid(),param.getPrice());
//增加流水
YxUserBill userBill = new YxUserBill();
userBill.setUid(orderQueryVo.getUid());
userBill.setLinkId(orderQueryVo.getId().toString());
userBill.setPm(1);
userBill.setTitle("商品退款");
userBill.setCategory("now_money");
userBill.setType("pay_product_refund");
userBill.setNumber(BigDecimal.valueOf(param.getPrice()));
userBill.setBalance(NumberUtil.add(param.getPrice(),userQueryVo.getNowMoney()));
userBill.setMark("订单退款到余额");
userBill.setAddTime(OrderUtil.getSecondTimestampTwo());
userBill.setStatus(1);
billService.save(userBill);
orderStatusService.create(orderQueryVo.getId(),"order_edit","退款给用户:"+param.getPrice() +"");
}
/**
* 订单发货
* @param param
*/
@Override
public void orderDelivery(OrderDeliveryParam param) {
YxStoreOrderQueryVo orderQueryVo = getOrderInfo(param.getOrderId(),0);
if(ObjectUtil.isNull(orderQueryVo)) throw new ErrorRequestException("订单不存在");
if(orderQueryVo.getStatus() != 0 || orderQueryVo.getPaid() == 0) throw new ErrorRequestException("订单状态错误");
YxStoreOrder storeOrder = new YxStoreOrder();
storeOrder.setId(orderQueryVo.getId());
storeOrder.setStatus(1);
storeOrder.setDeliveryId(param.getDeliveryId());
storeOrder.setDeliveryName(param.getDeliveryName());
storeOrder.setDeliveryType(param.getDeliveryType());
yxStoreOrderMapper.updateById(storeOrder);
//增加状态
orderStatusService.create(storeOrder.getId(),"delivery_goods",
"已发货 快递公司:"+param.getDeliveryName()+"快递单号:" +param.getDeliveryId());
}
/**
* 修改订单价格
* @param param
*/
@Override
public void editOrderPrice(OrderPriceParam param) {
YxStoreOrderQueryVo orderQueryVo = getOrderInfo(param.getOrderId(),0);
if(ObjectUtil.isNull(orderQueryVo)) throw new ErrorRequestException("订单不存在");
if(orderQueryVo.getPayPrice().doubleValue() == param.getPrice()) return;
if(orderQueryVo.getPaid() > 0) throw new ErrorRequestException("订单状态错误");
YxStoreOrder storeOrder = new YxStoreOrder();
storeOrder.setId(orderQueryVo.getId());
storeOrder.setPayPrice(BigDecimal.valueOf(param.getPrice()));
yxStoreOrderMapper.updateById(storeOrder);
//增加状态
orderStatusService.create(storeOrder.getId(),"order_edit","修改实际支付金额");
}
/**
* 获取拼团订单
* @param pid
* @param uid
* @param type
* @return
*/
@Override
public YxStoreOrder getOrderPink(int pid, int uid,int type) {
QueryWrapper<YxStoreOrder> wrapper = new QueryWrapper<>();
@ -427,7 +546,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
@Override
public List<YxStoreOrderQueryVo> orderList(int uid, int type, int page, int limit) {
QueryWrapper<YxStoreOrder> wrapper= new QueryWrapper<>();
wrapper.eq("is_del",0).eq("uid",uid).orderByDesc("add_time");
if(uid > 0) wrapper.eq("uid",uid);
wrapper.eq("is_del",0).orderByDesc("add_time");
switch (type){
case 0://未支付
@ -470,8 +590,110 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
return newList;
}
/**
* chart图标统计
* @param cate
* @param type
* @return
*/
@Override
public Map<String,Object> chartCount(int cate,int type) {
int today = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(new Date()));
int yesterday = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(DateUtil.
yesterday()));
int lastWeek = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(DateUtil.lastWeek()));
int nowMonth = OrderUtil.dateToTimestampT(DateUtil
.beginOfMonth(new Date()));
double price = 0d;
List<ChartDataDTO> list = null;
QueryWrapper<YxStoreOrder> wrapper = new QueryWrapper<>();
wrapper.eq("paid",1).eq("refund_status",0).eq("is_del",0);
switch (cate){
case 1: //今天
wrapper.ge("pay_time",today);
break;
case 2: //昨天
wrapper.lt("pay_time",today).ge("pay_time",yesterday);
break;
case 3: //上周
wrapper.ge("pay_time",lastWeek);
break;
case 4: //本月
wrapper.ge("pay_time",nowMonth);
break;
}
if(type == 1){
list = yxStoreOrderMapper.chartList(wrapper);
price = yxStoreOrderMapper.todayPrice(wrapper);
}else{
list = yxStoreOrderMapper.chartListT(wrapper);
price = yxStoreOrderMapper.selectCount(wrapper).doubleValue();
}
Map<String,Object> map = new LinkedHashMap<>();
map.put("chart",list);
map.put("time",price);
return map;
}
/**
* 获取 今日 昨日 本月 订单金额
* @return
*/
@Override
public OrderTimeDataDTO getOrderTimeData() {
int today = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(new Date()));
int yesterday = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(DateUtil.
yesterday()));
int nowMonth = OrderUtil.dateToTimestampT(DateUtil
.beginOfMonth(new Date()));
OrderTimeDataDTO orderTimeDataDTO = new OrderTimeDataDTO();
//今日成交额
QueryWrapper<YxStoreOrder> wrapperOne = new QueryWrapper<>();
wrapperOne.ge("pay_time",today).eq("paid",1)
.eq("refund_status",0).eq("is_del",0);
orderTimeDataDTO.setTodayPrice(yxStoreOrderMapper.todayPrice(wrapperOne));
//今日订单数
orderTimeDataDTO.setTodayCount(yxStoreOrderMapper.selectCount(wrapperOne));
//昨日成交额
QueryWrapper<YxStoreOrder> wrapperTwo = new QueryWrapper<>();
wrapperTwo.lt("pay_time",today).ge("pay_time",yesterday).eq("paid",1)
.eq("refund_status",0).eq("is_del",0);
orderTimeDataDTO.setProPrice(yxStoreOrderMapper.todayPrice(wrapperTwo));
//昨日订单数
orderTimeDataDTO.setProCount(yxStoreOrderMapper.selectCount(wrapperTwo));
//本月成交额
QueryWrapper<YxStoreOrder> wrapperThree = new QueryWrapper<>();
wrapperThree.ge("pay_time",nowMonth).eq("paid",1)
.eq("refund_status",0).eq("is_del",0);
orderTimeDataDTO.setMonthPrice(yxStoreOrderMapper.todayPrice(wrapperThree));
//本月订单数
orderTimeDataDTO.setMonthCount(yxStoreOrderMapper.selectCount(wrapperThree));
return orderTimeDataDTO;
}
/**
* 订单每月统计数据
* @param page
* @param limit
* @return
*/
@Override
public List<OrderDataDTO> getOrderDataPriceCount(int page, int limit) {
Page<YxStoreOrder> pageModel = new Page<>(page, limit);
return yxStoreOrderMapper.getOrderDataPriceList(pageModel);
}
/**
* 获取某个用户的订单统计数据
* @param uid uid>0 取用户 否则取所有
* @return
*/
@Override
@ -480,8 +702,8 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
OrderCountDTO countDTO = new OrderCountDTO();
//订单支付没有退款 数量
QueryWrapper<YxStoreOrder> wrapperOne = new QueryWrapper<>();
wrapperOne.eq("is_del",0).eq("paid",1)
.eq("uid",uid).eq("refund_status",0);
if(uid > 0 ) wrapperOne.eq("uid",uid);
wrapperOne.eq("is_del",0).eq("paid",1).eq("refund_status",0);
countDTO.setOrderCount(yxStoreOrderMapper.selectCount(wrapperOne));
//订单支付没有退款 支付总金额
@ -489,39 +711,45 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
//订单待支付 数量
QueryWrapper<YxStoreOrder> wrapperTwo = new QueryWrapper<>();
if(uid > 0 ) wrapperTwo.eq("uid",uid);
wrapperTwo.eq("is_del",0).eq("paid",0)
.eq("uid",uid).eq("refund_status",0).eq("status",0);
.eq("refund_status",0).eq("status",0);
countDTO.setUnpaidCount(yxStoreOrderMapper.selectCount(wrapperTwo));
//订单待发货 数量
QueryWrapper<YxStoreOrder> wrapperThree = new QueryWrapper<>();
if(uid > 0 ) wrapperThree.eq("uid",uid);
wrapperThree.eq("is_del",0).eq("paid",1)
.eq("uid",uid).eq("refund_status",0).eq("status",0);
.eq("refund_status",0).eq("status",0);
countDTO.setUnshippedCount(yxStoreOrderMapper.selectCount(wrapperThree));
//订单待收货 数量
QueryWrapper<YxStoreOrder> wrapperFour = new QueryWrapper<>();
if(uid > 0 ) wrapperFour.eq("uid",uid);
wrapperFour.eq("is_del",0).eq("paid",1)
.eq("uid",uid).eq("refund_status",0).eq("status",1);
.eq("refund_status",0).eq("status",1);
countDTO.setReceivedCount(yxStoreOrderMapper.selectCount(wrapperFour));
//订单待评价 数量
QueryWrapper<YxStoreOrder> wrapperFive = new QueryWrapper<>();
if(uid > 0 ) wrapperFive.eq("uid",uid);
wrapperFive.eq("is_del",0).eq("paid",1)
.eq("uid",uid).eq("refund_status",0).eq("status",2);
.eq("refund_status",0).eq("status",2);
countDTO.setEvaluatedCount(yxStoreOrderMapper.selectCount(wrapperFive));
//订单已完成 数量
QueryWrapper<YxStoreOrder> wrapperSix= new QueryWrapper<>();
if(uid > 0 ) wrapperSix.eq("uid",uid);
wrapperSix.eq("is_del",0).eq("paid",1)
.eq("uid",uid).eq("refund_status",0).eq("status",3);
.eq("refund_status",0).eq("status",3);
countDTO.setCompleteCount(yxStoreOrderMapper.selectCount(wrapperSix));
//订单退款
QueryWrapper<YxStoreOrder> wrapperSeven= new QueryWrapper<>();
if(uid > 0 ) wrapperSeven.eq("uid",uid);
String[] strArr = {"1","2"};
wrapperSeven.eq("is_del",0).eq("paid",1)
.eq("uid",uid).in("refund_status",Arrays.asList(strArr));
.in("refund_status",Arrays.asList(strArr));
countDTO.setRefundCount(yxStoreOrderMapper.selectCount(wrapperSeven));
@ -656,6 +884,20 @@ public class YxStoreOrderServiceImpl extends BaseServiceImpl<YxStoreOrderMapper,
public WxPayMpOrderResult wxPay(String orderId) throws WxPayException {
String apiUrl = systemConfigService.getData("api_url");
if(StrUtil.isBlank(apiUrl)) throw new ErrorRequestException("请配置api地址");
//读取redis配置
String appId = RedisUtil.get("wxpay_appId");
String mchId = RedisUtil.get("wxpay_mchId");
String mchKey = RedisUtil.get("wxpay_mchKey");
if(StrUtil.isBlank(appId) || StrUtil.isBlank(mchId) || StrUtil.isBlank(mchKey)){
throw new ErrorRequestException("请配置微信支付");
}
WxPayConfig wxPayConfig = new WxPayConfig();
wxPayConfig.setAppId(appId);
wxPayConfig.setMchId(mchId);
wxPayConfig.setMchKey(mchKey);
wxPayService.setConfig(wxPayConfig);
YxStoreOrderQueryVo orderInfo = getOrderInfo(orderId,0);
if(ObjectUtil.isNull(orderInfo)) throw new ErrorRequestException("订单不存在");
if(orderInfo.getPaid() == 1) throw new ErrorRequestException("该订单已支付");

View File

@ -262,10 +262,10 @@ public class StoreOrderController extends BaseController {
/**
* 订单详情
* 订单列表
*/
@GetMapping("/order/list")
@ApiOperation(value = "订单详情",notes = "订单详情")
@ApiOperation(value = "订单列表",notes = "订单列表")
public ApiResult<List<YxStoreOrderQueryVo>> orderList(@RequestParam(value = "type",defaultValue = "0") int type,
@RequestParam(value = "page",defaultValue = "1") int page,
@RequestParam(value = "limit",defaultValue = "10") int limit){

View File

@ -107,6 +107,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/register").anonymous()
.antMatchers("/user/activity").anonymous()
.antMatchers("/combination/list").anonymous()
.antMatchers("/webservice/**").anonymous()
//微信相关
.antMatchers("/wechat/config").anonymous()
.antMatchers("/wechat/auth").anonymous()

View File

@ -48,8 +48,7 @@ public class IndexController {
map.put("menus",systemGroupDataService.getDatas("routine_home_menus"));
//首页活动区域图片
map.put("activity",systemGroupDataService.getDatas("routine_home_activity"));
//logo
map.put("logoUrl",systemConfigService.getData("wechat_logo"));
//精品推荐
map.put("bastList",storeProductService.getList(1,6,1));
@ -63,9 +62,7 @@ public class IndexController {
//滚动
map.put("roll",systemGroupDataService.getDatas("routine_home_roll_news"));
//todo 优惠券
List list = new ArrayList();
map.put("couponList",list);
return ApiResult.ok(map);

View File

@ -56,6 +56,10 @@ public interface YxUserMapper extends BaseMapper<YxUser> {
" where uid=#{uid}")
int incPayCount(@Param("uid") int uid);
@Update("update yx_user set now_money=now_money+#{price}" +
" where uid=#{uid}")
int incMoney(@Param("uid") int uid,double price);
@Update("update yx_user set integral=integral-#{integral}" +
" where uid=#{uid}")
int decIntegral(@Param("integral") double integral,@Param("uid") int uid);

View File

@ -23,6 +23,8 @@ import java.util.List;
*/
public interface YxUserService extends BaseService<YxUser> {
void incMoney(int uid,double price);
void incIntegral(int uid,double integral);
YxUserQueryVo getNewYxUserById(Serializable id);

View File

@ -62,6 +62,16 @@ public class YxUserServiceImpl extends BaseServiceImpl<YxUserMapper, YxUser> imp
private YxUserBillService billService;
/**
* 更新用户余额
* @param uid
* @param price
*/
@Override
public void incMoney(int uid, double price) {
yxUserMapper.incMoney(uid,price);
}
@Override
public void incIntegral(int uid, double integral) {
yxUserMapper.incIntegral(integral,uid);

View File

@ -3,6 +3,7 @@ package co.yixiang.modules.wechat.web.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.common.api.ApiCode;
import co.yixiang.common.api.ApiResult;
import co.yixiang.common.web.controller.BaseController;
import co.yixiang.modules.order.service.YxStoreOrderService;
@ -39,6 +40,11 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
@ -110,18 +116,27 @@ public class WechatController extends BaseController {
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxService.oauth2getAccessToken(code);
WxMpUser wxMpUser = wxService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
String openid = wxMpUser.getOpenId();
YxWechatUser wechatUser = wechatUserService.getUserInfo(openid);;
YxUserQueryVo yxUserQueryVo = userService.getYxUserById(wechatUser.getUid());
YxWechatUser wechatUser = wechatUserService.getUserInfo(openid);
JwtUser jwtUser = null;
if(ObjectUtil.isNotNull(wechatUser) && ObjectUtil.isNotNull(yxUserQueryVo)){
jwtUser = (JwtUser) userDetailsService.loadUserByUsername(wechatUser.getOpenid());
}else{
if(ObjectUtil.isNotNull(wechatUser)){
wechatUserService.removeById(wechatUser.getUid());
}
if(ObjectUtil.isNotNull(wechatUser)){
YxUserQueryVo yxUserQueryVo = userService.getYxUserById(wechatUser.getUid());
if(ObjectUtil.isNotNull(yxUserQueryVo)){
userService.removeById(yxUserQueryVo.getUid());
jwtUser = (JwtUser) userDetailsService.loadUserByUsername(wechatUser.getOpenid());
}else{
if(ObjectUtil.isNotNull(wechatUser)){
wechatUserService.removeById(wechatUser.getUid());
}
if(ObjectUtil.isNotNull(yxUserQueryVo)){
userService.removeById(yxUserQueryVo.getUid());
}
return ApiResult.fail(ApiCode.FAIL_AUTH,"授权失败");
}
}else{
//用户保存
YxUser user = new YxUser();
user.setAccount(wxMpUser.getNickname());
@ -245,14 +260,17 @@ public class WechatController extends BaseController {
return "fail";
}
@PostMapping("/wechat/serve")
public String post(@RequestBody String requestBody,
public void post(@RequestBody String requestBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("openid") String openid,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
@RequestParam(name = "msg_signature", required = false) String msgSignature,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (!wxService.checkSignature(timestamp, nonce, signature)) {
@ -264,25 +282,21 @@ public class WechatController extends BaseController {
// 明文传输的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toXml();
System.out.println("xml:"+out);
} else if ("aes".equalsIgnoreCase(encType)) {
// aes加密的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(),
timestamp, nonce, msgSignature);
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage());
}
return out;
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print(out);
writer.close();
}
private WxMpXmlOutMessage route(WxMpXmlMessage message) {

View File

@ -0,0 +1,198 @@
package co.yixiang.modules.wechat.web.controller;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.common.api.ApiCode;
import co.yixiang.common.api.ApiResult;
import co.yixiang.exception.ErrorRequestException;
import co.yixiang.modules.order.service.YxStoreOrderService;
import co.yixiang.modules.security.security.JwtUser;
import co.yixiang.modules.security.utils.JwtTokenUtil;
import co.yixiang.modules.user.entity.YxUser;
import co.yixiang.modules.user.entity.YxWechatUser;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.modules.user.service.YxWechatUserService;
import co.yixiang.modules.user.web.vo.YxUserQueryVo;
import co.yixiang.mp.utils.JsonUtils;
import co.yixiang.utils.EncryptUtils;
import co.yixiang.utils.OrderUtil;
import co.yixiang.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;
import me.chanjar.weixin.common.error.WxErrorException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
/**
* 微信小程序用户接口
*
* @author xuwenbo
*/
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WxMaUserController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final WxMaService wxMaService;
private final YxWechatUserService wechatUserService;
private final YxUserService userService;
private final JwtTokenUtil jwtTokenUtil;
@Autowired
@Qualifier("jwtUserDetailsService")
private UserDetailsService userDetailsService;
/**
* 小程序登陆接口
*/
@PostMapping("/wechat/mp_auth")
public ApiResult<Object> login(@RequestParam(value = "code") String code,
@RequestParam(value = "spread") String spread,
@RequestParam(value = "encryptedData") String encryptedData,
@RequestParam(value = "iv") String iv ) {
if (StringUtils.isBlank(code)) {
return ApiResult.fail("empty jscode");
}
try {
//读取redis配置
String appId = RedisUtil.get("wxapp_appId");
String secret = RedisUtil.get("wxapp_secret");
if(StrUtil.isBlank(appId) || StrUtil.isBlank(secret)){
throw new ErrorRequestException("请先配置小程序");
}
WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
wxMaConfig.setAppid(appId);
wxMaConfig.setSecret(secret);
wxMaService.setWxMaConfig(wxMaConfig);
WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
YxWechatUser wechatUser = wechatUserService.getUserInfo(session.getOpenid());;
JwtUser jwtUser = null;
if(ObjectUtil.isNotNull(wechatUser)){
YxUserQueryVo yxUserQueryVo = userService.getYxUserById(wechatUser.getUid());
if(ObjectUtil.isNotNull(yxUserQueryVo)){
jwtUser = (JwtUser) userDetailsService.loadUserByUsername(wechatUser.getOpenid());
}else{
if(ObjectUtil.isNotNull(wechatUser)){
wechatUserService.removeById(wechatUser.getUid());
}
if(ObjectUtil.isNotNull(yxUserQueryVo)){
userService.removeById(yxUserQueryVo.getUid());
}
return ApiResult.fail(ApiCode.FAIL_AUTH,"授权失败");
}
}else{
WxMaUserInfo wxMpUser = wxMaService.getUserService()
.getUserInfo(session.getSessionKey(), encryptedData, iv);
//用户保存
YxUser user = new YxUser();
user.setAccount(wxMpUser.getNickName());
user.setUsername(wxMpUser.getOpenId());
user.setPassword(EncryptUtils.encryptPassword("123456"));
user.setPwd(EncryptUtils.encryptPassword("123456"));
user.setPhone("");
user.setUserType("wechat");
user.setAddTime(OrderUtil.getSecondTimestampTwo());
user.setLastTime(OrderUtil.getSecondTimestampTwo());
user.setNickname(wxMpUser.getNickName());
user.setAvatar(wxMpUser.getAvatarUrl());
user.setNowMoney(BigDecimal.ZERO);
user.setBrokeragePrice(BigDecimal.ZERO);
user.setIntegral(BigDecimal.ZERO);
userService.save(user);
//保存微信用户
YxWechatUser yxWechatUser = new YxWechatUser();
// System.out.println("wxMpUser:"+wxMpUser);
yxWechatUser.setAddTime(OrderUtil.getSecondTimestampTwo());
yxWechatUser.setNickname(wxMpUser.getNickName());
yxWechatUser.setOpenid(wxMpUser.getOpenId());
int sub = 0;
yxWechatUser.setSubscribe(sub);
yxWechatUser.setSex(Integer.valueOf(wxMpUser.getGender()));
yxWechatUser.setLanguage(wxMpUser.getLanguage());
yxWechatUser.setCity(wxMpUser.getCity());
yxWechatUser.setProvince(wxMpUser.getProvince());
yxWechatUser.setCountry(wxMpUser.getCountry());
yxWechatUser.setHeadimgurl(wxMpUser.getAvatarUrl());
if(StrUtil.isNotEmpty(wxMpUser.getUnionId())){
yxWechatUser.setUnionid(wxMpUser.getUnionId());
}
yxWechatUser.setUid(user.getUid());
wechatUserService.save(yxWechatUser);
jwtUser = (JwtUser) userDetailsService.loadUserByUsername(wxMpUser.getOpenId());
}
//设置推广关系
if(StrUtil.isNotEmpty(spread) && !spread.equals("NaN")){
//System.out.println("spread:"+spread);
userService.setSpread(Integer.valueOf(spread),
jwtUser.getId().intValue());
}
// 生成令牌
final String token = jwtTokenUtil.generateToken(jwtUser);
Date expiresTime = jwtTokenUtil.getExpirationDateFromToken(token);
String expiresTimeStr = DateUtil.formatDateTime(expiresTime);
Map<String,String> map = new LinkedHashMap<>();
map.put("token",token);
map.put("expires_time",expiresTimeStr);
// 返回 token
return ApiResult.ok(map);
} catch (WxErrorException e) {
this.logger.error(e.getMessage(), e);
return ApiResult.fail(e.toString());
}
}
// /**
// * <pre>
// * 获取用户绑定手机号信息
// * </pre>
// */
// @GetMapping("/phone")
// public String phone(@PathVariable String appid, String sessionKey, String signature,
// String rawData, String encryptedData, String iv) {
//
// // 用户信息校验
// if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
// return "user check failed";
// }
//
// // 解密
// WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
//
// return JsonUtils.toJson(phoneNoInfo);
// }
}

View File

@ -2,8 +2,16 @@ server:
port: 8009
servlet:
context-path: /api
tomcat:
uri-encoding: UTF-8
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
freemarker:
check-template-location: false
profiles:
@ -48,27 +56,6 @@ mybatis-plus:
logic-not-delete-value: 1
mapper-locations: classpath*:mapper/**/*Mapper.xml
# 公众号配置(必填)
wx:
mp:
configs:
- appId: wxc061dee8806ff712
secret:
token: yshop
aesKey: yYuBUkC8BXImCXyu7O6hkzLj4TC5nxsWPfL4CQAZPNY
pay:
appId: wxc061dee8806ff712
mchId:
mchKey: dayouqiantuhupeng8638004yixiangt
subAppId:
subMchId:
keyPath:
miniapp:
appid: wxa82b5b7fcb0ec161
secret:
token:
aesKey:
msgDataFormat: JSON
logging:
level:
org.springframework.web: INFO

View File

@ -1,8 +1,10 @@
package co.yixiang.utils;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import javax.xml.crypto.Data;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -53,6 +55,15 @@ public class OrderUtil {
return Integer.valueOf(timestamp);
}
/**
* 获取精确到秒的时间戳
* @return
**/
public static int dateToTimestampT(DateTime date){
String timestamp = String.valueOf(date.getTime()/1000);
return Integer.valueOf(timestamp);
}
/**
* 获取订单状态名称
* @param paid

View File

@ -0,0 +1,145 @@
package co.yixiang.utils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
public class RedisUtil {
private static RedisTemplate<String,Object> redisTemplate = SpringContextUtils
.getBean("redisTemplate",RedisTemplate.class);
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public static boolean expire(String key,long time){
try {
if(time>0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效 失效时间为负数,说明该主键未设置失效时间(失效时间默认为-1
*/
public static long getExpire(String key){
return redisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false 不存在
*/
public static boolean hasKey(String key){
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public static void del(String ... key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key){
return key==null?null:(T)redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public static boolean set(String key,Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public static boolean set(String key,Object value,long time){
try {
if(time>0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增 此时value值必须为int类型 否则报错
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public static long incr(String key, long delta){
if(delta<0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public static long decr(String key, long delta){
if(delta<0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
}

View File

@ -0,0 +1,41 @@
package co.yixiang.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring Context 工具类
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
}

View File

@ -2,6 +2,7 @@ package co.yixiang.domain;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
/**
* 代码生成配置
@ -11,7 +12,7 @@ import javax.persistence.*;
@Data
@Entity
@Table(name = "gen_config")
public class GenConfig {
public class GenConfig implements Serializable {
@Id
private Long id;

View File

@ -23,16 +23,16 @@
<artifactId>wx-java-pay-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>co.yixiang</groupId>
<artifactId>yshop-common</artifactId>
<version>1.3</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.binarywang</groupId>-->
<!-- <artifactId>wx-java-miniapp-spring-boot-starter</artifactId>-->
<!-- <version>3.5.0</version>-->
<!-- </dependency>-->
</dependencies>

View File

@ -1,15 +1,19 @@
package co.yixiang.mp.config;
import cn.hutool.core.util.StrUtil;
import co.yixiang.mp.handler.*;
import co.yixiang.utils.RedisUtil;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.poi.util.StringUtil;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ -41,13 +45,40 @@ public class WxMpConfiguration {
private final SubscribeHandler subscribeHandler;
private final ScanHandler scanHandler;
private final WxMpProperties properties;
private final RedisHandler redisHandler;
@Bean
public WxMpService wxMpService() {
// 代码里 getConfigs()处报错的同学请注意仔细阅读项目说明你的IDE需要引入lombok插件
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
System.out.println(configs);
if (configs == null) {
final List<WxMpProperties.MpConfig> configs = new ArrayList<>();
WxMpProperties.MpConfig mpConfig = new WxMpProperties.MpConfig();
String appId = redisHandler.getVal("wechat_appid");
String secret = redisHandler.getVal("wechat_appsecret");
String token = redisHandler.getVal("wechat_token");
String aesKey = redisHandler.getVal("wechat_encodingaeskey");
if(StrUtil.isNotBlank(appId) && StrUtil.isNotBlank(secret)
&& StrUtil.isNotBlank(token) && StrUtil.isNotBlank(aesKey)) {
mpConfig.setAppId(appId);
mpConfig.setSecret(secret);
mpConfig.setToken(token);
mpConfig.setAesKey(aesKey);
System.out.println(mpConfig);
configs.add(mpConfig);
}else{
mpConfig.setAppId("111111");
mpConfig.setSecret("111111");
mpConfig.setToken("111111");
mpConfig.setAesKey("111111");
configs.add(mpConfig);
}
//System.out.println("configs:"+configs);
if (configs.isEmpty()) {
throw new RuntimeException("请先配置!");
}

View File

@ -1,8 +1,11 @@
package co.yixiang.mp.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.exception.BadRequestException;
import co.yixiang.mp.domain.YxArticle;
import co.yixiang.mp.service.YxArticleService;
import co.yixiang.mp.service.dto.YxArticleDTO;
import co.yixiang.mp.service.dto.YxArticleQueryCriteria;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -57,6 +60,7 @@ public class YxArticleController {
@DeleteMapping(value = "/yxArticle/{id}")
@PreAuthorize("hasAnyRole('ADMIN','YXARTICLE_ALL','YXARTICLE_DELETE')")
public ResponseEntity delete(@PathVariable Integer id){
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
yxArticleService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
@ -64,8 +68,10 @@ public class YxArticleController {
@ApiOperation(value = "发布文章")
@GetMapping(value = "/yxArticle/publish/{id}")
@PreAuthorize("hasAnyRole('ADMIN','YXARTICLE_ALL','YXARTICLE_DELETE')")
public ResponseEntity publish(@PathVariable Integer id){
//todo
public ResponseEntity publish(@PathVariable Integer id) throws Exception{
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
YxArticleDTO yxArticleDTO= yxArticleService.findById(id);
yxArticleService.uploadNews(yxArticleDTO);
return new ResponseEntity(HttpStatus.OK);
}

View File

@ -1,6 +1,8 @@
package co.yixiang.mp.controller;
import cn.hutool.core.util.StrUtil;
import co.yixiang.exception.BadRequestException;
import co.yixiang.mp.domain.YxCache;
import co.yixiang.mp.service.YxCacheService;
import co.yixiang.utils.OrderUtil;
@ -62,6 +64,7 @@ public class YxCacheController {
yxCacheService.create(yxCache);
}
System.out.println("menu:"+menu);
//创建菜单
try {

View File

@ -1,6 +1,8 @@
package co.yixiang.mp.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.exception.BadRequestException;
import co.yixiang.mp.domain.YxWechatReply;
import co.yixiang.mp.service.YxWechatReplyService;
import com.alibaba.fastjson.JSON;
@ -39,6 +41,7 @@ public class YxWechatReplyController {
@PostMapping(value = "/yxWechatReply")
@PreAuthorize("hasAnyRole('ADMIN','YXWECHATREPLY_ALL','YXWECHATREPLY_CREATE')")
public ResponseEntity create(@RequestBody String jsonStr){
//if(StrUtil.isNotEmpty(jsonStr)) throw new BadRequestException("演示环境禁止操作");
JSONObject jsonObject = JSON.parseObject(jsonStr);
YxWechatReply yxWechatReply = new YxWechatReply();
YxWechatReply isExist = yxWechatReplyService.isExist(jsonObject.get("key").toString());

View File

@ -0,0 +1,31 @@
package co.yixiang.mp.handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisHandler{
@Autowired
RedisTemplate redisTemplate;
public String getVal(String key) {
try {
String value = redisTemplate.opsForValue().get(key).toString();
return value;
}catch (Exception e){
return "";
}
}
public Object getObj(String key) {
return redisTemplate.opsForValue().get(key);
}
}

View File

@ -31,9 +31,6 @@ public class SubscribeHandler extends AbstractHandler {
WxSessionManager sessionManager) throws WxErrorException {
//System.out.println("wxMessage:"+wxMessage);
//System.out.println("context:"+context);
YxWechatReply wechatReply = yxWechatReplyService.isExist("subscribe");
if(ObjectUtil.isNull(wechatReply)){
@ -42,15 +39,12 @@ public class SubscribeHandler extends AbstractHandler {
String str = JSONObject.parseObject(wechatReply.getData()).getString("content");
try {
//String str = new String(wechatReply.getData().getBytes(),"utf-8");
WxMpXmlOutMessage msg= WxMpXmlOutMessage.TEXT()
.content(str)
.fromUser(wxMessage.getToUser())
.toUser(wxMessage.getFromUser())
.build();
//System.out.println(msg);
return msg;
//return new TextBuilder().build(str, wxMessage, weixinService);
} catch (Exception e) {
this.logger.error(e.getMessage(), e);
}

View File

@ -62,4 +62,7 @@ public interface YxArticleService {
*/
//@CacheEvict(allEntries = true)
void delete(Integer id);
void uploadNews(YxArticleDTO yxArticleDTO) throws Exception;
}

View File

@ -70,4 +70,6 @@ public class YxArticleDTO implements Serializable {
// 是否轮播图(小程序)
private Integer isBanner;
private String thumbMediaId;
}

View File

@ -1,23 +1,42 @@
package co.yixiang.mp.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import co.yixiang.exception.ErrorRequestException;
import co.yixiang.mp.domain.YxArticle;
import co.yixiang.mp.repository.YxArticleRepository;
import co.yixiang.mp.service.YxArticleService;
import co.yixiang.mp.service.dto.YxArticleDTO;
import co.yixiang.mp.service.dto.YxArticleQueryCriteria;
import co.yixiang.mp.service.mapper.YxArticleMapper;
import co.yixiang.mp.utils.URLUtils;
import co.yixiang.utils.OrderUtil;
import co.yixiang.utils.PageUtil;
import co.yixiang.utils.QueryHelp;
import co.yixiang.utils.ValidationUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpMassTagMessage;
import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;
import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -26,6 +45,7 @@ import java.util.Optional;
* @author hupeng
* @date 2019-10-07
*/
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxArticleServiceImpl implements YxArticleService {
@ -36,6 +56,12 @@ public class YxArticleServiceImpl implements YxArticleService {
@Autowired
private YxArticleMapper yxArticleMapper;
@Autowired
private WxMpService wxMpService;
@Value("${file.path}")
private String uploadDirStr;
@Override
public Map<String,Object> queryAll(YxArticleQueryCriteria criteria, Pageable pageable){
Page<YxArticle> page = yxArticleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
@ -76,4 +102,97 @@ public class YxArticleServiceImpl implements YxArticleService {
public void delete(Integer id) {
yxArticleRepository.deleteById(id);
}
@Override
public void uploadNews(YxArticleDTO wxNewsArticleItem) throws Exception {
WxMpMaterialNews wxMpMaterialNews = new WxMpMaterialNews();
WxMpMaterialNews.WxMpMaterialNewsArticle article = new WxMpMaterialNews.WxMpMaterialNewsArticle();
WxMpMaterialUploadResult wxMpMaterialUploadResult = uploadPhotoToWx( wxMpService,
wxNewsArticleItem.getImageInput() );
wxNewsArticleItem.setThumbMediaId( wxMpMaterialUploadResult.getMediaId() );
article.setAuthor( wxNewsArticleItem.getAuthor() );
System.out.println(wxNewsArticleItem.getContent());
//处理content
String content = processContent(wxMpService, wxNewsArticleItem.getContent());
System.out.println(content);
article.setContent( content );
article.setContentSourceUrl( wxNewsArticleItem.getUrl() );
article.setDigest( wxNewsArticleItem.getSynopsis() );
article.setShowCoverPic( true );
article.setThumbMediaId( wxNewsArticleItem.getThumbMediaId() );
article.setTitle( wxNewsArticleItem.getTitle() );
//TODO 暂时注释掉,测试号没有留言权限
//article.setNeedOpenComment( wxNewsArticleItem );
//article.setOnlyFansCanComment( wxNewsArticleItem );
wxMpMaterialNews.addArticle( article );
log.info( "wxMpMaterialNews : {}", JSONUtil.toJsonStr( wxMpMaterialNews ) );
WxMpMaterialUploadResult wxMpMaterialUploadResult1 = wxMpService.getMaterialService()
.materialNewsUpload( wxMpMaterialNews );
//推送开始
WxMpMassTagMessage massMessage = new WxMpMassTagMessage();
massMessage.setMsgType(WxConsts.MassMsgType.MPNEWS);
massMessage.setMediaId(wxMpMaterialUploadResult1.getMediaId());
massMessage.setSendAll(true);
WxMpMassSendResult massResult = wxMpService.getMassMessageService()
.massGroupMessageSend(massMessage);
if(!massResult.getErrorCode().equals("0")) {
log.info("error:"+massResult.getErrorMsg());
throw new ErrorRequestException("发送失败");
}
log.info( "massResult : {}", JSONUtil.toJsonStr( massResult ) );
log.info( "wxMpMaterialUploadResult : {}", JSONUtil.toJsonStr( wxMpMaterialUploadResult1 ) );
}
private WxMpMaterialUploadResult uploadPhotoToWx(WxMpService wxMpService, String picPath) throws WxErrorException {
WxMpMaterial wxMpMaterial = new WxMpMaterial();
String filename = String.valueOf( System.currentTimeMillis() ) + ".png";
String downloadPath = uploadDirStr + filename;
long size = HttpUtil.downloadFile(picPath, FileUtil.file(downloadPath));
picPath = downloadPath;
File picFile = new File( picPath );
wxMpMaterial.setFile( picFile );
wxMpMaterial.setName( picFile.getName() );
log.info( "picFile name : {}", picFile.getName() );
WxMpMaterialUploadResult wxMpMaterialUploadResult = wxMpService.getMaterialService().materialFileUpload( WxConsts.MediaFileType.IMAGE, wxMpMaterial );
log.info( "wxMpMaterialUploadResult : {}", JSONUtil.toJsonStr( wxMpMaterialUploadResult ) );
return wxMpMaterialUploadResult;
}
private String processContent(WxMpService wxMpService,String content) throws WxErrorException {
if(StringUtils.isBlank( content )){
return content;
}
String imgReg = "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";
List<String> imgList = ReUtil.findAllGroup1( imgReg,content);
for (int j = 0; j < imgList.size(); j++) {
String imgSrc = imgList.get( j );
String filepath = URLUtils.getParam( imgSrc,"filepath" );
if(StringUtils.isBlank( filepath )){//网络图片URL需下载到本地
String filename = String.valueOf( System.currentTimeMillis() ) + ".png";
String downloadPath = uploadDirStr + filename;
long size = HttpUtil.downloadFile(imgSrc, FileUtil.file(downloadPath));
filepath = downloadPath;
}
WxMediaImgUploadResult wxMediaImgUploadResult = wxMpService.getMaterialService().mediaImgUpload( new File(filepath) );
content = StringUtils.replace( content,imgList.get( j ),wxMediaImgUploadResult.getUrl());
}
return content;
}
}

View File

@ -0,0 +1,76 @@
package co.yixiang.mp.utils;
import java.util.HashMap;
import java.util.Map;
/**
* URLUtils
* @author Kevin
* @date 2019-03-20 13:39
*/
public class URLUtils {
/**
* 获取URL中的某个参数
* @param url
* @param name
* @return
*/
public static String getParam(String url, String name) {
return urlSplit(url).get( name );
}
/**
* 去掉url中的路径留下请求参数部分
* @param strURL url地址
* @return url请求参数部分
*/
private static String truncateUrlPage(String strURL){
String strAllParam=null;
String[] arrSplit=null;
strURL=strURL.trim().toLowerCase();
arrSplit=strURL.split("[?]");
if(strURL.length()>1){
if(arrSplit.length>1){
for (int i=1;i<arrSplit.length;i++){
strAllParam = arrSplit[i];
}
}
}
return strAllParam;
}
/**
* 解析出url参数中的键值对
* 如 "index.jsp?Action=del&id=123"解析出Action:del,id:123存入map中
* @param URL url地址
* @return url请求参数部分
*/
public static Map<String, String> urlSplit(String URL){
Map<String, String> mapRequest = new HashMap<String, String>();
String[] arrSplit=null;
String strUrlParam= truncateUrlPage(URL);
if(strUrlParam==null){
return mapRequest;
}
arrSplit=strUrlParam.split("[&]");
for(String strSplit:arrSplit){
String[] arrSplitEqual=null;
arrSplitEqual= strSplit.split("[=]");
//解析出键值
if(arrSplitEqual.length>1){
//正确解析
mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
}else{
if(arrSplitEqual[0]!=""){
//只有参数没有值,不加入
mapRequest.put(arrSplitEqual[0], "");
}
}
}
return mapRequest;
}
}

View File

@ -2,10 +2,16 @@ package co.yixiang.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import java.util.List;
/**
* WebMvcConfigurer
@ -41,4 +47,6 @@ public class ConfigurerAdapter implements WebMvcConfigurer {
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
}
}

View File

@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -38,6 +39,8 @@ public class RedisServiceImpl implements RedisService {
if (s.toString().indexOf("role::loadPermissionByUser") != -1 || s.toString().indexOf("user::loadUserByUsername") != -1) {
continue;
}
DataType dataType = redisTemplate.type(s.toString());
if(dataType.code().equals("hash")) continue;
RedisVo redisVo = new RedisVo(s.toString(),redisTemplate.opsForValue().get(s.toString()).toString());
redisVos.add(redisVo);
}

View File

@ -1,8 +1,12 @@
package co.yixiang.modules.shop.repository;
import co.yixiang.modules.shop.domain.YxStoreOrder;
import co.yixiang.modules.shop.service.dto.ChartDataDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author hupeng
@ -10,6 +14,36 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
*/
public interface YxStoreOrderRepository extends JpaRepository<YxStoreOrder, Integer>, JpaSpecificationExecutor {
//今天 //上周 //本月
int countByPayTimeGreaterThanEqual(int time);
//昨天
int countByPayTimeLessThanAndPayTimeGreaterThanEqual(int timeO,int timeT);
@Query(value = "select IFNULL(sum(pay_price),0) from yx_store_order " +
"where refund_status=0 and is_del=0 and paid=1 and pay_time >= ?1",nativeQuery = true)
double sumPrice(Integer time);
@Query(value = "select IFNULL(sum(pay_price),0) from yx_store_order " +
"where refund_status=0 and is_del=0 and paid=1 and pay_time >= ?1 and pay_time < ?2",nativeQuery = true)
double sumTPrice(Integer timeO,Integer timeT);
@Query(value = "SELECT IFNULL(sum(pay_price),0) as num," +
"FROM_UNIXTIME(add_time, '%m-%d') as time " +
" FROM yx_store_order where refund_status=0 and is_del=0 and paid=1 and pay_time >= ?1" +
" GROUP BY FROM_UNIXTIME(add_time,'%Y-%m-%d') " +
" ORDER BY add_time ASC",nativeQuery = true)
List<ChartDataDTO> chartList(Integer time);
@Query(value = "SELECT count(id) as num," +
"FROM_UNIXTIME(add_time, '%m-%d') as time " +
" FROM yx_store_order where refund_status=0 and is_del=0 and paid=1 and pay_time >= ?1" +
" GROUP BY FROM_UNIXTIME(add_time,'%Y-%m-%d') " +
" ORDER BY add_time ASC",nativeQuery = true)
List<ChartDataDTO> chartListT(Integer time);
/**
* findByUnique
* @param unique

View File

@ -36,6 +36,8 @@ public class YxStoreCategoryController {
@GetMapping(value = "/yxStoreCategory")
@PreAuthorize("hasAnyRole('ADMIN','YXSTORECATEGORY_ALL','YXSTORECATEGORY_SELECT')")
public ResponseEntity getYxStoreCategorys(YxStoreCategoryQueryCriteria criteria, Pageable pageable){
List<YxStoreCategoryDTO> categoryDTOList = yxStoreCategoryService.queryAll(criteria);
return new ResponseEntity(yxStoreCategoryService.buildTree(categoryDTOList),HttpStatus.OK);
}

View File

@ -33,6 +33,19 @@ public class YxStoreOrderController {
@Autowired
private YxStoreOrderStatusService yxStoreOrderStatusService;
@GetMapping(value = "/data/count")
//@PreAuthorize("hasAnyRole('ADMIN','YXSTOREORDER_ALL','YXSTOREORDER_SELECT')")
public ResponseEntity getCount(){
return new ResponseEntity(yxStoreOrderService.getOrderTimeData(),HttpStatus.OK);
}
@GetMapping(value = "/data/chart")
//@PreAuthorize("hasAnyRole('ADMIN','YXSTOREORDER_ALL','YXSTOREORDER_SELECT')")
public ResponseEntity getChart(){
return new ResponseEntity(yxStoreOrderService.chartCount(),HttpStatus.OK);
}
@ApiOperation(value = "查询订单")
@GetMapping(value = "/yxStoreOrder")

View File

@ -58,6 +58,7 @@ public class YxStoreProductController {
@PutMapping(value = "/yxStoreProduct")
@PreAuthorize("hasAnyRole('ADMIN','YXSTOREPRODUCT_ALL','YXSTOREPRODUCT_EDIT')")
public ResponseEntity update(@Validated @RequestBody YxStoreProduct resources){
//if(ObjectUtil.isNotNull(resources)) throw new BadRequestException("演示环境禁止操作");
yxStoreProductService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@ -106,6 +107,7 @@ public class YxStoreProductController {
@ApiOperation(value = "清除属性")
@PostMapping(value = "/yxStoreProduct/clearAttr/{id}")
public ResponseEntity clearAttr(@PathVariable Integer id){
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
yxStoreProductService.clearProductAttr(id,true);
return new ResponseEntity(HttpStatus.OK);
}

View File

@ -1,6 +1,7 @@
package co.yixiang.modules.shop.service;
import co.yixiang.modules.shop.domain.YxStoreOrder;
import co.yixiang.modules.shop.service.dto.OrderTimeDataDTO;
import co.yixiang.modules.shop.service.dto.YxStoreOrderDTO;
import co.yixiang.modules.shop.service.dto.YxStoreOrderQueryCriteria;
import org.springframework.data.domain.Pageable;
@ -13,6 +14,9 @@ import java.util.List;
*/
//@CacheConfig(cacheNames = "yxStoreOrder")
public interface YxStoreOrderService {
OrderTimeDataDTO getOrderTimeData();
Map<String,Object> chartCount();
String orderType(int id,int pinkId,int combinationId);

View File

@ -0,0 +1,19 @@
package co.yixiang.modules.shop.service.dto;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import java.io.Serializable;
/**
* @ClassName ChartDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
//@Data
public interface ChartDataDTO{
// @Value("#{target.adminCount}")
Double getNum();
String getTime();
}

View File

@ -0,0 +1,23 @@
package co.yixiang.modules.shop.service.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @ClassName OrderTimeDataDTO
* @Author hupeng <610796224@qq.com>
* @Date 2019/11/25
**/
@Data
public class OrderTimeDataDTO implements Serializable {
private Double todayPrice; //今日成交额
private Integer todayCount; //今日订单数
private Double proPrice; //昨日成交额
private Integer proCount;//昨日订单数
private Double monthPrice;//本月成交额
private Integer monthCount;//本月订单数
private Integer lastWeekCount;//上周
private Double lastWeekPrice; //上周
}

View File

@ -17,9 +17,7 @@ import co.yixiang.modules.shop.service.YxStoreOrderService;
import co.yixiang.modules.shop.service.YxStoreOrderStatusService;
import co.yixiang.modules.shop.service.YxUserBillService;
import co.yixiang.modules.shop.service.YxUserService;
import co.yixiang.modules.shop.service.dto.YxStoreOrderDTO;
import co.yixiang.modules.shop.service.dto.YxStoreOrderQueryCriteria;
import co.yixiang.modules.shop.service.dto.YxUserDTO;
import co.yixiang.modules.shop.service.dto.*;
import co.yixiang.modules.shop.service.mapper.YxStoreOrderMapper;
import co.yixiang.utils.OrderUtil;
import co.yixiang.utils.QueryHelp;
@ -27,7 +25,6 @@ import co.yixiang.utils.ValidationUtil;
import com.alibaba.fastjson.JSON;
import co.yixiang.modules.shop.domain.StoreOrderCartInfo;
import co.yixiang.modules.shop.repository.YxStoreOrderCartInfoRepository;
import co.yixiang.modules.shop.service.dto.StoreOrderCartInfoDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
@ -70,6 +67,44 @@ public class YxStoreOrderServiceImpl implements YxStoreOrderService {
@Autowired
private YxStorePinkRepository storePinkRepository;
@Override
public OrderTimeDataDTO getOrderTimeData() {
int today = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(new Date()));
int yesterday = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(DateUtil.
yesterday()));
int lastWeek = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(DateUtil.lastWeek()));
int nowMonth = OrderUtil.dateToTimestampT(DateUtil
.beginOfMonth(new Date()));
OrderTimeDataDTO orderTimeDataDTO = new OrderTimeDataDTO();
orderTimeDataDTO.setTodayCount(yxStoreOrderRepository.countByPayTimeGreaterThanEqual(today));
orderTimeDataDTO.setTodayPrice(yxStoreOrderRepository.sumPrice(today));
orderTimeDataDTO.setProCount(yxStoreOrderRepository
.countByPayTimeLessThanAndPayTimeGreaterThanEqual(today,yesterday));
orderTimeDataDTO.setProPrice(yxStoreOrderRepository.sumTPrice(today,yesterday));
orderTimeDataDTO.setLastWeekCount(yxStoreOrderRepository.countByPayTimeGreaterThanEqual(lastWeek));
orderTimeDataDTO.setLastWeekPrice(yxStoreOrderRepository.sumPrice(lastWeek));
orderTimeDataDTO.setMonthCount(yxStoreOrderRepository.countByPayTimeGreaterThanEqual(nowMonth));
orderTimeDataDTO.setMonthPrice(yxStoreOrderRepository.sumPrice(nowMonth));
return orderTimeDataDTO;
}
@Override
public Map<String, Object> chartCount() {
Map<String, Object> map = new LinkedHashMap<>();
int nowMonth = OrderUtil.dateToTimestampT(DateUtil
.beginOfMonth(new Date()));
map.put("chart",yxStoreOrderRepository.chartList(nowMonth));
map.put("chartT",yxStoreOrderRepository.chartListT(nowMonth));
return map;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refund(YxStoreOrder resources) {

View File

@ -102,7 +102,7 @@ public class RoleController {
@PutMapping(value = "/roles/menu")
@PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_EDIT')")
public ResponseEntity updateMenu(@RequestBody Role resources){
//if(ObjectUtil.isNotNull(resources)) throw new BadRequestException("演示环境禁止操作");
//
roleService.updateMenu(resources,roleService.findById(resources.getId()));
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@ -111,7 +111,7 @@ public class RoleController {
@DeleteMapping(value = "/roles/{id}")
@PreAuthorize("hasAnyRole('ADMIN','ROLES_ALL','ROLES_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
// if(id > 0) throw new BadRequestException("演示环境禁止操作");
try {
roleService.delete(id);
}catch (Throwable e){

View File

@ -162,6 +162,7 @@ public class UserController {
*/
@PostMapping(value = "/users/updateAvatar")
public ResponseEntity updateAvatar(@RequestParam MultipartFile file){
//if(ObjectUtil.isNotNull(file)) throw new BadRequestException("演示环境禁止操作");
userService.updateAvatar(file);
return new ResponseEntity(HttpStatus.OK);
}

View File

@ -2,6 +2,7 @@ package co.yixiang.modules.system.service.dto;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
@ -10,7 +11,7 @@ import java.util.List;
* @date 2018-12-17
*/
@Data
public class MenuDTO {
public class MenuDTO implements Serializable {
private Long id;

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.exception.BadRequestException;
import co.yixiang.modules.wechat.domain.YxSystemConfig;
import co.yixiang.utils.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import co.yixiang.aop.log.Log;
@ -51,6 +52,7 @@ public class YxSystemConfigController {
YxSystemConfig yxSystemConfigModel = new YxSystemConfig();
yxSystemConfigModel.setMenuName(key);
yxSystemConfigModel.setValue(value.toString());
RedisUtil.set(key,value.toString());
if(ObjectUtil.isNull(yxSystemConfig)){
yxSystemConfigService.create(yxSystemConfigModel);
}else{
@ -63,23 +65,6 @@ public class YxSystemConfigController {
return new ResponseEntity(HttpStatus.CREATED);
}
@Log("修改YxSystemConfig")
@ApiOperation(value = "修改YxSystemConfig")
@PutMapping(value = "/yxSystemConfig")
@PreAuthorize("hasAnyRole('ADMIN','YXSYSTEMCONFIG_ALL','YXSYSTEMCONFIG_EDIT')")
public ResponseEntity update(@Validated @RequestBody YxSystemConfig resources){
//if(ObjectUtil.isNotNull(resources)) throw new BadRequestException("演示环境禁止操作");
yxSystemConfigService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log("删除YxSystemConfig")
@ApiOperation(value = "删除YxSystemConfig")
@DeleteMapping(value = "/yxSystemConfig/{id}")
@PreAuthorize("hasAnyRole('ADMIN','YXSYSTEMCONFIG_ALL','YXSYSTEMCONFIG_DELETE')")
public ResponseEntity delete(@PathVariable Integer id){
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
yxSystemConfigService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
}

View File

@ -35,7 +35,9 @@ public class YxSystemConfigServiceImpl implements YxSystemConfigService {
@Override
public Map<String,Object> queryAll(YxSystemConfigQueryCriteria criteria, Pageable pageable){
Page<YxSystemConfig> page = yxSystemConfigRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
Page<YxSystemConfig> page = yxSystemConfigRepository
.findAll((root, criteriaQuery, criteriaBuilder)
-> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
return PageUtil.toPage(page.map(yxSystemConfigMapper::toDto));
}

View File

@ -1,6 +1,7 @@
server:
port: 8000
spring:
freemarker:
check-template-location: false
@ -34,17 +35,3 @@ code:
loginCode:
expiration: 2
# 公众号配置(必填)
wx:
mp:
configs:
- appId: wxc061dee8806ff712
secret:
token: yshop
aesKey: yYuBUkC8BXImCXyu7O6hkzLj4TC5nxsWPfL4CQAZPNY
# miniapp:
# appid: wx604d2ea4702620d2
# secret:
# token:
# aesKey:
# msgDataFormat: JSON