├── sell ├── README.md └── src │ ├── main │ ├── resources │ │ ├── application.yml │ │ ├── static │ │ │ ├── mp3 │ │ │ │ └── song.mp3 │ │ │ ├── pay.html │ │ │ └── api │ │ │ │ └── seller.json │ │ ├── templates │ │ │ ├── pay │ │ │ │ ├── success.ftl │ │ │ │ └── create.ftl │ │ │ ├── common │ │ │ │ ├── header.ftl │ │ │ │ ├── error.ftl │ │ │ │ ├── success.ftl │ │ │ │ └── nav.ftl │ │ │ ├── category │ │ │ │ ├── index.ftl │ │ │ │ └── list.ftl │ │ │ ├── order │ │ │ │ └── detail.ftl │ │ │ └── product │ │ │ │ └── index.ftl │ │ ├── mapper │ │ │ └── ProductCategoryMapper.xml │ │ ├── application-dev.yml │ │ ├── application-prod.yml │ │ └── logback-spring.xml │ └── java │ │ └── cn │ │ └── chenhaoxiang │ │ ├── enums │ │ ├── CodeEnum.java │ │ ├── PayStatusEnum.java │ │ ├── ProductStatusEnum.java │ │ ├── OrderStausEnum.java │ │ └── ResultEnum.java │ │ ├── exception │ │ ├── SellAuthorizeException.java │ │ ├── SellException.java │ │ └── ResponseBankException.java │ │ ├── constans │ │ ├── RedisConstans.java │ │ └── CookieConstant.java │ │ ├── service │ │ ├── PushMessageService.java │ │ ├── BuyerService.java │ │ ├── SellerService.java │ │ ├── SeckillService.java │ │ ├── PayService.java │ │ ├── impl │ │ │ ├── SellerServiceImpl.java │ │ │ ├── ProductCategoryServiceImpl.java │ │ │ ├── BuyerServiceImpl.java │ │ │ ├── PushMessageServiceImpl.java │ │ │ ├── SeckillServiceImpl.java │ │ │ └── PayServiceImpl.java │ │ ├── ProductCategoryService.java │ │ ├── OrderService.java │ │ ├── ProductInfoService.java │ │ └── RedisLock.java │ │ ├── dao │ │ ├── SellerInfoDao.java │ │ ├── OrderDetailDao.java │ │ ├── ProductInfoDao.java │ │ ├── ProductCategoryDao.java │ │ └── OrderMasterDao.java │ │ ├── dataObject │ │ ├── SellerInfo.java │ │ ├── OrderDetail.java │ │ ├── dao │ │ │ └── ProductCategoryMyBatisDao.java │ │ ├── ProductCategory.java │ │ ├── OrderMaster.java │ │ ├── ProductInfo.java │ │ └── mapper │ │ │ └── ProductCategoryMapper.java │ │ ├── SellApplication.java │ │ ├── utils │ │ ├── KeyUtil.java │ │ ├── MathUtil.java │ │ ├── EnumUtil.java │ │ ├── ResultVOUtil.java │ │ ├── JsonUtil.java │ │ ├── serializer │ │ │ └── Date2LongSerializer.java │ │ └── CookieUtil.java │ │ ├── dto │ │ ├── CartDTO.java │ │ └── OrderDTO.java │ │ ├── form │ │ ├── ProductCategoryForm.java │ │ ├── OrderForm.java │ │ └── ProductForm.java │ │ ├── config │ │ ├── ProjectUrlConfig.java │ │ ├── WechatAccountConfig.java │ │ ├── WechatMpConfig.java │ │ ├── WechatOpenConfig.java │ │ ├── WechatPayConfig.java │ │ └── WebSocketConfig.java │ │ ├── vo │ │ ├── ProductVO.java │ │ ├── ResultVO.java │ │ └── ProductInfoVO.java │ │ ├── converter │ │ ├── OrderMaster2OrderDTOConverter.java │ │ └── OrderForm2OrderDTOConverter.java │ │ ├── controller │ │ ├── WeixinController.java │ │ ├── SeckullController.java │ │ ├── PayController.java │ │ ├── SellerCategoryController.java │ │ ├── SellerUserController.java │ │ ├── BuyerProductController.java │ │ └── SellerOrderController.java │ │ ├── handler │ │ ├── HandshakeInterceptor.java │ │ └── SellExceptionHandler.java │ │ └── aspect │ │ └── SellerAuthorizeAspect.java │ └── test │ └── java │ └── cn │ └── chenhaoxiang │ ├── SellApplicationTests.java │ ├── service │ └── impl │ │ ├── PushMessageServiceImplTest.java │ │ ├── SellerServiceImplTest.java │ │ ├── PayServiceImplTest.java │ │ ├── ProductCategoryServiceImplTest.java │ │ ├── ProductInfoServiceImplTest.java │ │ └── OrderServiceImplTest.java │ ├── dataObject │ ├── dao │ │ └── ProductCategoryDaoTest.java │ └── mapper │ │ └── ProductCategoryMapperTest.java │ ├── LoggerTest.java │ └── dao │ ├── SellerInfoDaoTest.java │ ├── OrderDetailDaoTest.java │ ├── ProductInfoDaoTest.java │ ├── OrderMasterDaoTest.java │ └── ProductCategoryDaoTest.java ├── .gitignore ├── javadoc └── sell │ ├── javadoc.bat │ ├── packages │ ├── package-list │ ├── script.js │ ├── cn │ └── chenhaoxiang │ │ ├── package-frame.html │ │ ├── aspect │ │ └── package-frame.html │ │ ├── dataObject │ │ ├── dao │ │ │ └── package-frame.html │ │ ├── mapper │ │ │ └── package-frame.html │ │ └── package-frame.html │ │ ├── utils │ │ ├── serializer │ │ │ └── package-frame.html │ │ └── package-frame.html │ │ ├── dto │ │ └── package-frame.html │ │ ├── handler │ │ └── package-frame.html │ │ ├── vo │ │ └── package-frame.html │ │ ├── converter │ │ └── package-frame.html │ │ ├── constans │ │ └── package-frame.html │ │ ├── form │ │ └── package-frame.html │ │ ├── exception │ │ └── package-frame.html │ │ ├── enums │ │ └── package-frame.html │ │ ├── config │ │ └── package-frame.html │ │ ├── dao │ │ ├── package-frame.html │ │ └── package-use.html │ │ ├── service │ │ ├── impl │ │ │ └── package-frame.html │ │ └── package-frame.html │ │ ├── controller │ │ └── package-frame.html │ │ └── package-use.html │ ├── index.html │ ├── overview-frame.html │ └── deprecated-list.html ├── commit-to-master.sh ├── README.md └── API.md /sell/README.md: -------------------------------------------------------------------------------- 1 | 微信点餐系统 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ IDEA ### 2 | /sell/.idea 3 | *.iws 4 | *.iml 5 | *.ipr 6 | 7 | /sell/target -------------------------------------------------------------------------------- /javadoc/sell/javadoc.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files\Java\jdk1.8.0_31\jre\..\bin\javadoc.exe" @options @packages -------------------------------------------------------------------------------- /sell/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: dev 4 | # 默认的配置文件 -------------------------------------------------------------------------------- /sell/src/main/resources/static/mp3/song.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenhaoxiang/WeChatOrderSystem/HEAD/sell/src/main/resources/static/mp3/song.mp3 -------------------------------------------------------------------------------- /sell/src/main/resources/templates/pay/success.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/common/header.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 卖家后端管理系统 4 | 5 | 6 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/enums/CodeEnum.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.enums; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/21. 7 | * Time: 下午 7:45. 8 | * Explain: 9 | */ 10 | public interface CodeEnum { 11 | T getCode(); 12 | } 13 | -------------------------------------------------------------------------------- /commit-to-master.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | git checkout master 3 | git add . 4 | echo 请输入本次提交的注释 如输入空白字符则使用"commit" 5 | read -t 600 var 6 | #会读取一行到var变量 7 | if [ -z $var ];then 8 | echo 未输入注释 空白注释 9 | git commit -am "commit" 10 | else 11 | echo commit is $var 12 | git commit -am "$var" 13 | fi 14 | git push origin master 15 | sleep 15 -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/exception/SellAuthorizeException.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.exception; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/24. 7 | * Time: 下午 8:39. 8 | * Explain: 校验的异常类 9 | */ 10 | public class SellAuthorizeException extends RuntimeException{ 11 | } 12 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/constans/RedisConstans.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.constans; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/24. 7 | * Time: 下午 7:55. 8 | * Explain: Redis常量 9 | */ 10 | public interface RedisConstans { 11 | /** 12 | * token前缀 13 | */ 14 | String TOKEN_PREFIX="token_%s"; 15 | /** 16 | * 过期时间 17 | */ 18 | Integer EXPIPE = 7200; //单位s 19 | 20 | } 21 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/SellApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SellApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/PushMessageService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/24. 9 | * Time: 下午 9:23. 10 | * Explain: 推送消息 11 | */ 12 | public interface PushMessageService { 13 | 14 | /** 15 | * 订单状态变更消息推送 16 | * @param orderDTO 17 | */ 18 | void orderStatus(OrderDTO orderDTO); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/constans/CookieConstant.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.constans; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/24. 7 | * Time: 下午 8:04. 8 | * Explain: Cookie常量 9 | */ 10 | public interface CookieConstant { 11 | 12 | /** 13 | * token的Cookie name 14 | */ 15 | String TOKEN = "token"; 16 | /** 17 | * 过期时间 18 | * 单位:s 19 | */ 20 | Integer EXPIPE = 7200; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dao/SellerInfoDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.SellerInfo; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/23. 10 | * Time: 下午 10:50. 11 | * Explain: 12 | */ 13 | public interface SellerInfoDao extends JpaRepository{ 14 | SellerInfo findByOpenid(String openid); 15 | } 16 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/BuyerService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/16. 9 | * Time: 下午 8:51. 10 | * Explain: 买家Service 11 | */ 12 | public interface BuyerService { 13 | 14 | //查询一个订单 15 | OrderDTO findOrderOne(String openid,String orderId); 16 | 17 | //取消订单 18 | OrderDTO cancelOrder(String openid,String orderId); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/SellerService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dataObject.SellerInfo; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/24. 9 | * Time: 下午 6:47. 10 | * Explain: 卖家端service 11 | */ 12 | public interface SellerService { 13 | 14 | /** 15 | * 通过openid查询卖家端信息 16 | * @param openid 17 | * @return 18 | */ 19 | SellerInfo findSellerInfoByOpenid(String openid); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/SellerInfo.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/23. 12 | * Time: 下午 10:48. 13 | * Explain: 卖家信息 14 | */ 15 | @Data 16 | @Entity 17 | public class SellerInfo { 18 | @Id 19 | private String sellerId; 20 | 21 | private String username; 22 | 23 | private String password; 24 | 25 | private String openid; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/SeckillService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/26. 7 | * Time: 下午 9:28. 8 | * Explain: 9 | */ 10 | public interface SeckillService { 11 | 12 | /** 13 | * 查询特价商品 14 | * @param productId 15 | * @return 16 | */ 17 | String querySecKillProductInfo(String productId); 18 | 19 | /** 20 | * 秒杀的逻辑方法 21 | * @param productId 22 | */ 23 | void orderProductMocckDiffUser(String productId); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /javadoc/sell/packages: -------------------------------------------------------------------------------- 1 | cn.chenhaoxiang.aspect 2 | cn.chenhaoxiang.config 3 | cn.chenhaoxiang.constans 4 | cn.chenhaoxiang.controller 5 | cn.chenhaoxiang.converter 6 | cn.chenhaoxiang.dao 7 | cn.chenhaoxiang.dataObject.dao 8 | cn.chenhaoxiang.dataObject.mapper 9 | cn.chenhaoxiang.dataObject 10 | cn.chenhaoxiang.dto 11 | cn.chenhaoxiang.enums 12 | cn.chenhaoxiang.exception 13 | cn.chenhaoxiang.form 14 | cn.chenhaoxiang.handler 15 | cn.chenhaoxiang 16 | cn.chenhaoxiang.service 17 | cn.chenhaoxiang.service.impl 18 | cn.chenhaoxiang.utils 19 | cn.chenhaoxiang.utils.serializer 20 | cn.chenhaoxiang.vo -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/SellApplication.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cache.annotation.EnableCaching; 6 | 7 | @SpringBootApplication 8 | //@MapperScan(basePackages = {"cn.chenhaoxiang.dataObject.mapper"})//配置mybatis mapper扫描路径 9 | @EnableCaching //缓存支持 配置Redis缓存需要的 10 | public class SellApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(SellApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /javadoc/sell/package-list: -------------------------------------------------------------------------------- 1 | cn.chenhaoxiang 2 | cn.chenhaoxiang.aspect 3 | cn.chenhaoxiang.config 4 | cn.chenhaoxiang.constans 5 | cn.chenhaoxiang.controller 6 | cn.chenhaoxiang.converter 7 | cn.chenhaoxiang.dao 8 | cn.chenhaoxiang.dataObject 9 | cn.chenhaoxiang.dataObject.dao 10 | cn.chenhaoxiang.dataObject.mapper 11 | cn.chenhaoxiang.dto 12 | cn.chenhaoxiang.enums 13 | cn.chenhaoxiang.exception 14 | cn.chenhaoxiang.form 15 | cn.chenhaoxiang.handler 16 | cn.chenhaoxiang.service 17 | cn.chenhaoxiang.service.impl 18 | cn.chenhaoxiang.utils 19 | cn.chenhaoxiang.utils.serializer 20 | cn.chenhaoxiang.vo 21 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/enums/PayStatusEnum.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/14. 9 | * Time: 下午 9:04. 10 | * Explain: 支付状态 11 | */ 12 | @Getter 13 | public enum PayStatusEnum implements CodeEnum{ 14 | WAIT(0,"等待支付"), 15 | SUCCESS(1,"支付成功"), 16 | ; 17 | 18 | private Integer code; 19 | 20 | private String message; 21 | 22 | PayStatusEnum(Integer code, String message) { 23 | this.code = code; 24 | this.message = message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/enums/ProductStatusEnum.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/9. 9 | * Time: 下午 7:16. 10 | * Explain: 商品状态 11 | */ 12 | @Getter //自动生成getter方法 13 | public enum ProductStatusEnum implements CodeEnum { 14 | UP(0,"在架"), 15 | DOWN(1,"下架") 16 | ; 17 | private Integer code; 18 | 19 | private String message; 20 | 21 | ProductStatusEnum(Integer code,String message) { 22 | this.code = code; 23 | this.message=message; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dao/OrderDetailDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderDetail; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/14. 12 | * Time: 下午 9:14. 13 | * Explain: 14 | */ 15 | public interface OrderDetailDao extends JpaRepository { 16 | 17 | /** 18 | * 查询订单详情 - 根据订单id 19 | * @param orderId 20 | * @return 21 | */ 22 | List findByOrderId(String orderId); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/KeyUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/14. 9 | * Time: 下午 10:56. 10 | * Explain: 11 | */ 12 | public class KeyUtil { 13 | 14 | /** 15 | * 生成唯一主键 16 | * 格式:时间+随机数 17 | * @return 18 | */ 19 | public static synchronized String getUniqueKey(){//加一个锁 20 | Random random = new Random(); 21 | Integer number = random.nextInt(900000) + 100000;//随机六位数 22 | return System.currentTimeMillis()+String.valueOf(number); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/MathUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: 陈浩翔. 6 | * Date: 2018/1/20. 7 | * Time: 下午 11:42. 8 | * Explain: 9 | */ 10 | public class MathUtil { 11 | 12 | private static final Double MONEY_RANGE = 0.01; 13 | /** 14 | * 比较两个金额是否相等 15 | * @param d1 16 | * @param d2 17 | * @return 18 | */ 19 | public static Boolean equals(Double d1,Double d2){ 20 | Double result =Math.abs(d1-d2); 21 | if(result < MONEY_RANGE){ 22 | return true; 23 | }else { 24 | return false; 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dao/ProductInfoDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductInfo; 4 | import org.springframework.cache.annotation.Cacheable; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/9. 13 | * Time: 下午 6:58. 14 | * Explain: 15 | */ 16 | public interface ProductInfoDao extends JpaRepository { 17 | /** 18 | * 通过商品状态查询 19 | * @param productStatus 20 | * @return 21 | */ 22 | List findByProductStatus(Integer productStatus); 23 | } 24 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dto/CartDTO.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dto; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/14. 9 | * Time: 下午 11:06. 10 | * Explain:购物车 - 在Service层加减库存使用的 11 | */ 12 | @Data 13 | public class CartDTO { 14 | /** 15 | * 商品Id 16 | */ 17 | private String productId; 18 | 19 | /** 20 | * 数量 21 | */ 22 | private Integer productQuantity; 23 | 24 | public CartDTO() { 25 | } 26 | 27 | public CartDTO(String productId, Integer productQuantity) { 28 | this.productId = productId; 29 | this.productQuantity = productQuantity; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dao/ProductCategoryDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/8. 12 | * Time: 下午 10:05. 13 | * Explain: 14 | */ 15 | public interface ProductCategoryDao extends JpaRepository{//后面的是主键类型 16 | 17 | /** 18 | * 通过categoryType集合 查询出ProductCategory集合 19 | * @param categoryTypeList 20 | * @return 21 | */ 22 | List findByCategoryTypeIn(List categoryTypeList); 23 | } 24 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/form/ProductCategoryForm.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.form; 2 | 3 | import lombok.Data; 4 | import org.hibernate.validator.constraints.NotBlank; 5 | 6 | import javax.validation.constraints.NotNull; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/23. 12 | * Time: 下午 10:14. 13 | * Explain: 14 | */ 15 | @Data 16 | public class ProductCategoryForm { 17 | private Integer categoryId; 18 | /** 19 | * 类目名字 20 | */ 21 | @NotBlank(message = "类目名字不能为空") 22 | private String categoryName; 23 | /** 24 | * 类目编号 25 | */ 26 | @NotNull(message = "类目编号不能为空") 27 | private Integer categoryType; 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/exception/SellException.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.exception; 2 | 3 | import cn.chenhaoxiang.enums.ResultEnum; 4 | import lombok.Data; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/14. 10 | * Time: 下午 10:46. 11 | * Explain: 自定义异常 12 | */ 13 | @Data 14 | public class SellException extends RuntimeException{ 15 | 16 | private Integer code; 17 | 18 | public SellException(ResultEnum resultEnum) { 19 | super(resultEnum.getMessage()); 20 | this.code = resultEnum.getCode(); 21 | } 22 | 23 | 24 | public SellException(Integer code, String defaultMessage) { 25 | super(defaultMessage); 26 | this.code=code; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dao/OrderMasterDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderMaster; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/14. 12 | * Time: 下午 9:12. 13 | * Explain: 14 | */ 15 | public interface OrderMasterDao extends JpaRepository { 16 | 17 | /** 18 | * 按照买家的openid查询 19 | * 分页查询订单 20 | * @param buyerOpenid 21 | * @param pageable 22 | * @return 23 | */ 24 | Page findByBuyerOpenid(String buyerOpenid, Pageable pageable); 25 | } 26 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/EnumUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | import cn.chenhaoxiang.enums.CodeEnum; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/21. 9 | * Time: 下午 7:48. 10 | * Explain: 枚举工具类 11 | */ 12 | public class EnumUtil { 13 | /** 14 | * 通过code和枚举类型获取枚举 15 | * @param code code 16 | * @param enumClass 枚举类型class 17 | * @param 枚举类型 18 | * @return 19 | */ 20 | public static T getByCode(Integer code, Class enumClass){ 21 | for(T each: enumClass.getEnumConstants()){//遍历枚举类型 22 | if(each.getCode().equals(code)){ 23 | return each; 24 | } 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/exception/ResponseBankException.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.exception; 2 | 3 | import cn.chenhaoxiang.enums.ResultEnum; 4 | import lombok.Data; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/25. 10 | * Time: 下午 8:48. 11 | * Explain: 返回错误状态码的异常 出现该异常不返回200 12 | */ 13 | @Data 14 | public class ResponseBankException extends RuntimeException{ 15 | 16 | private Integer code; 17 | 18 | public ResponseBankException(ResultEnum resultEnum) { 19 | super(resultEnum.getMessage()); 20 | this.code = resultEnum.getCode(); 21 | } 22 | 23 | 24 | public ResponseBankException(Integer code, String defaultMessage) { 25 | super(defaultMessage); 26 | this.code=code; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/PayService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import com.lly835.bestpay.model.PayResponse; 5 | import com.lly835.bestpay.model.RefundResponse; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * User: 陈浩翔. 10 | * Date: 2018/1/19. 11 | * Time: 下午 9:25. 12 | * Explain: 支付 13 | */ 14 | public interface PayService { 15 | /** 16 | * 发起支付 17 | * @param orderDTO 18 | * @return 19 | */ 20 | PayResponse create(OrderDTO orderDTO); 21 | 22 | /** 23 | * 微信异步通知支付结果 24 | * @param notifyData 25 | */ 26 | PayResponse notify(String notifyData); 27 | 28 | /** 29 | * 退款 30 | * @param orderDTO 31 | */ 32 | RefundResponse refund(OrderDTO orderDTO); 33 | } 34 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/SellerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dao.SellerInfoDao; 4 | import cn.chenhaoxiang.dataObject.SellerInfo; 5 | import cn.chenhaoxiang.service.SellerService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/24. 13 | * Time: 下午 6:48. 14 | * Explain: 15 | */ 16 | @Service 17 | public class SellerServiceImpl implements SellerService { 18 | @Autowired 19 | private SellerInfoDao sellerInfoDao; 20 | @Override 21 | public SellerInfo findSellerInfoByOpenid(String openid) { 22 | return sellerInfoDao.findByOpenid(openid); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/ProjectUrlConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * User: 陈浩翔. 10 | * Date: 2018/1/24. 11 | * Time: 下午 7:15. 12 | * Explain: 配置文件中的url 13 | */ 14 | @Data 15 | @ConfigurationProperties(prefix = "projectUrl") 16 | @Component 17 | public class ProjectUrlConfig { 18 | 19 | /** 20 | * 微信公众平台授权Url 配置授权域即可 21 | */ 22 | public String wechatMpAuthorize; 23 | 24 | /** 25 | * 微信开放平台授权url 配置授权域即可 26 | */ 27 | public String wechatOpenAuthorize; 28 | 29 | /** 30 | * 本项目的地址 31 | */ 32 | public String project; 33 | } 34 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/vo/ProductVO.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/9. 13 | * Time: 下午 7:40. 14 | * Explain: 商品(包含类目) 15 | */ 16 | @Data 17 | public class ProductVO implements Serializable{ 18 | private static final long serialVersionUID = 1397557650534605111L; 19 | /** 20 | * 类目名 21 | */ 22 | @JsonProperty("name")//序列化返回给前端时,json里面的该字段名为name 23 | private String categoryName; 24 | @JsonProperty("type") 25 | private Integer categoryType; 26 | @JsonProperty("foods") 27 | private List productInfoVOList; 28 | } 29 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/vo/ResultVO.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/9. 12 | * Time: 下午 7:37. 13 | * Explain: http请求返回的最外层对象 14 | */ 15 | @Data 16 | //@JsonInclude(JsonInclude.Include.NON_NULL) //为null的属性不返回到前端, 也就是类转json 属性为NULL的不参加序列化 17 | public class ResultVO implements Serializable{ 18 | private static final long serialVersionUID = 4176441568338187710L;//实现序列化 19 | /** 20 | * 错误码 21 | */ 22 | private Integer code; 23 | /** 24 | * 提示信息 25 | */ 26 | private String msg; 27 | // private String msg = "";//赋予初始值 28 | 29 | /** 30 | * 返回的具体内容 31 | */ 32 | private T data; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/common/error.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 错误提示 5 | 6 | 7 | 8 |
9 |
10 |
11 |
12 | 13 |

14 | 注意! 15 |

${msg} 3s后自动跳转 16 |
17 |
18 |
19 |
20 | 21 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/vo/ProductInfoVO.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/9. 13 | * Time: 下午 7:46. 14 | * Explain: 商品详情 返回给前端的 15 | */ 16 | @Data 17 | public class ProductInfoVO implements Serializable{ 18 | private static final long serialVersionUID = 4177439763246797991L; 19 | @JsonProperty("id") 20 | private String productId; 21 | @JsonProperty("name") 22 | private String productName; 23 | @JsonProperty("price") 24 | private BigDecimal productPrice; 25 | @JsonProperty("description") 26 | private String productDescription; 27 | @JsonProperty("icon") 28 | private String productIcon; 29 | } 30 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/ResultVOUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | import cn.chenhaoxiang.vo.ResultVO; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/9. 9 | * Time: 下午 8:10. 10 | * Explain: 11 | */ 12 | public class ResultVOUtil { 13 | 14 | public static ResultVO success(Object object){ 15 | ResultVO resultVO = new ResultVO(); 16 | resultVO.setData(object); 17 | resultVO.setCode(0); 18 | resultVO.setMsg("成功"); 19 | return resultVO; 20 | } 21 | 22 | public static ResultVO success(){ 23 | return success(null); 24 | } 25 | 26 | public static ResultVO error(Integer code,String msg){ 27 | ResultVO resultVO = new ResultVO(); 28 | resultVO.setMsg(msg); 29 | resultVO.setCode(code); 30 | return resultVO; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/common/success.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 成功提示 5 | 6 | 7 | 8 |
9 |
10 |
11 |
12 | 13 |

14 | 注意! 15 | <#--如果模板的msg没有值,就给一个默认值--> 16 |

${msg!"操作成功"} 3s后自动跳转 17 |
18 |
19 |
20 |
21 | 22 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/20. 10 | * Time: 下午 5:38. 11 | * Explain: JSON工具类 12 | */ 13 | public class JsonUtil { 14 | /** 15 | * 对象转换成JSON格式字符串 并格式化 16 | * 类似输出: 17 | * { 18 | "payTypeEnum": "WXPAY_H5", 19 | "orderId": "1516104088756358983", 20 | "orderAmount": 40.0, 21 | "orderName": "微信点餐订单", 22 | "openid": "123456789" 23 | } 24 | * @param object 25 | * @return 26 | */ 27 | public static String toJson(Object object){ 28 | GsonBuilder gsonBuilder = new GsonBuilder(); 29 | gsonBuilder.setPrettyPrinting(); 30 | Gson gson = gsonBuilder.create(); 31 | return gson.toJson(object); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/serializer/Date2LongSerializer.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils.serializer; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.JsonSerializer; 6 | import com.fasterxml.jackson.databind.SerializerProvider; 7 | 8 | import java.io.IOException; 9 | import java.util.Date; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/16. 15 | * Time: 下午 8:14. 16 | * Explain: 让时间戳精度在秒 17 | */ 18 | public class Date2LongSerializer extends JsonSerializer {//Date类型对应OrderDTO中的时间的属性类型 19 | @Override 20 | public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { 21 | jsonGenerator.writeNumber(date.getTime() / 1000);//这个date是加了JsonSerialize注解的参数 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sell/src/main/resources/mapper/ProductCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /javadoc/sell/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang

14 |
15 |

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/form/OrderForm.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.form; 2 | 3 | import lombok.Data; 4 | import org.hibernate.validator.constraints.NotEmpty; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/16. 10 | * Time: 下午 7:27. 11 | * Explain: 进行表单验证的实体类 12 | * 参数就是前端传进来的参数 13 | */ 14 | @Data 15 | public class OrderForm { 16 | /** 17 | * 买家姓名 18 | */ 19 | @NotEmpty(message = "姓名必填") 20 | private String name; 21 | 22 | /** 23 | * 买家手机号 24 | */ 25 | @NotEmpty(message = "手机号必填") 26 | private String phone; 27 | 28 | /** 29 | * 买家地址 30 | */ 31 | @NotEmpty(message = "地址必填") 32 | private String address; 33 | 34 | /** 35 | * 买家微信openId 36 | */ 37 | @NotEmpty(message = "openid必填") 38 | private String openid; 39 | 40 | /** 41 | * 购物车 42 | */ 43 | @NotEmpty(message = "购物车不能为空") 44 | private String items; 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/ProductCategoryService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * User: 陈浩翔. 10 | * Date: 2018/1/9. 11 | * Time: 下午 6:38. 12 | * Explain: 类目 13 | */ 14 | public interface ProductCategoryService { 15 | 16 | /** 17 | * 查询一个 18 | * @param categoryId 19 | * @return 20 | */ 21 | ProductCategory findOne(Integer categoryId); 22 | 23 | /** 24 | * 查询所有 25 | * @return 26 | */ 27 | List findAll(); 28 | /** 29 | * 通过categoryType集合 查询出ProductCategory集合 30 | * @param categoryTypeList 31 | * @return 32 | */ 33 | List findByCategoryTypeIn(List categoryTypeList); 34 | 35 | /** 36 | * 更新和新增 37 | * @param productCategory 38 | * @return 39 | */ 40 | ProductCategory save(ProductCategory productCategory); 41 | } 42 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/aspect/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.aspect (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.aspect

14 |
15 |

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/OrderDetail.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/14. 13 | * Time: 下午 9:08. 14 | * Explain:订单详情 15 | */ 16 | @Entity 17 | @Data 18 | public class OrderDetail { 19 | 20 | @Id 21 | private String detailId; 22 | 23 | /** 24 | * 订单id 25 | */ 26 | private String orderId; 27 | 28 | /** 29 | * 商品Id 30 | */ 31 | private String productId; 32 | 33 | /** 34 | * 商品名称 35 | */ 36 | private String productName; 37 | 38 | /** 39 | * 单价 40 | * 千万不能从前端传过来。必须从数据库由我们自己取出来 41 | */ 42 | private BigDecimal productPrice; 43 | 44 | /** 45 | * 商品数量 46 | */ 47 | private Integer productQuantity; 48 | 49 | /** 50 | * 商品小图 51 | */ 52 | private String productIcon; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/dao/ProductCategoryMyBatisDao.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import cn.chenhaoxiang.dataObject.mapper.ProductCategoryMapper; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Repository; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * User: 陈浩翔. 15 | * Date: 2018/1/25. 16 | * Time: 下午 11:59. 17 | * Explain: 使用MyBatis的Dao测试 18 | */ 19 | @Repository 20 | public class ProductCategoryMyBatisDao { 21 | @Autowired 22 | private ProductCategoryMapper productCategoryMapper; 23 | 24 | public int insertByMap(Map map){ 25 | return productCategoryMapper.insertByMap(map); 26 | } 27 | 28 | public List findByCategoryName(String categoryName){ 29 | return productCategoryMapper.findByCategoryName(categoryName); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dataObject/dao/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.dataObject.dao (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.dataObject.dao

14 |
15 |

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/utils/serializer/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.utils.serializer (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.utils.serializer

14 |
15 |

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dto/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.dto (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.dto

14 |
15 |

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/PushMessageServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.service.OrderService; 5 | import cn.chenhaoxiang.service.PushMessageService; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * User: 陈浩翔. 15 | * Date: 2018/1/24. 16 | * Time: 下午 9:45. 17 | * Explain: 18 | */ 19 | @RunWith(SpringRunner.class) 20 | @SpringBootTest 21 | public class PushMessageServiceImplTest { 22 | 23 | @Autowired 24 | private PushMessageService pushMessageService; 25 | @Autowired 26 | private OrderService orderService; 27 | @Test 28 | public void orderStatus() throws Exception { 29 | OrderDTO orderDTO =orderService.findOne("1516538902199931605"); 30 | pushMessageService.orderStatus(orderDTO); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dataObject/mapper/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.dataObject.mapper (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.dataObject.mapper

14 |
15 |

接口

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/SellerServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dataObject.SellerInfo; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: 陈浩翔. 17 | * Date: 2018/1/24. 18 | * Time: 下午 6:49. 19 | * Explain: 20 | */ 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | @Slf4j 24 | public class SellerServiceImplTest { 25 | 26 | private static final String openid="abc"; 27 | @Autowired 28 | private SellerServiceImpl sellerService; 29 | @Test 30 | public void findSellerInfoByOpenid() throws Exception { 31 | SellerInfo result =sellerService.findSellerInfoByOpenid(openid); 32 | Assert.assertEquals(openid,result.getOpenid()); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/handler/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.handler (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.handler

14 |
15 |

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderMaster; 4 | import cn.chenhaoxiang.dto.OrderDTO; 5 | import org.springframework.data.domain.Page; 6 | import org.springframework.data.domain.Pageable; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: 陈浩翔. 11 | * Date: 2018/1/14. 12 | * Time: 下午 10:29. 13 | * Explain: 订单 14 | */ 15 | public interface OrderService { 16 | 17 | /** 18 | * 创建订单 19 | */ 20 | OrderDTO create(OrderDTO orderDTO); 21 | 22 | /** 23 | * 查询单个订单 24 | */ 25 | OrderDTO findOne(String orderId); 26 | 27 | /** 28 | * 查询订单列表 - 单个人 29 | */ 30 | Page findList(String buyerOpenid, Pageable pageable); 31 | 32 | /** 33 | * 分页查询订单列表 34 | */ 35 | Page findList(Pageable pageable); 36 | 37 | /** 38 | * 取消订单 39 | */ 40 | OrderDTO cancel(OrderDTO orderDTO); 41 | 42 | /** 43 | * 完结订单 44 | */ 45 | OrderDTO finish(OrderDTO orderDTO); 46 | 47 | /** 48 | * 支付订单 49 | */ 50 | OrderDTO paid(OrderDTO orderDTO); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/vo/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.vo (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.vo

14 |
15 |

16 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/enums/OrderStausEnum.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.enums; 2 | 3 | import lombok.Getter; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * User: 陈浩翔. 9 | * Date: 2018/1/14. 10 | * Time: 下午 9:00. 11 | * Explain: 订单状态 12 | */ 13 | @Getter 14 | public enum OrderStausEnum implements CodeEnum { 15 | NEW(0,"新订单"), 16 | FINISHED(1,"完结"), 17 | CANCEL(2,"已取消"), 18 | ; 19 | private Integer code; 20 | 21 | private String message; 22 | 23 | OrderStausEnum(Integer code, String message) { 24 | this.code = code; 25 | this.message = message; 26 | } 27 | 28 | /** 29 | * 通过cide获取订单状态枚举 30 | * 不能这么写,如果还有另外的枚举状态,就还得复制拷贝过去 31 | * 所以用实现接口和工具类来实现 32 | * @param code 33 | * @return 34 | */ 35 | // public static OrderStausEnum getOrderStatusEnum(Integer code){ 36 | // for(OrderStausEnum orderStausEnum:OrderStausEnum.values()){ 37 | // if(orderStausEnum.getCode().equals(code)){ 38 | // return orderStausEnum; 39 | // } 40 | // } 41 | // return null; 42 | // } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/converter/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.converter (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.converter

14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/constans/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.constans (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.constans

14 |
15 |

接口

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/form/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.form (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.form

14 |
15 |

16 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/form/ProductForm.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.form; 2 | 3 | import lombok.Data; 4 | import org.hibernate.validator.constraints.NotBlank; 5 | 6 | import javax.validation.constraints.NotNull; 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/23. 13 | * Time: 下午 9:27. 14 | * Explain: 商品字段 - 处理表单提交过来的字段 15 | */ 16 | @Data 17 | public class ProductForm { 18 | private String productId; 19 | /** 20 | * 名字 21 | * @NotBlank 注解用在String上 22 | * @NotEmpty 用在集合类上面 23 | * @NotNull 用在基本类型上 24 | */ 25 | @NotBlank(message = "商品名称不能为空") 26 | private String productName; 27 | 28 | /** 29 | * 单价 30 | */ 31 | @NotNull(message = "单价不能为空") 32 | private BigDecimal productPrice; 33 | 34 | /** 35 | * 库存 36 | */ 37 | @NotNull(message = "库存不能为空") 38 | private Integer productStock; 39 | /** 40 | * 描述 41 | */ 42 | private String productDescription; 43 | /** 44 | * 小图 45 | */ 46 | private String productIcon; 47 | /** 48 | * 类目编号 49 | */ 50 | @NotNull(message = "类目编号不能为空") 51 | private Integer categoryType; 52 | } 53 | -------------------------------------------------------------------------------- /sell/src/main/resources/static/pay.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/PayServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.service.OrderService; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: 陈浩翔. 17 | * Date: 2018/1/20. 18 | * Time: 下午 5:17. 19 | * Explain: 20 | */ 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | @Slf4j 24 | public class PayServiceImplTest { 25 | 26 | @Autowired 27 | private PayServiceImpl payService; 28 | 29 | @Autowired 30 | private OrderService orderService; 31 | @Test 32 | public void create() throws Exception { 33 | OrderDTO orderDTO = orderService.findOne("1516104088756358983"); 34 | payService.create(orderDTO); 35 | } 36 | 37 | @Test 38 | public void refund(){ 39 | OrderDTO orderDTO = orderService.findOne("1516104088756358983"); 40 | payService.refund(orderDTO); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/exception/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.exception (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.exception

14 |
15 |

异常错误

16 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dataObject/dao/ProductCategoryDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * User: 陈浩翔. 19 | * Date: 2018/1/26. 20 | * Time: 上午 12:07. 21 | * Explain: 进行简单的测试 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | @Slf4j 26 | public class ProductCategoryDaoTest { 27 | @Autowired 28 | private ProductCategoryMyBatisDao productCategoryMyBatisDao; 29 | @Test 30 | public void insertByMap() throws Exception { 31 | } 32 | 33 | @Test 34 | public void findByCategoryName() throws Exception { 35 | List productCategoryList =productCategoryMyBatisDao.findByCategoryName("美味的"); 36 | log.info("productCategoryList={}",productCategoryList); 37 | Assert.assertNotEquals(0,productCategoryList.size()); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/WechatAccountConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.net.ssl.SSLContext; 8 | import java.util.Map; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: 陈浩翔. 13 | * Date: 2018/1/18. 14 | * Time: 下午 7:53. 15 | * Explain:微信账号相关 16 | */ 17 | @Data 18 | @Component 19 | @ConfigurationProperties(prefix = "wechat") 20 | public class WechatAccountConfig { 21 | /** 22 | * 公众号appId 23 | */ 24 | private String mpAppId; 25 | /** 26 | * 公众号appSecret 27 | */ 28 | private String mpAppSecret; 29 | 30 | /** 31 | * 开放平台appId 32 | */ 33 | private String openAppId; 34 | /** 35 | * 开放平台appSecret 36 | */ 37 | private String openAppSecret; 38 | 39 | 40 | /** 41 | * 商户号 42 | */ 43 | private String mchId; 44 | 45 | /** 46 | * 商户密钥 47 | */ 48 | private String mchKey; 49 | 50 | /** 51 | * 商户证书路径 52 | */ 53 | private String keyPath; 54 | 55 | /** 56 | * 微信支付异步通知地址 57 | */ 58 | private String notifyUrl; 59 | 60 | /** 61 | * 模板消息Id 62 | */ 63 | private Map templateId; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/converter/OrderMaster2OrderDTOConverter.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.converter; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderMaster; 4 | import cn.chenhaoxiang.dto.OrderDTO; 5 | import org.springframework.beans.BeanUtils; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: 陈浩翔. 13 | * Date: 2018/1/15. 14 | * Time: 下午 6:35. 15 | * Explain: 转换器 16 | */ 17 | public class OrderMaster2OrderDTOConverter { 18 | 19 | /** 20 | * OrderMaster转换为OrderDTO 21 | * @param orderMaster 22 | * @return 23 | */ 24 | private static OrderDTO convert(OrderMaster orderMaster){ 25 | OrderDTO orderDTO = new OrderDTO(); 26 | BeanUtils.copyProperties(orderMaster,orderDTO); 27 | return orderDTO; 28 | } 29 | 30 | /** 31 | * lambda 32 | * List转换为List 33 | * @param orderMasterList 34 | * @return 35 | */ 36 | public static List convert(List orderMasterList){ 37 | return orderMasterList.stream().map(e->convert(e)) 38 | .collect(Collectors.toList()); 39 | //很容易理解,e其实就是遍历orderMasterList中的每一个OrderMaster,然后通过convert函数转换为OrderDTO 40 | //Collectors收集器可以被用来收集流的输出到一个集合,或者产生一个单一的值。toList收集器使用了ArrayList作为列表的实现。 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/WechatMpConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import me.chanjar.weixin.mp.api.WxMpConfigStorage; 4 | import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; 5 | import me.chanjar.weixin.mp.api.WxMpService; 6 | import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/18. 15 | * Time: 下午 7:47. 16 | * Explain:MP-公众号的意思 微信公众号配置 17 | */ 18 | @Component 19 | public class WechatMpConfig { 20 | @Autowired 21 | private WechatAccountConfig wechatAccountConfig; 22 | @Bean//作为一个Bean 23 | public WxMpService wxMpService(){ 24 | WxMpService wxMpService = new WxMpServiceImpl(); 25 | wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); 26 | return wxMpService; 27 | } 28 | public WxMpConfigStorage wxMpConfigStorage(){ 29 | WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();//基于内存的 30 | wxMpInMemoryConfigStorage.setAppId(wechatAccountConfig.getMpAppId()); 31 | wxMpInMemoryConfigStorage.setSecret(wechatAccountConfig.getMpAppSecret()); 32 | return wxMpInMemoryConfigStorage; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/ProductCategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dao.ProductCategoryDao; 4 | import cn.chenhaoxiang.dataObject.ProductCategory; 5 | import cn.chenhaoxiang.service.ProductCategoryService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/9. 15 | * Time: 下午 6:41. 16 | * Explain: 类目 17 | */ 18 | @Service 19 | public class ProductCategoryServiceImpl implements ProductCategoryService { 20 | 21 | @Autowired 22 | private ProductCategoryDao productCategoryDao; 23 | 24 | @Override 25 | public ProductCategory findOne(Integer categoryId) { 26 | return productCategoryDao.findOne(categoryId); 27 | } 28 | 29 | @Override 30 | public List findAll() { 31 | return productCategoryDao.findAll(); 32 | } 33 | 34 | @Override 35 | public List findByCategoryTypeIn(List categoryTypeList) { 36 | return productCategoryDao.findByCategoryTypeIn(categoryTypeList); 37 | } 38 | 39 | @Override 40 | public ProductCategory save(ProductCategory productCategory) { 41 | return productCategoryDao.save(productCategory); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/WechatOpenConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import me.chanjar.weixin.mp.api.WxMpConfigStorage; 4 | import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; 5 | import me.chanjar.weixin.mp.api.WxMpService; 6 | import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/24. 15 | * Time: 下午 6:58. 16 | * Explain: 微信开放平台配置 17 | */ 18 | @Component 19 | public class WechatOpenConfig { 20 | @Autowired 21 | private WechatAccountConfig wechatAccountConfig; 22 | 23 | @Bean 24 | public WxMpService wxOpenService(){ 25 | WxMpService wxMpService = new WxMpServiceImpl(); 26 | wxMpService.setWxMpConfigStorage(wxOpenConfigStorage()); 27 | return wxMpService; 28 | } 29 | 30 | @Bean 31 | public WxMpConfigStorage wxOpenConfigStorage(){ 32 | WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage(); 33 | wxMpInMemoryConfigStorage.setAppId(wechatAccountConfig.getOpenAppId()); 34 | wxMpInMemoryConfigStorage.setSecret(wechatAccountConfig.getOpenAppSecret()); 35 | return wxMpInMemoryConfigStorage; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/LoggerTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang; 2 | 3 | import lombok.Data; 4 | import lombok.extern.slf4j.Slf4j; 5 | import lombok.extern.slf4j.XSlf4j; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | /** 14 | * Created with IntelliJ IDEA. 15 | * User: 陈浩翔. 16 | * Date: 2018/1/8. 17 | * Time: 下午 8:05. 18 | * Explain:日志测试 19 | */ 20 | 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | @Slf4j 24 | public class LoggerTest { 25 | private final Logger logger = LoggerFactory.getLogger(LoggerTest.class); 26 | 27 | /** 28 | * 传统方式实现日志 29 | */ 30 | @Test 31 | public void test1(){ 32 | logger.debug("debug");//默认日志级别为info 33 | logger.info("info"); 34 | logger.error("error"); 35 | logger.warn("warn"); 36 | } 37 | 38 | /** 39 | * Slf4j注解方式实现日志 40 | */ 41 | @Test 42 | public void test2(){ 43 | log.debug("debug");//默认日志级别为info 44 | log.info("info"); 45 | log.error("error"); 46 | log.warn("warn"); 47 | String name = "陈浩翔"; 48 | String password = "123456"; 49 | log.info("name:{},password:{}",name,password);//{}表示一个占位符 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dao/SellerInfoDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.SellerInfo; 4 | import cn.chenhaoxiang.utils.KeyUtil; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: 陈浩翔. 17 | * Date: 2018/1/23. 18 | * Time: 下午 10:51. 19 | * Explain: 20 | */ 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | public class SellerInfoDaoTest { 24 | @Autowired 25 | private SellerInfoDao sellerInfoDao; 26 | @Test 27 | public void save(){ 28 | SellerInfo sellerInfo = new SellerInfo(); 29 | sellerInfo.setSellerId(KeyUtil.getUniqueKey()); 30 | sellerInfo.setUsername("admin"); 31 | sellerInfo.setPassword("admin"); 32 | sellerInfo.setOpenid("abc"); 33 | SellerInfo result =sellerInfoDao.save(sellerInfo); 34 | Assert.assertNotNull(result); 35 | } 36 | 37 | @Test 38 | public void findByOpenid() throws Exception { 39 | SellerInfo result = sellerInfoDao.findByOpenid("abc"); 40 | Assert.assertEquals("abc",result.getOpenid()); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dataObject/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.dataObject (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.dataObject

14 |
15 |

16 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/ProductCategory.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject; 2 | 3 | import lombok.Data; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.hibernate.annotations.DynamicUpdate; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | import java.util.Date; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: 陈浩翔. 17 | * Date: 2018/1/8. 18 | * Time: 下午 10:01. 19 | * Explain:现在的表名 product_category 20 | */ 21 | //@Table(name = "product_category")//如果类名和表名不是一致的话就需要 22 | @Entity 23 | @DynamicUpdate //动态更新-需要设置数据库的更新时间字段为自动更新 这样,查询出时间,去设置其他字段后保存,更新时间依然会更新 24 | @Data //不用写setter和getter方法,toString也可以省了 性能是一样的,可以去看编译的class文件,和我们写的一样 25 | //@Getter //不用写getter方法 26 | //@Setter //不用写setter方法 27 | public class ProductCategory { 28 | /** 29 | * 类目ID 30 | */ 31 | @Id 32 | @GeneratedValue //自增 33 | private Integer categoryId; 34 | /** 35 | * 类目名字 36 | */ 37 | private String categoryName; 38 | /** 39 | * 类目编号 40 | */ 41 | private Integer categoryType; 42 | 43 | private Date createTime; 44 | 45 | private Date updateTime; 46 | 47 | public ProductCategory() { 48 | } 49 | 50 | public ProductCategory(String categoryName, Integer categoryType) { 51 | this.categoryName = categoryName; 52 | this.categoryType = categoryType; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/category/index.ftl: -------------------------------------------------------------------------------- 1 | 2 | <#include "../common/header.ftl"> 3 | 4 | 5 |
6 | <#--边栏sidebar--> 7 | <#include "../common/nav.ftl"> 8 | <#--主要内容区域--> 9 |
10 | <#--fluid-流动布局--> 11 |
12 | 13 |
14 |
15 |
16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 |
25 | <#--加个隐藏的字段--> 26 | 27 | 28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/utils/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.utils (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.utils

14 |
15 |

16 | 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/WechatPayConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import com.lly835.bestpay.config.WxPayH5Config; 4 | import com.lly835.bestpay.service.impl.BestPayServiceImpl; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/20. 13 | * Time: 下午 5:08. 14 | * Explain: 15 | */ 16 | @Component 17 | public class WechatPayConfig { 18 | 19 | @Autowired 20 | private WechatAccountConfig wechatAccountConfig; 21 | 22 | @Bean 23 | public BestPayServiceImpl bestPayService(){ 24 | BestPayServiceImpl bestPayService = new BestPayServiceImpl(); 25 | bestPayService.setWxPayH5Config(wxPayH5Config()); 26 | return bestPayService; 27 | } 28 | 29 | @Bean 30 | public WxPayH5Config wxPayH5Config(){ 31 | WxPayH5Config wxPayH5Config = new WxPayH5Config(); 32 | wxPayH5Config.setAppId(wechatAccountConfig.getMpAppId()); 33 | wxPayH5Config.setAppSecret(wechatAccountConfig.getMpAppSecret()); 34 | wxPayH5Config.setMchId(wechatAccountConfig.getMchId()); 35 | wxPayH5Config.setMchKey(wechatAccountConfig.getMchKey()); 36 | wxPayH5Config.setKeyPath(wechatAccountConfig.getKeyPath()); 37 | wxPayH5Config.setNotifyUrl(wechatAccountConfig.getNotifyUrl()); 38 | return wxPayH5Config; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/enums/ResultEnum.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.enums; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: 陈浩翔. 8 | * Date: 2018/1/14. 9 | * Time: 下午 10:46. 10 | * Explain:返回给前端提示的消息 11 | */ 12 | @Getter 13 | public enum ResultEnum { 14 | 15 | SUCCESS(0,"成功"), 16 | 17 | PARAM_ERROR(1,"参数不正确"), 18 | 19 | PRODUCT_NOT_EXIST(10,"商品不存在"), 20 | PRODUCT_STOCK_ERROR(11,"库存不足"), 21 | ORDER_NOT_EXIST(12,"订单不存在"), 22 | ORDERDETAIL_NOT_EXIST(13,"订单详情不存在"), 23 | ORDER_STATUS_ERROR(14,"订单状态不正确"), 24 | ORDER_UPDATE_FAIL(15,"订单更新失败"), 25 | 26 | ORDER_DETAIL_EMPTY(16,"订单详情为空"), 27 | 28 | ORDER_PAY_STATUS_ERROR(17,"订单支付状态不正确"), 29 | 30 | CART_EMPTY(18,"购物车为空"), 31 | 32 | ORDER_OWNER_ERROR(19,"该订单不属于当前用户"), 33 | 34 | WECHAT_MP_ERROR(20,"微信公众账号方面错误"), 35 | 36 | WXPAY_NOTIFY_MONEY_VERIFY_ERROR(21,"微信支付异步通知金额校验不通过"), 37 | 38 | ORDER_CANEL_SUCCESS(22,"订单取消成功"), 39 | 40 | ORDER_FINISH_SUCCESS(23,"订单完结成功"), 41 | 42 | PRODUCT_STATUS_ERROR(24,"商品状态不正确"), 43 | 44 | PRODUCT_ONSALE_SUCCESS(25,"商品上架成功"), 45 | 46 | PRODUCT_OFFSALE_SUCCESS(26,"商品下架成功"), 47 | 48 | WECHAT_QR_ERROR(27,"微信开放平台账号方面错误"), 49 | 50 | LOGIN_FAIL(28,"登录失败,登录信息不正确"), 51 | LOGOUT_SUCCESS(29,"登出成功"), 52 | ; 53 | private Integer code; 54 | private String message; 55 | 56 | ResultEnum(Integer code, String message) { 57 | this.code = code; 58 | this.message = message; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/ProductInfoService.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import cn.chenhaoxiang.dataObject.ProductInfo; 5 | import cn.chenhaoxiang.dto.CartDTO; 6 | import org.springframework.data.domain.Page; 7 | import org.springframework.data.domain.Pageable; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/9. 15 | * Time: 下午 7:11. 16 | * Explain: 商品 17 | */ 18 | public interface ProductInfoService { 19 | /** 20 | * 查询一个 21 | * @param productInfoId 22 | * @return 23 | */ 24 | ProductInfo findOne(String productInfoId); 25 | 26 | /** 27 | * 查询所有在架商品列表 28 | * @return 29 | */ 30 | List findUpAll(); 31 | 32 | /** 33 | * 分页查询所有 商品列表 34 | * @param pageable 35 | * @return 36 | */ 37 | Page findAll(Pageable pageable); 38 | 39 | /** 40 | * 更新和新增 41 | * @param productInfo 42 | * @return 43 | */ 44 | ProductInfo save(ProductInfo productInfo); 45 | 46 | /** 47 | * 加库存 48 | */ 49 | void increaseStock(List cartDTOList); 50 | 51 | /** 52 | * 减库存 53 | */ 54 | void decreaseStock(List cartDTOList); 55 | 56 | /** 57 | * 上架 58 | */ 59 | ProductInfo onSale(String productId); 60 | 61 | /** 62 | * 下架 63 | */ 64 | ProductInfo offSale(String productId); 65 | 66 | } 67 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/enums/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.enums (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.enums

14 |
15 |

接口

16 | 19 |

枚举

20 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/common/nav.ftl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/pay/create.ftl: -------------------------------------------------------------------------------- 1 | 2 | <#--

模板标题,注入的内容:${payResponse.appId}

--> 3 | 4 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/WeixinController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import org.springframework.web.client.RestTemplate; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: 陈浩翔. 13 | * Date: 2018/1/18. 14 | * Time: 下午 6:58. 15 | * Explain: 不用了 16 | */ 17 | @RestController 18 | @RequestMapping("/weixin") 19 | @Slf4j 20 | public class WeixinController { 21 | //视频上的:wxd898fcd01713c658 22 | //29d8a650db31472aa87800e3b0d739f2 23 | 24 | //uifuture 25 | //40567729325064e5590df98612846634 26 | //https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxec6162ffa649896b&redirect_uri=http://anyi.s1.natapp.cc/weixin/auth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect 27 | @GetMapping("/auth") 28 | public void auth(@RequestParam("code")String code){ 29 | log.info("进入微信auth方法"); 30 | log.info("code={}",code); 31 | String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxec6162ffa649896b&secret=40567729325064e5590df98612846634&code="+code+"&grant_type=authorization_code"; 32 | RestTemplate restTemplate = new RestTemplate(); 33 | String response =restTemplate.getForObject(url,String.class);//Get请求 34 | log.info("response={}",response); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/config/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.config (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.config

14 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dao/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.dao (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.dao

14 |
15 |

接口

16 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/converter/OrderForm2OrderDTOConverter.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.converter; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderDetail; 4 | import cn.chenhaoxiang.dto.OrderDTO; 5 | import cn.chenhaoxiang.enums.ResultEnum; 6 | import cn.chenhaoxiang.exception.SellException; 7 | import cn.chenhaoxiang.form.OrderForm; 8 | import com.google.gson.Gson; 9 | import com.google.gson.reflect.TypeToken; 10 | import lombok.extern.slf4j.Slf4j; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * User: 陈浩翔. 18 | * Date: 2018/1/16. 19 | * Time: 下午 7:36. 20 | * Explain:转换器 21 | */ 22 | @Slf4j 23 | public class OrderForm2OrderDTOConverter { 24 | public static OrderDTO convert(OrderForm orderForm){ 25 | OrderDTO orderDTO = new OrderDTO(); 26 | orderDTO.setBuyerName(orderForm.getName()); 27 | orderDTO.setBuyerPhone(orderForm.getPhone()); 28 | orderDTO.setBuyerAddress(orderForm.getAddress()); 29 | orderDTO.setBuyerOpenid(orderForm.getOpenid()); 30 | //购物车 31 | Gson gson = new Gson(); 32 | List orderDetailList = new ArrayList<>(); 33 | try { 34 | orderDetailList = gson.fromJson(orderForm.getItems(), 35 | new TypeToken>() { 36 | }.getType()); 37 | }catch (Exception e){ 38 | log.error("[对象转换] 错误,json={}",orderForm.getItems()); 39 | throw new SellException(ResultEnum.PARAM_ERROR); 40 | } 41 | orderDTO.setOrderDetailList(orderDetailList); 42 | return orderDTO; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/SeckullController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.service.SeckillService; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/26. 15 | * Time: 下午 9:24. 16 | * Explain: 秒杀高并发错Controller 17 | */ 18 | @RestController 19 | @RequestMapping("/skill") 20 | @Slf4j 21 | public class SeckullController { 22 | 23 | @Autowired 24 | private SeckillService seckillService; 25 | /** 26 | * 查询秒杀活动特价商品的信息 27 | * @param productId 28 | * @return 29 | */ 30 | @GetMapping("/query/{productId}")//PathVariable注解,设置路径中的值到变量 31 | public String query(@PathVariable String productId) throws Exception{ 32 | return seckillService.querySecKillProductInfo(productId); 33 | } 34 | 35 | /** 36 | * 秒杀,没有抢到返回"很抱歉,****",抢到了会返回剩余的库存量 37 | * @param productId 38 | * @return 39 | * @throws Exception 40 | */ 41 | @GetMapping("/order/{productId}")//PathVariable注解,设置路径中的值到变量 42 | public String skill(@PathVariable String productId) throws Exception{ 43 | log.info("@skill request,productId={}",productId); 44 | seckillService.orderProductMocckDiffUser(productId); 45 | return seckillService.querySecKillProductInfo(productId); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /sell/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # logback的简单配置 2 | #logging: 3 | # pattern: 4 | # 配置日志格式 5 | # console: "%d - %msg%n" 6 | # 配置日志级别 日志级别可以指定到某个类 7 | # level: 8 | # cn.chenhaoxiang.LoggerTest: debug 9 | # 配置日志文件。可以自定义日志文件名字 10 | # file: 11 | # 配置存储路径 不配置就不会保存到文件 默认spring.log 12 | # path: 13 | spring: 14 | datasource: 15 | driver-class-name: com.mysql.jdbc.Driver 16 | username: root 17 | password: 1234 18 | url: jdbc:mysql://127.0.0.1/wechatorder?characterEncoding=utf-8&userSSL=false 19 | jpa: 20 | # 打印SQL 21 | show-sql: true 22 | # 为null的属性不序列化成json字符串 - 也就是前端不会看到为null的属性 23 | redis: 24 | host: 127.0.0.1 25 | port: 6379 26 | password: chenhaoxiang 27 | # jackson: 28 | # default-property-inclusion: non_null 29 | #server: 30 | # 配置Url项目名 也就是URl的前缀 31 | # context-path: /sell 32 | wechat: 33 | # 师兄干货的 34 | # mpAppId: wxd898fcb01713c658 35 | # mpAppSecret: ed8bcd6a5acb51382cb967f1cf19ac89 36 | mpAppId: wxe007de634e454627 37 | mpAppSecret: ed8bcd6a5acb51382cb967f1cf19ac89 38 | openAppId: wxd898fcb01713c658 39 | openAppSecret: wxd898fcb01713c658 40 | mchId: 1483469312 41 | mchKey: C5245D70627C1F8E9964D494B0735025 42 | keyPath: F:/h5.p12 #文件路径 43 | notifyUrl: http://anyi.nat300.top/pay/notify #异步通知地址 44 | templateId: 45 | orderStatus: 3YRLwuwGNGc15Stk_ycFYshgh9jA_dpc493TDPn4OH8 46 | 47 | projectUrl: 48 | wechatMpAuthorize: http://anyi.nat300.top 49 | wechatOpenAuthorize: http://anyi.nat300.top 50 | project: http://anyi.nat300.top 51 | mybatis: 52 | mapper-locations: classpath:mapper/*.xml 53 | # 设置cn.chenhaoxiang包下所有类的日志输出级别-debug能看到执行的sql 54 | logging: 55 | level: 56 | cn.chenhaoxiang: debug 57 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dao/OrderDetailDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderDetail; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.math.BigDecimal; 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * User: 陈浩翔. 19 | * Date: 2018/1/14. 20 | * Time: 下午 10:07. 21 | * Explain: 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | public class OrderDetailDaoTest { 26 | 27 | @Autowired 28 | private OrderDetailDao orderDetailDao; 29 | 30 | @Test 31 | public void saveTest(){ 32 | OrderDetail orderDetail = new OrderDetail(); 33 | orderDetail.setDetailId("1234567810"); 34 | orderDetail.setOrderId("11111112"); 35 | orderDetail.setProductIcon("http://xxx.jpg"); 36 | orderDetail.setProductId("11111112"); 37 | orderDetail.setProductName("皮蛋粥"); 38 | orderDetail.setProductPrice(new BigDecimal(2.2)); 39 | orderDetail.setProductQuantity(3); 40 | 41 | OrderDetail result = orderDetailDao.save(orderDetail); 42 | Assert.assertNotNull(result); 43 | } 44 | 45 | @Test 46 | public void findByOrderId() throws Exception { 47 | List orderDetailList = orderDetailDao.findByOrderId("11111111"); 48 | Assert.assertNotEquals(0,orderDetailList.size()); 49 | 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /sell/src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | # logback的简单配置 2 | #logging: 3 | # pattern: 4 | # 配置日志格式 5 | # console: "%d - %msg%n" 6 | # 配置日志级别 日志级别可以指定到某个类 7 | # level: 8 | # cn.chenhaoxiang.LoggerTest: debug 9 | # 配置日志文件。可以自定义日志文件名字 10 | # file: 11 | # 配置存储路径 不配置就不会保存到文件 默认spring.log 12 | # path: 13 | spring: 14 | datasource: 15 | driver-class-name: com.mysql.jdbc.Driver 16 | username: root 17 | password: 1234 18 | url: jdbc:mysql://127.0.0.1/wechatorder?characterEncoding=utf-8&userSSL=false 19 | # jpa: 20 | # # 打印SQL 21 | # show-sql: true 22 | # 为null的属性不序列化成json字符串 - 也就是前端不会看到为null的属性 23 | redis: 24 | host: 127.0.0.1 25 | port: 6379 26 | password: chenhaoxiang 27 | # jackson: 28 | # default-property-inclusion: non_null 29 | #server: 30 | # 配置Url项目名 也就是URl的前缀 31 | # context-path: /sell 32 | wechat: 33 | # 师兄干货的 34 | # mpAppId: wxd898fcb01713c658 35 | # mpAppSecret: ed8bcd6a5acb51382cb967f1cf19ac89 36 | mpAppId: wxe007de634e454627 37 | mpAppSecret: ed8bcd6a5acb51382cb967f1cf19ac89 38 | openAppId: wxd898fcb01713c658 39 | openAppSecret: wxd898fcb01713c658 40 | mchId: 1483469312 41 | mchKey: C5245D70627C1F8E9964D494B0735025 42 | keyPath: F:/h5.p12 #文件路径 43 | notifyUrl: http://anyi.nat300.top/pay/notify #异步通知地址 44 | templateId: 45 | orderStatus: 3YRLwuwGNGc15Stk_ycFYshgh9jA_dpc493TDPn4OH8 46 | 47 | projectUrl: 48 | wechatMpAuthorize: http://anyi.nat300.top 49 | wechatOpenAuthorize: http://anyi.nat300.top 50 | project: http://anyi.nat300.top 51 | mybatis: 52 | mapper-locations: classpath:mapper/*.xml 53 | # 设置cn.chenhaoxiang包下所有类的日志输出级别-debug能看到执行的sql 54 | logging: 55 | level: 56 | cn.chenhaoxiang: debug 57 | -------------------------------------------------------------------------------- /sell/src/main/resources/static/api/seller.json: -------------------------------------------------------------------------------- 1 | { 2 | "errno": 0, 3 | "data": { 4 | "name": "粥品香坊(回龙观)", 5 | "description": "蜂鸟专送", 6 | "deliveryTime": 38, 7 | "score": 4.2, 8 | "serviceScore": 4.1, 9 | "foodScore": 4.3, 10 | "rankRate": 69.2, 11 | "minPrice": 0, 12 | "deliveryPrice": 0, 13 | "ratingCount": 24, 14 | "sellCount": 90, 15 | "bulletin": "粥品香坊其烹饪粥料的秘方源于中国千年古法,在融和现代制作工艺,由世界烹饪大师屈浩先生领衔研发。坚守纯天然、0添加的良心品质深得消费者青睐,发展至今成为粥类的引领品牌。是2008年奥运会和2013年园博会指定餐饮服务商。", 16 | "supports": [ 17 | { 18 | "type": 0, 19 | "description": "在线支付满28减5" 20 | }, 21 | { 22 | "type": 1, 23 | "description": "VC无限橙果汁全场8折" 24 | }, 25 | { 26 | "type": 2, 27 | "description": "单人精彩套餐" 28 | }, 29 | { 30 | "type": 3, 31 | "description": "该商家支持发票,请下单写好发票抬头" 32 | }, 33 | { 34 | "type": 4, 35 | "description": "已加入“外卖保”计划,食品安全保障" 36 | } 37 | ], 38 | "avatar": "http://static.galileo.xiaojukeji.com/static/tms/seller_avatar_256px.jpg", 39 | "pics": [ 40 | "http://fuss10.elemecdn.com/8/71/c5cf5715740998d5040dda6e66abfjpeg.jpeg?imageView2/1/w/180/h/180", 41 | "http://fuss10.elemecdn.com/b/6c/75bd250e5ba69868f3b1178afbda3jpeg.jpeg?imageView2/1/w/180/h/180", 42 | "http://fuss10.elemecdn.com/f/96/3d608c5811bc2d902fc9ab9a5baa7jpeg.jpeg?imageView2/1/w/180/h/180", 43 | "http://fuss10.elemecdn.com/6/ad/779f8620ff49f701cd4c58f6448b6jpeg.jpeg?imageView2/1/w/180/h/180" 44 | ], 45 | "infos": [ 46 | "该商家支持发票,请下单写好发票抬头", 47 | "品类:其他菜系,包子粥店", 48 | "北京市昌平区回龙观西大街龙观置业大厦底商B座102单元1340", 49 | "营业时间:10:00-20:30" 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dao/ProductInfoDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductInfo; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.math.BigDecimal; 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * User: 陈浩翔. 19 | * Date: 2018/1/9. 20 | * Time: 下午 7:01. 21 | * Explain: 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | public class ProductInfoDaoTest { 26 | @Autowired 27 | private ProductInfoDao productInfoDao; 28 | 29 | @Test 30 | public void saveTest(){ 31 | ProductInfo productInfo = new ProductInfo(); 32 | productInfo.setProductId("123456"); 33 | productInfo.setProductName("鸡蛋粥"); 34 | productInfo.setProductPrice(new BigDecimal(6.5)); 35 | productInfo.setProductStock(100); 36 | productInfo.setProductDescription("味道不错哦"); 37 | productInfo.setProductIcon("http://XXXX.jpg"); 38 | productInfo.setProductStatus(0); 39 | productInfo.setCategoryType(2); 40 | ProductInfo result = productInfoDao.save(productInfo); 41 | Assert.assertNotEquals(null,result); 42 | 43 | } 44 | 45 | @Test 46 | public void findByProductStatus() throws Exception { 47 | List productInfoList = productInfoDao.findByProductStatus(0); 48 | Assert.assertNotEquals(0,productInfoList.size()); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/OrderMaster.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject; 2 | 3 | import cn.chenhaoxiang.enums.OrderStausEnum; 4 | import cn.chenhaoxiang.enums.PayStatusEnum; 5 | import lombok.Data; 6 | import org.hibernate.annotations.DynamicUpdate; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.Id; 10 | import javax.persistence.Transient; 11 | import java.math.BigDecimal; 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * User: 陈浩翔. 18 | * Date: 2018/1/14. 19 | * Time: 下午 8:57. 20 | * Explain: 订单表 21 | */ 22 | @Entity 23 | @Data 24 | @DynamicUpdate //动态更新-需要设置数据库的更新时间字段为自动更新 这样,查询出时间,去设置其他字段后保存,更新时间依然会更新 25 | public class OrderMaster { 26 | 27 | /** 28 | * 订单ID 29 | */ 30 | @Id 31 | private String orderId; 32 | /** 33 | * 买家名字 34 | */ 35 | private String buyerName; 36 | 37 | /** 38 | * 买家手机号 39 | */ 40 | private String buyerPhone; 41 | 42 | /** 43 | * 买家地址 44 | */ 45 | private String buyerAddress; 46 | 47 | /** 48 | * 买家微信Openid 49 | */ 50 | private String buyerOpenid; 51 | /** 52 | * 订单金额 53 | */ 54 | private BigDecimal orderAmount; 55 | 56 | /** 57 | * 订单状态,默认为新下单 58 | */ 59 | private Integer orderStatus = OrderStausEnum.NEW.getCode(); 60 | 61 | /** 62 | * 支付状态,默认为0-未支付 63 | */ 64 | private Integer payStatus = PayStatusEnum.WAIT.getCode(); 65 | 66 | /** 67 | * 创建时间 68 | */ 69 | private Date createTime; 70 | 71 | /** 72 | * 更新时间 73 | */ 74 | private Date updateTime; 75 | 76 | 77 | // /** 78 | // * 关联订单详情 79 | // */ 80 | // @Transient //在数据库对应的时候能忽略,就不会去数据库找对应的字段了 81 | // private List orderDetailList; 82 | // 直接新建一个对象 OrderDTO 83 | 84 | } 85 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/BuyerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.enums.ResultEnum; 5 | import cn.chenhaoxiang.exception.SellException; 6 | import cn.chenhaoxiang.service.BuyerService; 7 | import cn.chenhaoxiang.service.OrderService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * User: 陈浩翔. 15 | * Date: 2018/1/16. 16 | * Time: 下午 8:53. 17 | * Explain: 18 | */ 19 | @Service 20 | @Slf4j 21 | public class BuyerServiceImpl implements BuyerService{ 22 | 23 | @Autowired 24 | private OrderService orderService; 25 | 26 | @Override 27 | public OrderDTO findOrderOne(String openid, String orderId) { 28 | return checkOrderOwner(openid, orderId); 29 | } 30 | 31 | @Override 32 | public OrderDTO cancelOrder(String openid, String orderId) { 33 | OrderDTO orderDTO = checkOrderOwner(openid, orderId); 34 | if(orderDTO ==null){ 35 | log.error("[取消订单] 查不到该订单,orderId={}",orderId); 36 | throw new SellException(ResultEnum.ORDER_NOT_EXIST); 37 | } 38 | return orderService.cancel(orderDTO); 39 | } 40 | 41 | private OrderDTO checkOrderOwner(String openid,String orderId){ 42 | OrderDTO orderDTO = orderService.findOne(orderId); 43 | if(orderDTO==null){ 44 | return null; 45 | } 46 | //判断是否是自己的订单 47 | if(!orderDTO.getBuyerOpenid().equalsIgnoreCase(openid)){ 48 | log.error("[查询订单] 订单的openid不一致。openid={},orderDTO={}",openid,orderDTO); 49 | throw new SellException(ResultEnum.ORDER_OWNER_ERROR); 50 | } 51 | return orderDTO; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dao/OrderMasterDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderMaster; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.data.domain.Page; 10 | import org.springframework.data.domain.PageRequest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import java.math.BigDecimal; 14 | 15 | import static org.junit.Assert.*; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: 陈浩翔. 20 | * Date: 2018/1/14. 21 | * Time: 下午 9:17. 22 | * Explain: 23 | */ 24 | @RunWith(SpringRunner.class) 25 | @SpringBootTest 26 | public class OrderMasterDaoTest { 27 | @Autowired 28 | private OrderMasterDao orderMasterDao; 29 | 30 | private final String OPENID ="110110"; 31 | @Test 32 | public void saveTest(){ 33 | OrderMaster orderMaster = new OrderMaster(); 34 | orderMaster.setOrderId("1234567"); 35 | orderMaster.setBuyerName("陈浩翔"); 36 | orderMaster.setBuyerPhone("12345678912"); 37 | orderMaster.setBuyerAddress("长沙"); 38 | orderMaster.setBuyerOpenid(OPENID); 39 | orderMaster.setOrderAmount(new BigDecimal(2.5)); 40 | OrderMaster result = orderMasterDao.save(orderMaster); 41 | Assert.assertNotNull(result); 42 | } 43 | 44 | @Test 45 | public void findByBuyerOpenid() throws Exception { 46 | 47 | PageRequest pageRequest = new PageRequest(1,3); 48 | Page result = orderMasterDao.findByBuyerOpenid(OPENID,pageRequest); 49 | Assert.assertNotEquals(0,result.getTotalElements()); 50 | //System.out.println(result.getTotalElements());//总条数 51 | 52 | 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/ProductInfo.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject; 2 | 3 | import cn.chenhaoxiang.enums.ProductStatusEnum; 4 | import cn.chenhaoxiang.utils.EnumUtil; 5 | import com.fasterxml.jackson.annotation.JsonIgnore; 6 | import lombok.Data; 7 | import org.hibernate.annotations.DynamicUpdate; 8 | 9 | import javax.persistence.Entity; 10 | import javax.persistence.Id; 11 | import java.io.Serializable; 12 | import java.math.BigDecimal; 13 | import java.util.Date; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * User: 陈浩翔. 18 | * Date: 2018/1/9. 19 | * Time: 下午 6:54. 20 | * Explain: 商品 21 | */ 22 | @Entity 23 | @Data 24 | @DynamicUpdate //修改时间字段自动更新的 需要的注解 25 | public class ProductInfo implements Serializable{ 26 | private static final long serialVersionUID = -3048495745484346347L; 27 | @Id 28 | private String productId; 29 | 30 | /** 31 | * 名字 32 | */ 33 | private String productName; 34 | 35 | /** 36 | * 单价 37 | */ 38 | private BigDecimal productPrice; 39 | 40 | /** 41 | * 库存 42 | */ 43 | private Integer productStock; 44 | /** 45 | * 描述 46 | */ 47 | private String productDescription; 48 | /** 49 | * 小图 50 | */ 51 | private String productIcon; 52 | /** 53 | * 状态 0-正常 1-下架 54 | */ 55 | private Integer productStatus = 0; 56 | /** 57 | * 类目编号 58 | */ 59 | private Integer categoryType; 60 | 61 | /** 62 | * 创建时间 63 | */ 64 | private Date createTime; 65 | /** 66 | * 修改时间 67 | */ 68 | private Date updateTime; 69 | 70 | /** 71 | * 上架下架 72 | * 注意是公开方法 73 | * @return 74 | */ 75 | @JsonIgnore //返回json格式的字符串时,忽略该字段/方法 也就是不序列化 76 | public ProductStatusEnum getProductStatusEnum(){ 77 | return EnumUtil.getByCode(productStatus,ProductStatusEnum.class); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/service/impl/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.service.impl (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.service.impl

14 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/ProductCategoryServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * User: 陈浩翔. 19 | * Date: 2018/1/9. 20 | * Time: 下午 6:43. 21 | * Explain: 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | public class ProductCategoryServiceImplTest { 26 | 27 | @Autowired 28 | private ProductCategoryServiceImpl productCategoryService;//这里选择实现,因为是实现的测试 29 | 30 | @Test 31 | public void findOne() throws Exception { 32 | ProductCategory productCategory = productCategoryService.findOne(1); 33 | Assert.assertEquals(new Integer(1),productCategory.getCategoryId()); 34 | } 35 | 36 | @Test 37 | public void findAll() throws Exception { 38 | List productCategoryList = productCategoryService.findAll(); 39 | Assert.assertNotEquals(0,productCategoryList.size()); 40 | } 41 | 42 | @Test 43 | public void findByCategoryTypeIn() throws Exception { 44 | List productCategoryList = productCategoryService.findByCategoryTypeIn(Arrays.asList(1,2,3,4)); 45 | Assert.assertNotEquals(0,productCategoryList.size()); 46 | } 47 | 48 | @Test 49 | public void save() throws Exception { 50 | ProductCategory productCategory = new ProductCategory("男士专用",5); 51 | ProductCategory result = productCategoryService.save(productCategory); 52 | Assert.assertNotEquals(null,result); 53 | 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/handler/HandshakeInterceptor.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.handler; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.http.server.ServerHttpRequest; 5 | import org.springframework.http.server.ServerHttpResponse; 6 | import org.springframework.web.socket.WebSocketHandler; 7 | import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/25. 15 | * Time: 下午 10:24. 16 | * Explain: websocket拦截器 17 | */ 18 | @Slf4j 19 | public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { 20 | /** 21 | * 如果 beforeHandshake 返回 false, 那么该 WebSocket 请求被拒绝连接. 22 | 其中 request 可以转换成 ServletServerHttpRequest, 并获取其中包装的 HttpServletRequest, 以获得 http 请求中 parameter 等信息. 23 | * @param request 24 | * @param response 25 | * @param wsHandler 26 | * @param attributes 27 | * @return 28 | * @throws Exception 29 | */ 30 | @Override 31 | public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 32 | Map attributes) throws Exception { 33 | //解决 The extension [x-webkit-deflate-frame] is not supported问题 34 | if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) { 35 | request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate"); 36 | } 37 | log.info("Before Handshake"); 38 | return super.beforeHandshake(request, response, wsHandler, attributes); 39 | } 40 | 41 | @Override 42 | public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 43 | Exception ex) { 44 | log.info("After Handshake"); 45 | super.afterHandshake(request, response, wsHandler, ex); 46 | } 47 | } -------------------------------------------------------------------------------- /sell/src/main/resources/templates/category/list.ftl: -------------------------------------------------------------------------------- 1 | 2 | <#include "../common/header.ftl"> 3 | 4 | 5 |
6 | <#--边栏sidebar--> 7 | <#include "../common/nav.ftl"> 8 | <#--主要内容区域--> 9 |
10 | <#--fluid-流动布局--> 11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | <#list productCategoryList as productCategory> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 |
类目Id名称type创建时间修改时间操作
${productCategory.categoryId}${productCategory.categoryName}${productCategory.categoryType}${productCategory.createTime}${productCategory.updateTime} 34 | 修改 35 |
40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/utils/CookieUtil.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.utils; 2 | 3 | import javax.servlet.http.Cookie; 4 | import javax.servlet.http.HttpServletRequest; 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/24. 13 | * Time: 下午 8:02. 14 | * Explain: Cookie工具类 15 | */ 16 | public class CookieUtil { 17 | 18 | /** 19 | * 清除cookie 20 | * @param response 21 | * @param name 22 | */ 23 | public static void del(HttpServletResponse response, 24 | String name){ 25 | set(response,name,null,0); 26 | } 27 | 28 | /** 29 | * 设置cookie 30 | * @param response 31 | * @param name 32 | * @param value 33 | * @param maxAge 34 | */ 35 | public static void set(HttpServletResponse response, 36 | String name, 37 | String value, 38 | int maxAge){ 39 | Cookie cookie = new Cookie(name,value); 40 | cookie.setPath("/"); 41 | cookie.setMaxAge(maxAge); 42 | response.addCookie(cookie); 43 | } 44 | 45 | /** 46 | * 获取Cookie 47 | * @param request 48 | * @param name 49 | * @return 50 | */ 51 | public static Cookie get(HttpServletRequest request, 52 | String name){ 53 | Map cookieMap =readCookieMap(request); 54 | if(cookieMap.containsKey(name)){ 55 | return cookieMap.get(name); 56 | } 57 | return null; 58 | } 59 | 60 | /** 61 | * 将cookie数组封装为Map 62 | * @param request 63 | * @return 64 | */ 65 | private static Map readCookieMap(HttpServletRequest request){ 66 | Map cookieMap = new HashMap<>(); 67 | Cookie[] cookies =request.getCookies(); 68 | if(cookies!=null){ 69 | for(Cookie cookie:cookies){ 70 | cookieMap.put(cookie.getName(),cookie); 71 | } 72 | } 73 | return cookieMap; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/controller/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.controller (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.controller

14 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WeChatOrderSystem 2 | sell - 微信点餐系统-SpringBoot开发 3 | 4 | 在这里使用了微信公众平台的账号和微信开放平台的账号。 5 | 需要自己去申请一些权限。 6 | 目前用到的权限有: 7 | 微信公众号的登录支付权限,消息推送权限。登录和消息推送可以在开发文档中使用测试账号。 8 | 至于支付权限,则需要你自己去找朋友借借账号了。 9 | 我是学习的廖师兄的视频进行的开发,需要有支付权限测试的,可以看这篇文档: 10 | https://github.com/Pay-Group/best-pay-sdk/blob/master/doc/borrowAccount.md 11 | 还有微信开放平台的登录权限,这个也需要自己去认证或者找朋友借下了。 12 | 13 | 在这里微信公众号接入开发和微信开放平台接入开发就没有重复造轮子了。 14 | 分别使用了两个开源的SDK。 15 | 链接如下 16 | https://github.com/Wechat-Group/weixin-java-tools 这个非常全,你看了就知道了 17 | https://github.com/Pay-Group/best-pay-sdk 这个就是廖师兄开发的SDK,支付使用的就是该SDK 18 | 19 | 20 | # linux服务器启动jar包项目 21 | 22 | centos7提倡的用法 23 | 24 | cd /ets/systemd/system 25 | 到这个目录下,新建一个 AAA.service,可以把AAA设置为项目名的 26 | 27 | vim AAA.service 28 | 文件内容Start: 29 | ``` 30 | [Unit] 31 | Description=AAA #描述 32 | After=syslog.target network.target #依赖 33 | 34 | [Service] 35 | Type=simple 36 | 37 | ExecStart=/usr/bin/java -jar /opt/javaapps/AAA.jar 38 | #前面是java命令的绝对路径 后面是jar包的绝对路径 39 | ExecStop=/bin/kill -15 $MAINPID 40 | 41 | User=root 42 | Group=root 43 | 44 | [Install] 45 | WantedBy=multi-user.target 46 | ``` 47 | 文件结束END 48 | 49 | 使用 50 | systemctl start AAA或者 51 | systemctl start AAA.service 52 | 如果被改变了: 53 | 先运行systemctl daemon-reload再运行systemctl start sell.service 54 | 55 | 停止服务: 56 | systemctl stop AAA或者 57 | systemctl stop AAA.service 58 | 59 | 开机自启动: 60 | systemctl enable AAA或者 61 | systemctl enable AAA.service 62 | 63 | 不想开机启动: 64 | systemctl disable AAA或者 65 | systemctl disable AAA.service 66 | 67 | 68 | # 项目总结 69 | 70 | ## 微信特性 71 | 模板消息,授权,支付和退款 72 | 73 | ## Token认证 74 | 在卖家端登录管理系统用到 75 | 我在aop中已经屏蔽了,因为我没有微信开放平台的认证账号,无法登录 76 | 可以自行去cn.chenhaoxiang.aspect.SellerAuthorizeAspect将类上的注解放开 77 | 78 | ## WebSocket消息 79 | 在买家下订单后,对买家端有消息提示并播放音乐 80 | 81 | ## Redis缓存+分布式锁 82 | Redis的缓存的话,注意增删改更新缓存,否则会出现无法预知的后果 83 | 在这里,如果有商品的抢购活动,就可以使用到Redis的分布式锁了 84 | 85 | 86 | 87 | 我觉得该项目还有一些需要完善的地方 88 | 比如卖家端没有权限控制 89 | 比如应用没有独立,项目里面的商品,订单 90 | 比如哪天修改了商品的代码,会影响到订单的部分 91 | 应该把商品和订单拆分开来,作为两个独立的应用 92 | 93 | 在这个项目中学到了很多。 94 | 学到的最重要的不是一些知识点的学习,而是项目架构方面的学习,比如DTO,比如工具类,比如From,前端表单数据提交的实体类,比如应用独立,前后端分离,分布式和集群等等。 95 | 96 | 在此感谢廖师兄分享的视频教程。 97 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/PushMessageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.config.WechatAccountConfig; 4 | import cn.chenhaoxiang.dto.OrderDTO; 5 | import cn.chenhaoxiang.service.PushMessageService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import me.chanjar.weixin.common.exception.WxErrorException; 8 | import me.chanjar.weixin.mp.api.WxMpService; 9 | import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; 10 | import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: 陈浩翔. 20 | * Date: 2018/1/24. 21 | * Time: 下午 9:24. 22 | * Explain: 23 | */ 24 | @Service 25 | @Slf4j 26 | public class PushMessageServiceImpl implements PushMessageService { 27 | @Autowired 28 | private WxMpService wxMpService; 29 | 30 | @Autowired 31 | private WechatAccountConfig wechatAccountConfig; 32 | @Override 33 | public void orderStatus(OrderDTO orderDTO) { 34 | List dataList = Arrays.asList( 35 | new WxMpTemplateData("first","亲,请记得收货"), 36 | new WxMpTemplateData("keyword1","微信点餐"), 37 | new WxMpTemplateData("keyword2","17674031234"), 38 | new WxMpTemplateData("keyword3",orderDTO.getOrderId()), 39 | new WxMpTemplateData("keyword4",orderDTO.getOrderStatusEnum().getMessage()), 40 | new WxMpTemplateData("keyword5","¥"+orderDTO.getOrderAmount()), 41 | new WxMpTemplateData("remark","欢迎再次光临") 42 | ); 43 | WxMpTemplateMessage templateMessage =WxMpTemplateMessage.builder() 44 | .toUser(orderDTO.getBuyerOpenid()) 45 | .templateId(wechatAccountConfig.getTemplateId().get("orderStatus")) 46 | .data(dataList) 47 | .build(); 48 | try { 49 | wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage); 50 | } catch (WxErrorException e) { 51 | //不抛异常出去 防止其他地方的事务回滚 52 | log.error("[微信模板消息] 发送失败,{}",e); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dao/ProductCategoryDaoTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dao; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import javax.transaction.Transactional; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | //@Transactional有两个不同的包。在Spring的事务管理中应该使用org.springframework.transaction.annotation.Transactional 16 | //在Java EE 应用中,应该使用javax.transaction.Transactional。 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: 陈浩翔. 20 | * Date: 2018/1/8. 21 | * Time: 下午 10:06. 22 | * Explain: 23 | */ 24 | @RunWith(SpringRunner.class) 25 | @SpringBootTest 26 | @Slf4j 27 | public class ProductCategoryDaoTest { 28 | 29 | @Autowired 30 | private ProductCategoryDao productCategoryDao; 31 | 32 | /** 33 | * 测试查找 34 | */ 35 | @Test 36 | public void fingOnetest(){ 37 | ProductCategory productCategory =productCategoryDao.findOne(1); 38 | log.info(productCategory.toString()); 39 | } 40 | 41 | /** 42 | * 新增 43 | */ 44 | @Test 45 | @Transactional //在测试里面的事务是完全回滚,运行完就回滚 46 | public void saveTest(){ 47 | ProductCategory productCategory = new ProductCategory("女生最爱",5); 48 | ProductCategory result = productCategoryDao.save(productCategory); 49 | Assert.assertNotNull(result); 50 | // Assert.assertNotEquals(null,result);//不期望是null,期望是result 和上面是一样的 51 | } 52 | /** 53 | * 更新 54 | * 先查询出来再更新 55 | */ 56 | @Test 57 | public void saveTest2(){ 58 | ProductCategory productCategory = productCategoryDao.findOne(2); 59 | productCategory.setCategoryType(3); 60 | productCategoryDao.save(productCategory); 61 | } 62 | 63 | @Test 64 | public void findByCategoryTypeInTest(){ 65 | List list = Arrays.asList(2,3,4); 66 | List productCategoryList = productCategoryDao.findByCategoryTypeIn(list); 67 | log.info(productCategoryList.toString()); 68 | Assert.assertNotEquals(0,productCategoryList.size()); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/handler/SellExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.handler; 2 | 3 | import cn.chenhaoxiang.config.ProjectUrlConfig; 4 | import cn.chenhaoxiang.exception.ResponseBankException; 5 | import cn.chenhaoxiang.exception.SellAuthorizeException; 6 | import cn.chenhaoxiang.exception.SellException; 7 | import cn.chenhaoxiang.utils.ResultVOUtil; 8 | import cn.chenhaoxiang.vo.ResultVO; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.HttpStatus; 11 | import org.springframework.web.bind.annotation.ControllerAdvice; 12 | import org.springframework.web.bind.annotation.ExceptionHandler; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import org.springframework.web.bind.annotation.ResponseStatus; 15 | import org.springframework.web.servlet.ModelAndView; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: 陈浩翔. 20 | * Date: 2018/1/24. 21 | * Time: 下午 8:41. 22 | * Explain: 异常捕获类 23 | */ 24 | @ControllerAdvice 25 | public class SellExceptionHandler { 26 | 27 | @Autowired 28 | private ProjectUrlConfig projectUrlConfig; 29 | /** 30 | * 全局异常捕捉处理 31 | * 拦截登录异常 32 | * 重定向至登录页面 - 也就是微信扫码登录 33 | * @return 34 | */ 35 | @ExceptionHandler(value = SellAuthorizeException.class) 36 | public ModelAndView handlerSellerAuthorizeException(){ 37 | return new ModelAndView("redirect:" 38 | .concat(projectUrlConfig.getWechatOpenAuthorize())//微信开放平台登录授权地址 39 | .concat("/wechat/qrAuthorize") 40 | .concat("?returnUrl=") 41 | .concat(projectUrlConfig.getProject())//服务器访问的地址 42 | .concat("/seller/login")); 43 | } 44 | 45 | /** 46 | * 全局异常捕捉处理 47 | * @return 48 | */ 49 | @ExceptionHandler(value = SellException.class) 50 | @ResponseBody 51 | public ResultVO handlerSellException(SellException e){ 52 | return ResultVOUtil.error(e.getCode(),e.getMessage()); 53 | } 54 | 55 | /** 56 | * 全局异常捕捉处理 57 | * 返回状态码的修改 不再返回200 58 | * @return 59 | */ 60 | @ExceptionHandler(value = ResponseBankException.class) 61 | @ResponseStatus(HttpStatus.FORBIDDEN) //返回状态码的修改 62 | @ResponseBody 63 | public ResultVO handlerResponseBankException(ResponseBankException e){ 64 | return ResultVOUtil.error(e.getCode(),e.getMessage()); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/service/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cn.chenhaoxiang.service (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 |

cn.chenhaoxiang.service

14 |
15 |

接口

16 | 26 |

27 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/RedisLock.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.redis.core.StringRedisTemplate; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.util.StringUtils; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: 陈浩翔. 12 | * Date: 2018/1/26. 13 | * Time: 下午 10:05. 14 | * Explain:Redis分布式锁 15 | */ 16 | @Component 17 | @Slf4j 18 | public class RedisLock { 19 | @Autowired 20 | private StringRedisTemplate stringRedisTemplate; 21 | 22 | /** 23 | * 加锁 24 | * @param key productId - 商品的唯一标志 25 | * @param value 当前时间+超时时间 26 | * @return 27 | */ 28 | public boolean lock(String key,String value){ 29 | if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){//对应setnx命令 30 | //可以成功设置,也就是key不存在 31 | return true; 32 | } 33 | 34 | //判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁 35 | String currentValue = stringRedisTemplate.opsForValue().get(key); 36 | //如果锁过期 37 | if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){//currentValue不为空且小于当前时间 38 | //获取上一个锁的时间value 39 | String oldValue =stringRedisTemplate.opsForValue().getAndSet(key,value);//对应getset,如果key存在 40 | 41 | //假设两个线程同时进来,key被占用了。获取的值currentValue=A(get取的旧的值肯定是一样的),两个线程的value都是B,key都是K.锁时间已经过期了。 42 | //而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的value已经变成了B。只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。 43 | if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue) ){ 44 | //oldValue不为空且oldValue等于currentValue,也就是校验是不是上个对应的商品时间戳,也是防止并发 45 | return true; 46 | } 47 | } 48 | return false; 49 | } 50 | 51 | 52 | /** 53 | * 解锁 54 | * @param key 55 | * @param value 56 | */ 57 | public void unlock(String key,String value){ 58 | try { 59 | String currentValue = stringRedisTemplate.opsForValue().get(key); 60 | if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value) ){ 61 | stringRedisTemplate.opsForValue().getOperations().delete(key);//删除key 62 | } 63 | } catch (Exception e) { 64 | log.error("[Redis分布式锁] 解锁出现异常了,{}",e); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/aspect/SellerAuthorizeAspect.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.aspect; 2 | 3 | import cn.chenhaoxiang.constans.CookieConstant; 4 | import cn.chenhaoxiang.constans.RedisConstans; 5 | import cn.chenhaoxiang.exception.SellAuthorizeException; 6 | import cn.chenhaoxiang.exception.SellException; 7 | import cn.chenhaoxiang.utils.CookieUtil; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.aspectj.lang.annotation.Aspect; 10 | import org.aspectj.lang.annotation.Before; 11 | import org.aspectj.lang.annotation.Pointcut; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.data.redis.core.StringRedisTemplate; 14 | import org.springframework.stereotype.Component; 15 | import org.springframework.util.StringUtils; 16 | import org.springframework.web.context.request.RequestContextHolder; 17 | import org.springframework.web.context.request.ServletRequestAttributes; 18 | 19 | import javax.servlet.http.Cookie; 20 | import javax.servlet.http.HttpServletRequest; 21 | 22 | /** 23 | * Created with IntelliJ IDEA. 24 | * User: 陈浩翔. 25 | * Date: 2018/1/24. 26 | * Time: 下午 8:31. 27 | * Explain: 卖家授权aop 28 | */ 29 | //TODO 暂时屏蔽 能够登录后需要放开,也就是有开放平台登录账号 30 | //@Aspect 31 | //@Component 32 | @Slf4j 33 | public class SellerAuthorizeAspect { 34 | 35 | @Autowired 36 | private StringRedisTemplate redisTemplate; 37 | /** 38 | * 定义切面 39 | */ 40 | @Pointcut("execution(public * cn.chenhaoxiang.controller.Seller*.*(..))"+ 41 | "&& !execution(public * cn.chenhaoxiang.controller.SellerUserController.*(..))") //排除登录登出 42 | public void verify(){} 43 | 44 | /** 45 | * 运行之前 46 | */ 47 | @Before("verify()") 48 | public void doVerify(){ 49 | ServletRequestAttributes attributes =(ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); 50 | HttpServletRequest request = attributes.getRequest();//获取HttpServletRequest 51 | //查询Cookie 52 | Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN); 53 | if(cookie==null){ 54 | log.warn("[登录校验] Cookie中查不到token"); 55 | throw new SellAuthorizeException(); 56 | } 57 | //去redis中查 58 | String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstans.TOKEN_PREFIX,cookie.getValue())); 59 | if(StringUtils.isEmpty(tokenValue)){ 60 | log.warn("[登录校验] Redis中查不到token"); 61 | throw new SellAuthorizeException(); 62 | } 63 | 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /sell/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | logbak: %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ERROR 21 | 22 | DENY 23 | ACCEPT 24 | 25 | 26 | 27 | 28 | logbak: %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n 29 | 30 | 31 | 32 | 33 | 34 | F://log//info.%d.log 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ERROR 43 | 44 | 45 | 46 | logbak: %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n 47 | 48 | 49 | 50 | 51 | 52 | F://log//error.%d.log 53 | 54 | 55 | 56 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dto/OrderDTO.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dto; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderDetail; 4 | import cn.chenhaoxiang.enums.OrderStausEnum; 5 | import cn.chenhaoxiang.enums.PayStatusEnum; 6 | import cn.chenhaoxiang.utils.EnumUtil; 7 | import cn.chenhaoxiang.utils.serializer.Date2LongSerializer; 8 | import com.fasterxml.jackson.annotation.JsonIgnore; 9 | import com.fasterxml.jackson.annotation.JsonInclude; 10 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 11 | import lombok.Data; 12 | 13 | import javax.persistence.Id; 14 | import java.math.BigDecimal; 15 | import java.util.ArrayList; 16 | import java.util.Date; 17 | import java.util.List; 18 | 19 | /** 20 | * Created with IntelliJ IDEA. 21 | * User: 陈浩翔. 22 | * Date: 2018/1/14. 23 | * Time: 下午 10:34. 24 | * Explain: 数据传输对象,在数据传输时候使用的,可以看成Service层返回到Controller层的数据 25 | * 订单DTO 26 | */ 27 | @Data 28 | //Include.Include.ALWAYS 默认 29 | //Include.NON_DEFAULT 属性为默认值不序列化 30 | //Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化 31 | //Include.NON_NULL 属性为NULL 不序列化 32 | //@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) //旧版本的,已弃用 33 | //@JsonInclude(JsonInclude.Include.NON_NULL)//如果属性为null就不返回到前端去,也就是转json 为NULL不参加序列化 34 | public class OrderDTO { 35 | /** 36 | * 订单ID 37 | */ 38 | private String orderId; 39 | /** 40 | * 买家名字 41 | */ 42 | private String buyerName; 43 | 44 | /** 45 | * 买家手机号 46 | */ 47 | private String buyerPhone; 48 | 49 | /** 50 | * 买家地址 51 | */ 52 | private String buyerAddress; 53 | 54 | /** 55 | * 买家微信Openid 56 | */ 57 | private String buyerOpenid; 58 | /** 59 | * 订单金额 60 | */ 61 | private BigDecimal orderAmount; 62 | 63 | /** 64 | * 订单状态,默认为新下单 65 | */ 66 | private Integer orderStatus;//初始化状态不需要了 67 | 68 | /** 69 | * 支付状态,默认为0-未支付 70 | */ 71 | private Integer payStatus;//初始化状态不需要了 72 | 73 | /** 74 | * 创建时间 75 | */ 76 | @JsonSerialize(using = Date2LongSerializer.class)//让时间戳精度在秒 77 | private Date createTime; 78 | 79 | /** 80 | * 更新时间 81 | */ 82 | @JsonSerialize(using = Date2LongSerializer.class)//让时间戳精度在秒 83 | private Date updateTime; 84 | 85 | /** 86 | * 订单详情 87 | */ 88 | private List orderDetailList; 89 | // private List orderDetailList = new ArrayList<>();//赋予初始值 90 | 91 | @JsonIgnore //对象转换成json格式返回到前端会忽略该方法 92 | public OrderStausEnum getOrderStatusEnum(){ 93 | return EnumUtil.getByCode(orderStatus,OrderStausEnum.class); 94 | } 95 | @JsonIgnore //对象转换成json格式返回到前端会忽略该方法 96 | public PayStatusEnum getPayStatusEnum(){ 97 | return EnumUtil.getByCode(payStatus,PayStatusEnum.class); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /javadoc/sell/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | sell 0.0.1-SNAPSHOT API 8 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <noscript> 69 | <div>您的浏览器已禁用 JavaScript。</div> 70 | </noscript> 71 | <h2>框架预警</h2> 72 | <p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href="overview-summary.html">非框架版本</a>。</p> 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /javadoc/sell/overview-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 概览列表 (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 39 |

 

40 | 41 | 42 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/order/detail.ftl: -------------------------------------------------------------------------------- 1 | 2 | <#include "../common/header.ftl"> 3 | 4 |
5 | <#--边栏sidebar--> 6 | <#include "../common/nav.ftl"> 7 | <#--主要内容区域--> 8 |
9 |
10 |
11 |
12 | 13 | 14 | 15 | 18 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 32 | 33 |
16 | 订单ID 17 | 19 | 订单总金额 20 |
26 | ${orderDTO.orderId} 27 | 29 | ${orderDTO.orderAmount} 30 |
34 |
35 | 36 | <#--订单详情表数据--> 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | <#list orderDTO.orderDetailList as orderDetail> 50 | 51 | 54 | 57 | 60 | 63 | 66 | 67 | 68 | 69 |
商品ID商品名称单价数量总额
52 | ${orderDetail.productId} 53 | 55 | ${orderDetail.productName} 56 | 58 | ${orderDetail.productPrice} 59 | 61 | ${orderDetail.productQuantity} 62 | 64 | ${orderDetail.productQuantity * orderDetail.productPrice} 65 |
70 |
71 | 72 | <#--操作--> 73 |
74 | <#if orderDTO.getOrderStatusEnum().message == "新订单"> 75 | 完结订单 76 | 取消订单 77 | 78 |
79 | 80 |
81 |
82 |
83 |
84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/ProductInfoServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductInfo; 4 | import cn.chenhaoxiang.enums.ProductStatusEnum; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.data.domain.Page; 11 | import org.springframework.data.domain.PageRequest; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | 14 | import java.math.BigDecimal; 15 | import java.util.List; 16 | 17 | import static org.junit.Assert.*; 18 | 19 | /** 20 | * Created with IntelliJ IDEA. 21 | * User: 陈浩翔. 22 | * Date: 2018/1/9. 23 | * Time: 下午 7:20. 24 | * Explain: 25 | */ 26 | @RunWith(SpringRunner.class) 27 | @SpringBootTest 28 | public class ProductInfoServiceImplTest { 29 | @Autowired 30 | private ProductInfoServiceImpl productInfoService; 31 | 32 | @Test 33 | public void findOne() throws Exception { 34 | ProductInfo productInfo = productInfoService.findOne("123456"); 35 | Assert.assertEquals("123456",productInfo.getProductId()); 36 | } 37 | 38 | @Test 39 | public void findUpAll() throws Exception { 40 | List productInfoList = productInfoService.findUpAll(); 41 | Assert.assertNotEquals(0,productInfoList.size()); 42 | } 43 | 44 | @Test 45 | public void findAll() throws Exception { 46 | PageRequest request = new PageRequest(0,2);//第几页,内容行数 47 | Page productInfoPage = productInfoService.findAll(request);//分页 48 | // System.out.println(productInfoPage.getTotalElements());//输出总元素 49 | // productInfoPage.getContent();//查询的结果 50 | Assert.assertNotEquals(0,productInfoPage.getTotalElements()); 51 | } 52 | 53 | @Test 54 | public void save() throws Exception { 55 | ProductInfo productInfo = new ProductInfo(); 56 | productInfo.setProductId("123457"); 57 | productInfo.setProductName("皮皮虾"); 58 | productInfo.setProductPrice(new BigDecimal(15.5)); 59 | productInfo.setProductStock(100); 60 | productInfo.setProductDescription("虾子不错"); 61 | productInfo.setProductIcon("http://XXXX.jpg"); 62 | productInfo.setProductStatus(ProductStatusEnum.DOWN.getCode()); 63 | productInfo.setCategoryType(2); 64 | 65 | ProductInfo result = productInfoService.save(productInfo); 66 | Assert.assertNotNull(result); 67 | } 68 | 69 | /** 70 | * 测试上架 71 | * @throws Exception 72 | */ 73 | @Test 74 | public void onSale() throws Exception { 75 | ProductInfo result = productInfoService.onSale("1234568"); 76 | Assert.assertEquals(ProductStatusEnum.UP,result.getProductStatusEnum()); 77 | } 78 | 79 | /** 80 | * 测试下架 81 | * @throws Exception 82 | */ 83 | @Test 84 | public void offSale() throws Exception { 85 | ProductInfo result = productInfoService.offSale("1234568"); 86 | Assert.assertEquals(ProductStatusEnum.DOWN,result.getProductStatusEnum()); 87 | } 88 | 89 | 90 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/SeckillServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.exception.SellException; 4 | import cn.chenhaoxiang.service.RedisLock; 5 | import cn.chenhaoxiang.service.SeckillService; 6 | import cn.chenhaoxiang.utils.KeyUtil; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | /** 14 | * Created with IntelliJ IDEA. 15 | * User: 陈浩翔. 16 | * Date: 2018/1/26. 17 | * Time: 下午 9:30. 18 | * Explain: 19 | */ 20 | @Service 21 | public class SeckillServiceImpl implements SeckillService{ 22 | 23 | @Autowired 24 | private RedisLock redisLock; 25 | 26 | private static final int TIMEOUT = 10*1000;//超时时间 10s 27 | 28 | /** 29 | * 活动,特价,限量100000份 30 | */ 31 | static Map products;//模拟商品信息表 32 | static Map stock;//模拟库存表 33 | static Map orders;//模拟下单成功用户表 34 | static { 35 | /** 36 | * 模拟多个表,商品信息表,库存表,秒杀成功订单表 37 | */ 38 | products = new HashMap<>(); 39 | stock = new HashMap<>(); 40 | orders = new HashMap<>(); 41 | products.put("123456",100000); 42 | stock.put("123456",100000); 43 | } 44 | 45 | private String queryMap(String productId){//模拟查询数据库 46 | return "国庆活动,皮蛋特教,限量" 47 | +products.get(productId) 48 | +"份,还剩:"+stock.get(productId) 49 | +"份,该商品成功下单用户数:" 50 | +orders.size()+"人"; 51 | } 52 | 53 | @Override 54 | public String querySecKillProductInfo(String productId) { 55 | return this.queryMap(productId); 56 | } 57 | 58 | //解决方法二,基于Redis的分布式锁 http://redis.cn/commands/setnx.html http://redis.cn/commands/getset.html 59 | //SETNX命令 将key设置值为value,如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做 60 | // GETSET命令 先查询出原来的值,值不存在就返回nil。然后再设置值 61 | //支持分布式,可以更细粒度的控制 62 | //多台机器上多个线程对一个数据进行操作的互斥。 63 | //Redis是单线程的!!! 64 | @Override 65 | public void orderProductMocckDiffUser(String productId) {//解决方法一:synchronized锁方法是可以解决的,但是请求会变慢,请求变慢是正常的。主要是没做到细粒度控制。比如有很多商品的秒杀,但是这个把所有商品的秒杀都锁住了。而且这个只适合单机的情况,不适合集群 66 | 67 | //加锁 68 | long time = System.currentTimeMillis() + TIMEOUT; 69 | if(!redisLock.lock(productId,String.valueOf(time))){ 70 | throw new SellException(101,"很抱歉,人太多了,换个姿势再试试~~"); 71 | } 72 | 73 | //1.查询该商品库存,为0则活动结束 74 | int stockNum = stock.get(productId); 75 | if(stockNum==0){ 76 | throw new SellException(100,"活动结束"); 77 | }else { 78 | //2.下单 79 | orders.put(KeyUtil.getUniqueKey(),productId); 80 | //3.减库存 81 | stockNum =stockNum-1;//不做处理的话,高并发下会出现超卖的情况,下单数,大于减库存的情况。虽然这里减了,但由于并发,减的库存还没存到map中去。新的并发拿到的是原来的库存 82 | try{ 83 | Thread.sleep(100);//模拟减库存的处理时间 84 | }catch (InterruptedException e){ 85 | e.printStackTrace(); 86 | } 87 | stock.put(productId,stockNum); 88 | } 89 | 90 | //解锁 91 | redisLock.unlock(productId,String.valueOf(time)); 92 | 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /sell/src/main/resources/templates/product/index.ftl: -------------------------------------------------------------------------------- 1 | 2 | <#include "../common/header.ftl"> 3 | 4 | 5 |
6 | <#--边栏sidebar--> 7 | <#include "../common/nav.ftl"> 8 | <#--主要内容区域--> 9 |
10 | <#--fluid-流动布局--> 11 |
12 | 13 |
14 |
15 |
16 |
17 | 18 | 19 |
20 | 21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 |
30 | 31 | 32 |
33 |
34 | 35 | 36 | 37 |
38 | 39 |
40 | 41 | 53 |
54 | 55 | <#--加个隐藏的字段--> 56 | 57 | 58 |
59 |
60 |
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/config/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.config; 2 | 3 | import cn.chenhaoxiang.handler.HandshakeInterceptor; 4 | import cn.chenhaoxiang.service.WebSocket; 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.context.ServletContextAware; 11 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 12 | import org.springframework.web.socket.WebSocketHandler; 13 | import org.springframework.web.socket.config.annotation.EnableWebSocket; 14 | import org.springframework.web.socket.config.annotation.WebSocketConfigurer; 15 | import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; 16 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 17 | 18 | import javax.servlet.ServletContext; 19 | 20 | /** 21 | * Created with IntelliJ IDEA. 22 | * User: 陈浩翔. 23 | * Date: 2018/1/24. 24 | * Time: 下午 10:04. 25 | * Explain: websocket 配置 26 | */ 27 | // 现在已经把之前简单websocket配置换成了继承AbstractWebSocketHandler的方式实现websocket 28 | //@Component 29 | //public class WebSocketConfig { 30 | // //第一种方式 31 | // @Bean 32 | // public ServerEndpointExporter serverEndpointExporter(){ 33 | // return new ServerEndpointExporter(); 34 | // } 35 | //} 36 | @Configuration 37 | @EnableWebSocket 38 | public class WebSocketConfig implements WebSocketConfigurer { 39 | 40 | /** 41 | * 测试该句会出现异常ServerEndpointExporter causes refresh to fail with java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available 42 | * 请前去把cn.chenhaoxiang.config.WebSocketConfig中serverEndpointExporter方法上的Bean注解注释 43 | * 问题解决: https://jira.spring.io/browse/SPR-12340 44 | * https://jira.spring.io/browse/SPR-12109 45 | * 46 | * @throws Exception 47 | */ 48 | // @Bean 49 | // public ServerEndpointExporter serverEndpointExporter(ApplicationContext context) { 50 | // return new ServerEndpointExporter(); 51 | // } 52 | /** 53 | * 解决方法,使用下面的代码替换上面的代码 54 | * @param applicationContext 55 | * @return 56 | */ 57 | @Bean 58 | public ServletContextAware endpointExporterInitializer(final ApplicationContext applicationContext) { 59 | return new ServletContextAware() { 60 | @Override 61 | public void setServletContext(ServletContext servletContext) { 62 | ServerEndpointExporter serverEndpointExporter = new ServerEndpointExporter(); 63 | serverEndpointExporter.setApplicationContext(applicationContext); 64 | try { 65 | serverEndpointExporter.afterPropertiesSet(); 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | }; 71 | } 72 | 73 | 74 | @Override 75 | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 76 | registry.addHandler(new WebSocket(), "/webSocket").addInterceptors(new HandshakeInterceptor());//Spring为了保护应用,OriginHandshakeInterceptor拦截器帮我们加了拦截器防止跨域.但是我们自己实现了拦截器,就不用担心了。还可以通过setAllowedOrigins("*")来允许跨域访问 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/PayController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.enums.ResultEnum; 5 | import cn.chenhaoxiang.exception.SellException; 6 | import cn.chenhaoxiang.service.OrderService; 7 | import cn.chenhaoxiang.service.PayService; 8 | import com.lly835.bestpay.model.PayResponse; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.*; 13 | import org.springframework.web.servlet.ModelAndView; 14 | 15 | import java.util.Map; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: 陈浩翔. 20 | * Date: 2018/1/19. 21 | * Time: 下午 9:22. 22 | * Explain: 23 | */ 24 | @Controller //返回界面用 25 | @RequestMapping("/pay") 26 | @Slf4j 27 | public class PayController { 28 | 29 | @Autowired 30 | private OrderService orderService; 31 | @Autowired 32 | private PayService payService; 33 | 34 | /** 35 | * 36 | * TODO 用"师兄干货"的支付接口来测试的支付接口 37 | * 支付授权:http://sell.springboot.cn/sell/pay?openid=oTgZpwd3BBEDTuMpw6b6f0gNUCik&orderId=1516539154652409049&returnUrl=chenhaoxiang.cn 38 | * 回调地址:http://anyi.nat300.top/pay?openid=oTgZpwd3BBEDTuMpw6b6f0gNUCik 39 | * @param openid 40 | * @param map 41 | * @return 42 | */ 43 | @GetMapping("") 44 | public ModelAndView index(@RequestParam("openid") String openid, 45 | @RequestParam("orderId") String orderId, 46 | @RequestParam("returnUrl")String returnUrl, 47 | Map map){ 48 | log.info("openid={},orderId={}.returnUrl={},",openid,orderId,returnUrl); 49 | //1.查询订单 50 | // String orderId ="1516539154906548294";//测试的orderId 51 | OrderDTO orderDTO = orderService.findOne(orderId); 52 | if(orderDTO==null){ 53 | throw new SellException(ResultEnum.ORDER_NOT_EXIST); 54 | } 55 | //发起支付 56 | PayResponse payResponse = payService.create(orderDTO); 57 | map.put("payResponse",payResponse); 58 | map.put("returnUrl",returnUrl); 59 | 60 | return new ModelAndView("pay/create",map);//页面,参数 61 | } 62 | 63 | 64 | /** 65 | * 发起支付 66 | * @param orderId 67 | * @param returnUrl 68 | * @param map 69 | * @return 70 | */ 71 | @GetMapping("/create") 72 | public ModelAndView create(@RequestParam("orderId") String orderId, 73 | @RequestParam("returnUrl")String returnUrl, 74 | Map map){ 75 | //1.查询订单 76 | OrderDTO orderDTO = orderService.findOne(orderId); 77 | if(orderDTO==null){ 78 | throw new SellException(ResultEnum.ORDER_NOT_EXIST); 79 | } 80 | //发起支付 81 | PayResponse payResponse = payService.create(orderDTO); 82 | 83 | map.put("payResponse",payResponse); 84 | map.put("returnUrl",returnUrl); 85 | 86 | return new ModelAndView("pay/create",map);//页面,参数 87 | } 88 | 89 | /** 90 | * 微信异步通知是否支付成功 91 | */ 92 | @PostMapping("notify") 93 | public ModelAndView notify(@RequestBody String notifyData){//入参为微信返回的xml格式的字符串 94 | payService.notify(notifyData); 95 | //通知微信处理结果 - 返回xml字符串 96 | return new ModelAndView("pay/success"); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/SellerCategoryController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import cn.chenhaoxiang.exception.SellException; 5 | import cn.chenhaoxiang.form.ProductCategoryForm; 6 | import cn.chenhaoxiang.service.ProductCategoryService; 7 | import org.springframework.beans.BeanUtils; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.validation.BindingResult; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.servlet.ModelAndView; 16 | 17 | import javax.validation.Valid; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | /** 22 | * Created with IntelliJ IDEA. 23 | * User: 陈浩翔. 24 | * Date: 2018/1/23. 25 | * Time: 下午 10:00. 26 | * Explain: 卖家类目controller 27 | */ 28 | @Controller 29 | @RequestMapping("/seller/category") 30 | public class SellerCategoryController { 31 | 32 | @Autowired 33 | private ProductCategoryService productCategoryService; 34 | 35 | /** 36 | * 类目列表 37 | * @param map 38 | * @return 39 | */ 40 | @GetMapping("list") 41 | public ModelAndView list(Map map){ 42 | List productCategoryList =productCategoryService.findAll(); 43 | map.put("productCategoryList",productCategoryList); 44 | return new ModelAndView("category/list",map); 45 | } 46 | 47 | /** 48 | * 修改类目 49 | * @param categoryId 50 | * @param map 51 | * @return 52 | */ 53 | @GetMapping("index") 54 | public ModelAndView index(@RequestParam(value = "categoryId",required = false)Integer categoryId, 55 | Map map){ 56 | if(categoryId!=null&&categoryId > 0){ 57 | //查询类目 58 | ProductCategory productCategory = productCategoryService.findOne(categoryId); 59 | map.put("productCategory",productCategory); 60 | } 61 | return new ModelAndView("category/index",map); 62 | } 63 | 64 | /** 65 | * 增加/修改类目 66 | * @param productCategoryForm 67 | * @param bindingResult 68 | * @param map 69 | * @return 70 | */ 71 | @PostMapping("save") 72 | public ModelAndView save(@Valid ProductCategoryForm productCategoryForm, 73 | BindingResult bindingResult, 74 | Map map){ 75 | if(bindingResult.hasErrors()){ 76 | map.put("msg",bindingResult.getFieldError().getDefaultMessage()); 77 | map.put("url","/seller/category/index"); 78 | return new ModelAndView("common/error",map); 79 | } 80 | ProductCategory productCategory = new ProductCategory(); 81 | try { 82 | if(productCategoryForm.getCategoryId()!=null){ 83 | productCategory = productCategoryService.findOne(productCategoryForm.getCategoryId()); 84 | } 85 | BeanUtils.copyProperties(productCategoryForm,productCategory); 86 | productCategoryService.save(productCategory); 87 | }catch (SellException e){ 88 | map.put("msg",e.getMessage()); 89 | map.put("url","/seller/category/index"); 90 | return new ModelAndView("common/error",map); 91 | } 92 | map.put("url","/seller/category/list"); 93 | return new ModelAndView("common/success",map); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/dataObject/mapper/ProductCategoryMapper.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject.mapper; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import org.apache.ibatis.annotations.*; 5 | import org.mybatis.spring.annotation.MapperScan; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: 陈浩翔. 14 | * Date: 2018/1/25. 15 | * Time: 下午 9:04. 16 | * Explain: MyBatis的Mapper 17 | */ 18 | //在SellApplication上配置了注解@MapperScan(basePackages = "cn.chenhaoxiang.dataObject.mapper")//配置mybatis mapper扫描路径 所以不用我们再写注解注入Bean 19 | @Mapper 20 | @Component //也可以通过上面两个注解实现注入Bean 21 | public interface ProductCategoryMapper { 22 | /** 23 | * 通过Map插入 24 | * @param map 25 | * @return 26 | */ 27 | @Insert("insert into product_category(category_name,category_type) values (#{category_name,jdbcType=VARCHAR},#{category_type,jdbcType=INTEGER})") 28 | int insertByMap(Map map); 29 | 30 | /** 31 | * 通过对象插入 32 | * @param productCategory 33 | * @return 34 | */ 35 | @Insert("insert into product_category(category_name,category_type) values (#{categoryName,jdbcType=VARCHAR},#{categoryType,jdbcType=INTEGER})") 36 | int insertByObject(ProductCategory productCategory); 37 | 38 | /** 39 | * 通过CategoryType查询 40 | * @param categoryType 41 | * @return 42 | */ 43 | @Select("select * from product_category where category_type=#{categoryType,jdbcType=INTEGER}") 44 | @Results({ 45 | @Result(column = "category_id",property = "categoryId"), 46 | @Result(column = "category_name",property = "categoryName"), 47 | @Result(column = "category_type",property = "categoryType"), 48 | @Result(column = "create_time",property = "createTime"), 49 | })//映射 50 | ProductCategory findByCategoryType(Integer categoryType); 51 | 52 | /** 53 | * 通过CategoryName查询多条数据 54 | * @param categoryName 55 | * @return 56 | */ 57 | @Select("select * from product_category where category_name=#{categoryName}") 58 | @Results({ 59 | @Result(column = "category_id",property = "categoryId"), 60 | @Result(column = "category_name",property = "categoryName"), 61 | @Result(column = "category_type",property = "categoryType"), 62 | @Result(column = "create_time",property = "createTime"), 63 | })//映射 64 | List findByCategoryName(String categoryName); 65 | 66 | /** 67 | * 通过categoryType修改categoryName 68 | * @param categoryType 69 | * @param categoryName 70 | * @return 71 | */ 72 | @Update("update product_category set category_name=#{categoryName} where category_type=#{categoryType}") 73 | int updateByCategoryType(@Param("categoryType")Integer categoryType,@Param("categoryName")String categoryName); 74 | 75 | /** 76 | * 通过categoryType修改对象category_name 77 | * @param productCategory 78 | * @return 79 | */ 80 | @Update("update product_category set category_name=#{categoryName} where category_type=#{categoryType}") 81 | int updateByObject(ProductCategory productCategory); 82 | 83 | /** 84 | * 删除 85 | * @param categoryType 86 | * @return 87 | */ 88 | @Delete("delete from product_category where category_type=#{categoryType}") 89 | int deleteByCategoryType(Integer categoryType); 90 | 91 | /** 92 | * 配置xml的方式实现查询 93 | * 配置文件的resources下面 94 | * 在yml配置文件中配置xml的扫描路径 95 | * xml的写法可以百度一下,spring集成mybatis的,现在很多人的写法都是这种xml的。包括我自己,哈哈,以后的项目会用注解方式了 96 | * mybatis官方不推荐这种写法噢 97 | * @param categoryType 98 | * @return 99 | */ 100 | ProductCategory selectByCategoryType(Integer categoryType); 101 | } 102 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/dataObject/mapper/ProductCategoryMapperTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.dataObject.mapper; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * User: 陈浩翔. 19 | * Date: 2018/1/25. 20 | * Time: 下午 9:10. 21 | * Explain: 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | @Slf4j 26 | public class ProductCategoryMapperTest { 27 | 28 | @Autowired 29 | private ProductCategoryMapper productCategoryMapper; 30 | 31 | /** 32 | * 测试该句会出现异常ServerEndpointExporter causes refresh to fail with java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available 33 | * 请前去把cn.chenhaoxiang.config.WebSocketConfig中serverEndpointExporter方法上的Bean注解注释 34 | * 问题解决: https://jira.spring.io/browse/SPR-12340 35 | * https://jira.spring.io/browse/SPR-12109 36 | * 现在已经把之前简单websocket配置换成了继承AbstractWebSocketHandler的方式实现websocket 37 | * @throws Exception 38 | */ 39 | @Test 40 | public void insertByMap() throws Exception { 41 | Map map = new HashMap<>(); 42 | map.put("category_name","测试使用"); 43 | map.put("category_type",7); 44 | int result =productCategoryMapper.insertByMap(map); 45 | Assert.assertEquals(1,result); 46 | } 47 | 48 | @Test 49 | public void insertByObject() throws Exception { 50 | ProductCategory productCategory = new ProductCategory(); 51 | productCategory.setCategoryName("美味的"); 52 | productCategory.setCategoryType(11); 53 | int result =productCategoryMapper.insertByObject(productCategory); 54 | Assert.assertEquals(1,result); 55 | } 56 | 57 | @Test 58 | public void findByCategoryType() throws Exception { 59 | ProductCategory productCategory =productCategoryMapper.findByCategoryType(9); 60 | log.info("productCategory={}",productCategory); 61 | Assert.assertNotNull(productCategory); 62 | } 63 | 64 | @Test 65 | public void findByCategoryName() throws Exception { 66 | List productCategoryList =productCategoryMapper.findByCategoryName("美味的"); 67 | log.info("productCategoryList={}",productCategoryList); 68 | Assert.assertNotEquals(0,productCategoryList.size()); 69 | } 70 | 71 | @Test 72 | public void updateByCategoryType() throws Exception { 73 | int result =productCategoryMapper.updateByCategoryType(11,"测试11"); 74 | Assert.assertEquals(1,result); 75 | } 76 | 77 | @Test 78 | public void updateByObject() throws Exception { 79 | ProductCategory productCategory = new ProductCategory(); 80 | productCategory.setCategoryName("美味的"); 81 | productCategory.setCategoryType(11); 82 | int result =productCategoryMapper.updateByObject(productCategory); 83 | Assert.assertEquals(1,result); 84 | } 85 | 86 | 87 | @Test 88 | public void deleteByCategoryType() throws Exception { 89 | int result =productCategoryMapper.deleteByCategoryType(11); 90 | Assert.assertEquals(1,result); 91 | } 92 | 93 | @Test 94 | public void selectByCategoryType() throws Exception { 95 | ProductCategory productCategory =productCategoryMapper.selectByCategoryType(9); 96 | log.info("返回结果={}",productCategory); 97 | Assert.assertNotNull(productCategory); 98 | } 99 | 100 | 101 | } -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/SellerUserController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.config.ProjectUrlConfig; 4 | import cn.chenhaoxiang.constans.CookieConstant; 5 | import cn.chenhaoxiang.constans.RedisConstans; 6 | import cn.chenhaoxiang.dataObject.SellerInfo; 7 | import cn.chenhaoxiang.enums.ResultEnum; 8 | import cn.chenhaoxiang.exception.SellException; 9 | import cn.chenhaoxiang.service.SellerService; 10 | import cn.chenhaoxiang.utils.CookieUtil; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.data.redis.core.StringRedisTemplate; 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.web.bind.annotation.GetMapping; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | import org.springframework.web.bind.annotation.RequestParam; 17 | import org.springframework.web.bind.annotation.RestController; 18 | import org.springframework.web.servlet.ModelAndView; 19 | 20 | import javax.servlet.http.Cookie; 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpServletResponse; 23 | import java.util.Map; 24 | import java.util.UUID; 25 | import java.util.concurrent.TimeUnit; 26 | 27 | /** 28 | * Created with IntelliJ IDEA. 29 | * User: 陈浩翔. 30 | * Date: 2018/1/24. 31 | * Time: 下午 7:27. 32 | * Explain: 卖家用户相关操作 33 | */ 34 | @Controller //涉及到页面跳转。不用@RestController 35 | @RequestMapping("/seller") 36 | public class SellerUserController { 37 | 38 | @Autowired 39 | private SellerService sellerService; 40 | 41 | @Autowired 42 | private StringRedisTemplate stringRedisTemplate; 43 | @Autowired 44 | private ProjectUrlConfig projectUrlConfig; 45 | /** 46 | * 登录 47 | * @param openid 48 | */ 49 | @GetMapping("/login") 50 | public ModelAndView login(@RequestParam("openid") String openid, 51 | HttpServletResponse response, 52 | Map map){ 53 | //1.openid去和数据库里的数据匹配 54 | SellerInfo sellerInfo = sellerService.findSellerInfoByOpenid(openid); 55 | //TODO 未考虑新增的情况,也就是用户微信扫码登录不存在openid的情况下 56 | if(sellerInfo==null){ 57 | map.put("msg", ResultEnum.LOGIN_FAIL.getMessage()); 58 | map.put("url","/seller/order/list"); 59 | return new ModelAndView("common/error",map); 60 | } 61 | //2.设置token至Redis 62 | // stringRedisTemplate.opsForValue().set("abc","122");//操作某些value 写入key-value 63 | String token= UUID.randomUUID().toString(); 64 | stringRedisTemplate.opsForValue().set(String.format(RedisConstans.TOKEN_PREFIX,token),openid,RedisConstans.EXPIPE, TimeUnit.SECONDS);//key,value,过期时间,时间单位 s 65 | 66 | //3.设置token至cookie 67 | CookieUtil.set(response, CookieConstant.TOKEN,token,CookieConstant.EXPIPE); 68 | //做一个跳转获取订单列表后再跳转 重定向不要带项目名 - 最好带绝对地址 也就是带http://的绝对地址 69 | return new ModelAndView("redirect:"+projectUrlConfig.getProject()+"/seller/order/list"); 70 | } 71 | 72 | /** 73 | * 登出 74 | * @param request 75 | * @param response 76 | * @param map 77 | */ 78 | @GetMapping("/logout") 79 | public ModelAndView logout(HttpServletRequest request, 80 | HttpServletResponse response, 81 | Map map){ 82 | //1.从Cookie查询 83 | Cookie cookie =CookieUtil.get(request,CookieConstant.TOKEN); 84 | if(cookie!=null){ 85 | //2.清除redis 86 | stringRedisTemplate.opsForValue().getOperations().delete(String.format(RedisConstans.TOKEN_PREFIX,cookie.getValue())); 87 | //3.清除cookie 88 | CookieUtil.del(response,CookieConstant.TOKEN); 89 | } 90 | map.put("msg",ResultEnum.LOGOUT_SUCCESS.getMessage()); 91 | map.put("url","/seller/order/list"); 92 | return new ModelAndView("common/success",map); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/service/impl/PayServiceImpl.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.enums.ResultEnum; 5 | import cn.chenhaoxiang.exception.SellException; 6 | import cn.chenhaoxiang.service.OrderService; 7 | import cn.chenhaoxiang.service.PayService; 8 | import cn.chenhaoxiang.utils.JsonUtil; 9 | import cn.chenhaoxiang.utils.MathUtil; 10 | import com.lly835.bestpay.enums.BestPayTypeEnum; 11 | import com.lly835.bestpay.model.PayRequest; 12 | import com.lly835.bestpay.model.PayResponse; 13 | import com.lly835.bestpay.model.RefundRequest; 14 | import com.lly835.bestpay.model.RefundResponse; 15 | import com.lly835.bestpay.service.impl.BestPayServiceImpl; 16 | import lombok.extern.slf4j.Slf4j; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.stereotype.Service; 19 | 20 | /** 21 | * Created with IntelliJ IDEA. 22 | * User: 陈浩翔. 23 | * Date: 2018/1/19. 24 | * Time: 下午 9:25. 25 | * Explain: 26 | */ 27 | @Service 28 | @Slf4j 29 | public class PayServiceImpl implements PayService{ 30 | 31 | private static final String ORDER_NAME = "微信点餐订单"; 32 | 33 | @Autowired 34 | private BestPayServiceImpl bestPayService; 35 | 36 | @Autowired 37 | private OrderService orderService; 38 | 39 | @Override 40 | public PayResponse create(OrderDTO orderDTO) { 41 | PayRequest payRequest = new PayRequest(); 42 | payRequest.setOpenid(orderDTO.getBuyerOpenid()); 43 | payRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue()); 44 | payRequest.setOrderId(orderDTO.getOrderId()); 45 | payRequest.setOrderName(ORDER_NAME); 46 | payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5); 47 | log.info("[微信支付] 发起支付,request={}",JsonUtil.toJson(payRequest)); 48 | PayResponse payResponse = bestPayService.pay(payRequest); 49 | log.info("[微信支付] 发起支付,payResponse={}", JsonUtil.toJson(payResponse)); 50 | return payResponse; 51 | } 52 | 53 | @Override 54 | public PayResponse notify(String notifyData) { 55 | //1.验证notifyData签名 - bestPayService已经做了 56 | //2.验证notifyData支付状态 - bestPayService已经做了 57 | //3.验证支付金额 58 | //4.支付人(下单人 == 支付人) - 没有好友代付的,看具体需求 59 | PayResponse payResponse = bestPayService.asyncNotify(notifyData); 60 | log.info("[微信支付] 异步通知,payResponse={}",JsonUtil.toJson(payResponse)); 61 | 62 | //查询订单 63 | OrderDTO orderDTO = orderService.findOne(payResponse.getOrderId()); 64 | //判断订单是否存在 65 | if(orderDTO==null){ 66 | log.error("[微信支付] 异步通知,订单不存在,orderId={}",payResponse.getOrderId()); 67 | throw new SellException(ResultEnum.ORDER_NOT_EXIST); 68 | } 69 | //判断金额是否一致 判断BigDecimal值是否一致,相减 - 给一个精度 70 | //(0.1和0.10) 71 | if(!MathUtil.equals(orderDTO.getOrderAmount().doubleValue(),payResponse.getOrderAmount())){ 72 | log.error("[微信支付] 异步通知,订单金额不一致,orderId={},微信通知金额={},系统金额={}", 73 | payResponse.getOrderId(),payResponse.getOrderAmount(),orderDTO.getOrderAmount()); 74 | throw new SellException(ResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR); 75 | } 76 | //修改订单的支付状态 77 | orderService.paid(orderDTO); 78 | 79 | return payResponse; 80 | } 81 | 82 | @Override 83 | public RefundResponse refund(OrderDTO orderDTO) { 84 | RefundRequest refundRequest = new RefundRequest(); 85 | refundRequest.setOrderId(orderDTO.getOrderId()); 86 | refundRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue()); 87 | refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5); 88 | log.info("[微信退款] request={}",JsonUtil.toJson(refundRequest)); 89 | RefundResponse refundResponse = bestPayService.refund(refundRequest); 90 | log.info("[微信退款] refundResponse={}",JsonUtil.toJson(refundResponse)); 91 | return refundResponse; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/BuyerProductController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.dataObject.ProductCategory; 4 | import cn.chenhaoxiang.dataObject.ProductInfo; 5 | import cn.chenhaoxiang.service.ProductCategoryService; 6 | import cn.chenhaoxiang.service.ProductInfoService; 7 | import cn.chenhaoxiang.utils.ResultVOUtil; 8 | import cn.chenhaoxiang.vo.ProductInfoVO; 9 | import cn.chenhaoxiang.vo.ProductVO; 10 | import cn.chenhaoxiang.vo.ResultVO; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.cache.annotation.Cacheable; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Arrays; 21 | import java.util.List; 22 | import java.util.stream.Collectors; 23 | 24 | /** 25 | * Created with IntelliJ IDEA. 26 | * User: 陈浩翔. 27 | * Date: 2018/1/9. 28 | * Time: 下午 7:32. 29 | * Explain:买家商品 30 | */ 31 | @RestController 32 | @RequestMapping(value = "/buyer/product") 33 | @Slf4j 34 | public class BuyerProductController { 35 | @Autowired 36 | private ProductInfoService productInfoService; 37 | @Autowired 38 | private ProductCategoryService productCategoryService; 39 | @GetMapping("list") 40 | @Cacheable(cacheNames = "product",key = "123",unless = "#result.getCode() != 0") 41 | //Redis缓存注解 Cacheable第一次访问会访问到方内的内容,方法会返回一个对象,返回对象的时候,会把这个对象存储。下一次访问的时候,不会进去这个方法,直接从redis缓存中拿 42 | //上面的key的值是可以动态写的@Cacheable(cacheNames = "product",key = "#sellerId") sellerId为方法中的参数名 43 | //condition判断是否成立的条件 例如key = "#sellerId",condition = "#sellerId.length() > 3" 只有条件成立才会对结果缓存,结果不成立是不缓存的 44 | //依据结果来判断是否缓存 unless = "#result.getCode() != 0",#result其实就是ResultVO,也就是返回的对象 45 | //unless(除什么之外,如果不 的意思) 如果=0就缓存,需要写成!=0。理解起来就是,除了不等于0的情况之外,才缓存,也就是等于0才缓存。 46 | //其实就是,你想要什么条件下缓存,你反过来写就行了 47 | //测试缓存的话,你可以在方法内打一个断点进行测试 48 | //注意,返回的缓存对象一定要实现序列化!!! 49 | public ResultVO list(){ 50 | //1.先查询所有的上架商品 51 | List productInfoList = productInfoService.findUpAll(); 52 | 53 | //2.查询类目(一次性查询) 查询需要的 54 | //一定不要把数据库的查询放到for循环中 55 | //传统方法 56 | // List categoryTypeList = new ArrayList<>(); 57 | // for(ProductInfo productInfo:productInfoList){ 58 | // categoryTypeList.add(productInfo.getCategoryType()); 59 | // } 60 | //精简方法 (java8 lambda) 推荐 61 | List categoryTypeList = productInfoList.stream().map(e->e.getCategoryType()) 62 | .collect(Collectors.toList()); 63 | List productCategoryList = productCategoryService.findByCategoryTypeIn(categoryTypeList); 64 | 65 | //3.数据拼装 - 拼装成前端需要的格式 66 | List productVOList = new ArrayList<>(); 67 | //先遍历类目 68 | for (ProductCategory productCategory:productCategoryList){ 69 | ProductVO productVO = new ProductVO(); 70 | productVO.setCategoryType(productCategory.getCategoryType()); 71 | productVO.setCategoryName(productCategory.getCategoryName()); 72 | //遍历商品详情 73 | List productInfoVOList = new ArrayList<>(); 74 | for (ProductInfo productInfo:productInfoList){ 75 | if(productInfo.getCategoryType().equals(productCategory.getCategoryType())){ 76 | ProductInfoVO productInfoVO = new ProductInfoVO(); 77 | BeanUtils.copyProperties(productInfo,productInfoVO);//Spring中的拷贝工具类,能把一样的属性的属性值拷贝过去 78 | productInfoVOList.add(productInfoVO); 79 | } 80 | } 81 | productVO.setProductInfoVOList(productInfoVOList); 82 | productVOList.add(productVO); 83 | } 84 | return ResultVOUtil.success(productVOList); 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /javadoc/sell/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 已过时的列表 (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 44 |
45 | 72 | 73 |
74 |

已过时的 API

75 |

目录

76 |
77 | 78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 | 95 |
96 | 123 | 124 |

Copyright © 2018 Pivotal Software, Inc.. All rights reserved.

125 | 126 | 127 | -------------------------------------------------------------------------------- /sell/src/test/java/cn/chenhaoxiang/service/impl/OrderServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.service.impl; 2 | 3 | import cn.chenhaoxiang.dataObject.OrderDetail; 4 | import cn.chenhaoxiang.dto.OrderDTO; 5 | import cn.chenhaoxiang.enums.OrderStausEnum; 6 | import cn.chenhaoxiang.enums.PayStatusEnum; 7 | import cn.chenhaoxiang.service.OrderService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.junit.Assert; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.boot.test.context.SpringBootTest; 14 | import org.springframework.data.domain.Page; 15 | import org.springframework.data.domain.PageRequest; 16 | import org.springframework.test.context.junit4.SpringRunner; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import static org.junit.Assert.*; 22 | 23 | /** 24 | * Created with IntelliJ IDEA. 25 | * User: 陈浩翔. 26 | * Date: 2018/1/14. 27 | * Time: 下午 11:22. 28 | * Explain: 29 | */ 30 | @RunWith(SpringRunner.class) 31 | @SpringBootTest 32 | @Slf4j 33 | public class OrderServiceImplTest { 34 | @Autowired 35 | private OrderServiceImpl orderService; 36 | private final String BUYER_OPENID ="110110"; 37 | private final String ORDER_ID = "1515944601506656672"; 38 | @Test 39 | public void create() throws Exception { 40 | OrderDTO orderDTO = new OrderDTO(); 41 | orderDTO.setBuyerName("陈浩翔"); 42 | orderDTO.setBuyerAddress("湖南长沙"); 43 | orderDTO.setBuyerPhone("123456789012"); 44 | orderDTO.setBuyerOpenid(BUYER_OPENID); 45 | 46 | //购物车 47 | List orderDetailList = new ArrayList<>(); 48 | OrderDetail o1 = new OrderDetail(); 49 | o1.setProductId("1234568"); 50 | o1.setProductQuantity(1); 51 | 52 | OrderDetail o2 = new OrderDetail(); 53 | o2.setProductId("123457"); 54 | o2.setProductQuantity(2); 55 | 56 | orderDetailList.add(o1); 57 | orderDetailList.add(o2); 58 | 59 | orderDTO.setOrderDetailList(orderDetailList); 60 | OrderDTO result = orderService.create(orderDTO); 61 | log.info("[创建订单] result={}",result); 62 | Assert.assertNotNull(result); 63 | 64 | } 65 | 66 | @Test 67 | public void findOne() throws Exception { 68 | OrderDTO result = orderService.findOne(ORDER_ID); 69 | log.info("[查询单个订单] result = {}",result); 70 | Assert.assertEquals(ORDER_ID,result.getOrderId()); 71 | } 72 | 73 | @Test 74 | public void findList() throws Exception { 75 | PageRequest pageRequest = new PageRequest(0,2); 76 | Page orderDTOPage = orderService.findList(BUYER_OPENID,pageRequest); 77 | log.info("list = {}",orderDTOPage.getContent()); 78 | Assert.assertNotEquals(0,orderDTOPage.getTotalElements()); 79 | } 80 | 81 | /** 82 | * 分页查询 83 | * @throws Exception 84 | */ 85 | @Test 86 | public void list() throws Exception { 87 | PageRequest pageRequest = new PageRequest(0,2); 88 | Page orderDTOPage = orderService.findList(pageRequest); 89 | log.info("list = {}",orderDTOPage.getContent()); 90 | // Assert.assertNotEquals(0,orderDTOPage.getTotalElements()); 91 | //写得统一一点的话,可以这样 92 | Assert.assertTrue("查询所有的订单列表应该大于0",orderDTOPage.getTotalElements()>0);//查询总数大于0 93 | } 94 | 95 | 96 | @Test 97 | public void cancel() throws Exception { 98 | OrderDTO orderDTO = orderService.findOne(ORDER_ID); 99 | OrderDTO result = orderService.cancel(orderDTO); 100 | Assert.assertEquals(OrderStausEnum.CANCEL.getCode(),result.getOrderStatus()); 101 | } 102 | 103 | @Test 104 | public void finish() throws Exception { 105 | OrderDTO orderDTO = orderService.findOne(ORDER_ID); 106 | OrderDTO result = orderService.finish(orderDTO); 107 | Assert.assertEquals(OrderStausEnum.FINISHED.getCode(),result.getOrderStatus()); 108 | } 109 | 110 | @Test 111 | public void paid() throws Exception { 112 | OrderDTO orderDTO = orderService.findOne(ORDER_ID); 113 | OrderDTO result = orderService.paid(orderDTO); 114 | Assert.assertEquals(PayStatusEnum.SUCCESS.getCode(),result.getPayStatus()); 115 | } 116 | 117 | } -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | ###商品列表 4 | 5 | ``` 6 | GET /sell/buyer/product/list 7 | ``` 8 | 9 | 参数 10 | 11 | ``` 12 | 无 13 | ``` 14 | 15 | 返回 16 | 17 | ``` 18 | { 19 | "code": 0, 20 | "msg": "成功", 21 | "data": [ 22 | { 23 | "name": "热榜", 24 | "type": 1, 25 | "foods": [ 26 | { 27 | "id": "123456", 28 | "name": "皮蛋粥", 29 | "price": 1.2, 30 | "description": "好吃的皮蛋粥", 31 | "icon": "http://xxx.com", 32 | } 33 | ] 34 | }, 35 | { 36 | "name": "好吃的", 37 | "type": 2, 38 | "foods": [ 39 | { 40 | "id": "123457", 41 | "name": "慕斯蛋糕", 42 | "price": 10.9, 43 | "description": "美味爽口", 44 | "icon": "http://xxx.com", 45 | } 46 | ] 47 | } 48 | ] 49 | } 50 | ``` 51 | 52 | 53 | ###创建订单 54 | 55 | ``` 56 | POST /sell/buyer/order/create 57 | ``` 58 | 59 | 参数 60 | 61 | ``` 62 | name: "张三" 63 | phone: "18868822111" 64 | address: "慕课网总部" 65 | openid: "ew3euwhd7sjw9diwkq" //用户的微信openid 66 | items: [{ 67 | productId: "1423113435324", 68 | productQuantity: 2 //购买数量 69 | }] 70 | 71 | ``` 72 | 73 | 返回 74 | 75 | ``` 76 | { 77 | "code": 0, 78 | "msg": "成功", 79 | "data": { 80 | "orderId": "147283992738221" 81 | } 82 | } 83 | ``` 84 | 85 | ###订单列表 86 | 87 | ``` 88 | GET /sell/buyer/order/list 89 | ``` 90 | 91 | 参数 92 | 93 | ``` 94 | openid: 18eu2jwk2kse3r42e2e 95 | page: 0 //从第0页开始 96 | size: 10 97 | ``` 98 | 99 | 返回 100 | 101 | ``` 102 | { 103 | "code": 0, 104 | "msg": "成功", 105 | "data": [ 106 | { 107 | "orderId": "161873371171128075", 108 | "buyerName": "张三", 109 | "buyerPhone": "18868877111", 110 | "buyerAddress": "慕课网总部", 111 | "buyerOpenid": "18eu2jwk2kse3r42e2e", 112 | "orderAmount": 0, 113 | "orderStatus": 0, 114 | "payStatus": 0, 115 | "createTime": 1490171219, 116 | "updateTime": 1490171219, 117 | "orderDetailList": null 118 | }, 119 | { 120 | "orderId": "161873371171128076", 121 | "buyerName": "张三", 122 | "buyerPhone": "18868877111", 123 | "buyerAddress": "慕课网总部", 124 | "buyerOpenid": "18eu2jwk2kse3r42e2e", 125 | "orderAmount": 0, 126 | "orderStatus": 0, 127 | "payStatus": 0, 128 | "createTime": 1490171219, 129 | "updateTime": 1490171219, 130 | "orderDetailList": null 131 | }] 132 | } 133 | ``` 134 | 135 | ###查询订单详情 136 | 137 | ``` 138 | GET /sell/buyer/order/detail 139 | ``` 140 | 141 | 参数 142 | 143 | ``` 144 | openid: 18eu2jwk2kse3r42e2e 145 | orderId: 161899085773669363 146 | ``` 147 | 148 | 返回 149 | 150 | ``` 151 | { 152 | "code": 0, 153 | "msg": "成功", 154 | "data": { 155 | "orderId": "161899085773669363", 156 | "buyerName": "李四", 157 | "buyerPhone": "18868877111", 158 | "buyerAddress": "慕课网总部", 159 | "buyerOpenid": "18eu2jwk2kse3r42e2e", 160 | "orderAmount": 18, 161 | "orderStatus": 0, 162 | "payStatus": 0, 163 | "createTime": 1490177352, 164 | "updateTime": 1490177352, 165 | "orderDetailList": [ 166 | { 167 | "detailId": "161899085974995851", 168 | "orderId": "161899085773669363", 169 | "productId": "157875196362360019", 170 | "productName": "招牌奶茶", 171 | "productPrice": 9, 172 | "productQuantity": 2, 173 | "productIcon": "http://xxx.com", 174 | "productImage": "http://xxx.com" 175 | } 176 | ] 177 | } 178 | } 179 | ``` 180 | 181 | ###取消订单 182 | 183 | ``` 184 | POST /sell/buyer/order/cancel 185 | ``` 186 | 187 | 参数 188 | 189 | ``` 190 | openid: 18eu2jwk2kse3r42e2e 191 | orderId: 161899085773669363 192 | ``` 193 | 194 | 返回 195 | 196 | ``` 197 | { 198 | "code": 0, 199 | "msg": "成功", 200 | "data": null 201 | } 202 | ``` 203 | 204 | ###获取openid 205 | 206 | ``` 207 | 重定向到 /sell/wechat/authorize 208 | ``` 209 | 210 | 参数 211 | 212 | ``` 213 | returnUrl: http://xxx.com/abc //【必填】 214 | ``` 215 | 216 | 返回 217 | 218 | ``` 219 | http://xxx.com/abc?openid=oZxSYw5ldcxv6H0EU67GgSXOUrVg 220 | ``` 221 | 222 | 223 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 cn.chenhaoxiang的使用 (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 44 |
45 | 72 | 73 |
74 |

程序包的使用
cn.chenhaoxiang

75 |
76 |
没有cn.chenhaoxiang的用法
77 | 78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 | 95 |
96 | 123 | 124 |

Copyright © 2018 Pivotal Software, Inc.. All rights reserved.

125 | 126 | 127 | -------------------------------------------------------------------------------- /sell/src/main/java/cn/chenhaoxiang/controller/SellerOrderController.java: -------------------------------------------------------------------------------- 1 | package cn.chenhaoxiang.controller; 2 | 3 | import cn.chenhaoxiang.dto.OrderDTO; 4 | import cn.chenhaoxiang.enums.ResultEnum; 5 | import cn.chenhaoxiang.exception.SellException; 6 | import cn.chenhaoxiang.service.OrderService; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.domain.Page; 10 | import org.springframework.data.domain.PageRequest; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.servlet.ModelAndView; 16 | 17 | import java.util.Map; 18 | 19 | /** 20 | * Created with IntelliJ IDEA. 21 | * User: 陈浩翔. 22 | * Date: 2018/1/21. 23 | * Time: 下午 2:28. 24 | * Explain: 25 | */ 26 | @Controller //展示页面 27 | @RequestMapping("/seller/order") 28 | @Slf4j 29 | public class SellerOrderController { 30 | 31 | @Autowired 32 | private OrderService orderService; 33 | /** 34 | * 订单列表 35 | * @param page 第几页,从第一页开始 36 | * @param size 一页有多少数据 37 | * @return 38 | */ 39 | @GetMapping("/list") 40 | public ModelAndView list(@RequestParam(value = "page",defaultValue = "1")Integer page, 41 | @RequestParam(value = "size",defaultValue = "10")Integer size, 42 | Map map){//map - 模板数据返回到页面 43 | PageRequest pageRequest = new PageRequest(page-1,size); 44 | Page orderDTOPage = orderService.findList(pageRequest); 45 | map.put("orderDTOPage",orderDTOPage); 46 | map.put("currentPage",page);//当前页 47 | map.put("size",size);//一页有多少数据 48 | return new ModelAndView("order/list",map); 49 | } 50 | 51 | /** 52 | * 取消订单 53 | * @param orderId 54 | * @param map 55 | * @return 56 | */ 57 | @GetMapping("/cancel") 58 | public ModelAndView cancel(@RequestParam("orderId")String orderId, 59 | Map map){ 60 | try { 61 | OrderDTO orderDTO = orderService.findOne(orderId); 62 | orderService.cancel(orderDTO); 63 | }catch (SellException e){ 64 | log.error("[卖家端取消订单] 发生异常,异常信息={}",e); 65 | map.put("msg", e.getMessage()); 66 | map.put("url","/seller/order/list"); 67 | return new ModelAndView("common/error",map); 68 | } 69 | map.put("msg", ResultEnum.ORDER_CANEL_SUCCESS.getMessage()); 70 | map.put("url","/seller/order/list"); 71 | return new ModelAndView("common/success",map); 72 | } 73 | 74 | /** 75 | * 订单详情 76 | * @param orderId 77 | * @param map 78 | * @return 79 | */ 80 | @GetMapping("/detail") 81 | public ModelAndView detail(@RequestParam("orderId")String orderId, 82 | Map map){ 83 | OrderDTO orderDTO; 84 | try { 85 | orderDTO = orderService.findOne(orderId); 86 | }catch (SellException e){ 87 | log.error("[卖家端查询订单详情] 发生异常,异常信息={}",e); 88 | map.put("msg", e.getMessage()); 89 | map.put("url","/seller/order/list"); 90 | return new ModelAndView("common/error",map); 91 | } 92 | map.put("orderDTO",orderDTO); 93 | return new ModelAndView("order/detail",map); 94 | } 95 | 96 | /** 97 | * 完结订单 98 | * @param orderId 99 | * @param map 100 | * @return 101 | */ 102 | @GetMapping("/finish") 103 | public ModelAndView finish(@RequestParam("orderId")String orderId, 104 | Map map){ 105 | OrderDTO orderDTO; 106 | try { 107 | orderDTO = orderService.findOne(orderId); 108 | orderService.finish(orderDTO); 109 | }catch (SellException e){ 110 | log.error("[卖家端完结订单] 发生异常,异常信息={}",e); 111 | map.put("msg", e.getMessage()); 112 | map.put("url","/seller/order/list"); 113 | return new ModelAndView("common/error",map); 114 | } 115 | map.put("msg", ResultEnum.ORDER_FINISH_SUCCESS.getMessage()); 116 | map.put("url","/seller/order/list"); 117 | return new ModelAndView("common/success",map); 118 | } 119 | 120 | 121 | } 122 | -------------------------------------------------------------------------------- /javadoc/sell/cn/chenhaoxiang/dao/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 程序包 cn.chenhaoxiang.dao的使用 (sell 0.0.1-SNAPSHOT API) 8 | 9 | 10 | 11 | 12 | 13 | 23 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 44 |
45 | 72 | 73 |
74 |

程序包的使用
cn.chenhaoxiang.dao

75 |
76 |
没有cn.chenhaoxiang.dao的用法
77 | 78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 | 95 |
96 | 123 | 124 |

Copyright © 2018 Pivotal Software, Inc.. All rights reserved.

125 | 126 | 127 | --------------------------------------------------------------------------------