Commit 44656c57 by XiaHou

Default Changelist

parents
### gradle ###
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.settings/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
*.lock
rebel.xml
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### maven ###
target/
*.war
*.ear
*.zip
*.tar
*.tar.gz
### logs ####
/logs/
*.log
### temp ignore ###
*.cache
*.diff
*.patch
*.tmp
*.java~
*.properties~
*.xml~
### system ignore ###
.DS_Store
Thumbs.db
Servers
.metadata
upload
gen_code
### node ###
node_modules
### 1.0.0
*2019-07-02*
This diff is collapsed. Click to expand it.
![输入图片说明](https://gitee.com/vip_title.png "在这里输入图片标题")
![输入图片说明](https://images.gitee.com/uploads/images/2019/0711/174845_6db7724e_5094767.png "屏幕截图.png")
一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布式锁,为生产环境多实例完全准备,数据库为b2b2c设计,拥有完整sku和下单流程的完全开源商城
## 前言
`Mall4j`项目致力于为中小企业打造一个完整、易于维护的开源的电商系统,采用现阶段流行技术实现。后台管理系统包含商品管理、订单管理、运费模板、规格管理、会员管理、运营管理、内容管理、统计报表、权限管理、设置等模块。
## 授权
Mall4j官网 https://www.mall4j.com
Mall4j 使用 AGPLv3 开源,请遵守 AGPLv3 的相关条款,或者联系作者获取商业授权(https://www.mall4j.com)
## 项目链接
java后台:https://gitee.com/gz-yami/mall4j
vue后台前端:https://gitee.com/gz-yami/mall4v
小程序:https://gitee.com/gz-yami/mall4m
## 演示地址
**由于我们并不希望小程序的数据被弄混乱,我们弄了两个数据库。因此,您修改了后台的商品信息,小程序并不能看到!**
后台:<http://mall4j-admin.gz-yami.com> 账号:admin/123456
小程序:1. 扫描二维码
![小程序](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/miniQrcode.jpg)
​ 2. 搜索小程序 **亚米商城**
## 技术选型
| 技术 | 版本 | 说明 |
| ---------------------- | ------ | --------------------------------------- |
| Spring Boot | 2.1.6 | MVC核心框架 |
| Spring Security oauth2 | 2.1.5 | 认证和授权框架 |
| MyBatis | 3.5.0 | ORM框架 |
| MyBatisPlus | 3.1.0 | 基于mybatis,使用lambda表达式的 |
| Swagger-UI | 2.9.2 | 文档生产工具 |
| Hibernator-Validator | 6.0.17 | 验证框架 |
| redisson | 3.10.6 | 对redis进行封装、集成分布式锁等 |
| hikari | 3.2.0 | 数据库连接池 |
| log4j2 | 2.11.2 | 更快的log日志工具 |
| fst | 2.57 | 更快的序列化和反序列化工具 |
| orika | 1.5.4 | 更快的bean复制工具 |
| lombok | 1.18.8 | 简化对象封装工具 |
| hutool | 4.5.0 | 更适合国人的java工具集 |
| swagger-bootstrap | 1.9.3 | 基于swagger,更便于国人使用的swagger ui |
## 部署教程
### 1.开发环境
以下版本是最低要求的!!! 提问问题前请注意开发环境!!
| 工具 | 版本 |
| ----- | ---- |
| jdk | 1.8+ |
| mysql | 5.7+ |
| redis | 3.2+ |
### 2.启动
- 推荐使用idea,安装lombok插件后,使用idea导入maven项目
- 将yami_shop.sql导入到mysql中,修改`application-dev.yml`更改 datasource.url、user、password
- 将mysql配置为不区分表名大小写(定时任务需要)
- 通过修改`ma.properties` 修改微信小程序信息
- 通过修改`mp.properties` 修改微信公众号信息
- 通过修改`pay.properties` 修改微信支付信息
- 通过修改`shop.properties` 修改七牛云、阿里大于等信息
- 修改`api.properties` 修改当前接口所在域名,用于支付回调
- 启动redis,端口6379
- 通过`WebApplication`启动项目后台接口,`ApiApplication` 启动项目前端接口
关于如何启动可以参考视频: https://www.bilibili.com/video/av60447070
关于授权流程可以参考视频:https://www.bilibili.com/video/av60453722
## 相关截图
### 1. 后台截图
![登陆](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/login.png)
![订单](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/order.png)
![商品列表](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/prodList.png)
![sku](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/sku.png)
![运费模板](https://gitee.com/gz-yami/mall4j/raw/master/screenshot/transport.png)
### 2. 小程序截图
![小程序截图](https://images.gitee.com/uploads/images/2019/0706/085234_4eb7509b_5094767.jpeg "小程序截图")
## 提交反馈
- QQ群:722835385
![输入图片说明](https://images.gitee.com/uploads/images/2019/0723/094927_e686539d_5094767.jpeg "微信图片_20190723091006.jpg")
## 后续会加入微服务框架、分布式版本
## 你的点赞鼓励,是我们前进的动力~
## 你的点赞鼓励,是我们前进的动力~
## 你的点赞鼓励,是我们前进的动力~
FROM mysql:5.7
MAINTAINER opgames(opgames.cn@gmail.com)
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./db/yami_shop.sql /docker-entrypoint-initdb.d
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
version: '3'
services:
mall4j-mysql:
build:
context: ./
dockerfile: ./db/Dockerfile
environment:
MYSQL_ROOT_PASSWORD: root
restart: always
container_name: mall4j-mysql
image: mall4j-mysql
ports:
- 3306:3306
volumes:
- ./mall4j-mysql:/var/lib/mysql
command: --lower_case_table_names=1
mall4j-redis:
image: redis:5.0.4
restart: always
container_name: mall4j-redis
ports:
- 6379:6379
mall4j-admin:
build:
context: ./
dockerfile: ./yami-shop-admin/Dockerfile
restart: always
container_name: mall4j-admin
image: mall4j-admin
ports:
- 8085:8085
depends_on:
- mall4j-redis
- mall4j-mysql
links:
- "mall4j-redis"
- "mall4j-mysql"
mall4j-api:
build:
context: ./
dockerfile: ./yami-shop-api/Dockerfile
restart: always
container_name: mall4j-api
image: mall4j-api
ports:
- 8086:8086
depends_on:
- mall4j-redis
- mall4j-mysql
links:
- "mall4j-redis"
- "mall4j-mysql"
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>yami-shop-admin</module>
<module>yami-shop-sys</module>
<module>yami-shop-common</module>
<module>yami-shop-api</module>
<module>yami-shop-bean</module>
<module>yami-shop-service</module>
<module>yami-shop-security</module>
<module>yami-shop-quartz</module>
<module>yami-shop-mp</module>
</modules>
<properties>
<yami.shop.version>0.0.1-SNAPSHOT</yami.shop.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<security.oauth.auto.version>2.1.5.RELEASE</security.oauth.auto.version>
<java.version>1.8</java.version>
<guava.version>20.0</guava.version>
<hutool.version>4.5.0</hutool.version>
<jsoup.version>1.11.3</jsoup.version>
<poi.version>3.17</poi.version>
<qiniu.version>7.2.18</qiniu.version>
<weixin.version>3.5.0</weixin.version>
<orika.version>1.5.4</orika.version>
<swagger2.version>2.9.2</swagger2.version>
<swagger-bootstrap.version>1.9.3</swagger-bootstrap.version>
<emoji.version>4.0.0</emoji.version>
<aliyun-core.version>4.3.9</aliyun-core.version>
<aliyun-dysmsapi.version>1.1.0</aliyun-dysmsapi.version>
<mybatis-plus.version>3.1.0</mybatis-plus.version>
<redisson.version>3.10.6</redisson.version>
<fst.version>2.57</fst.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>${security.oauth.auto.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>${weixin.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>${weixin.version}</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin.version}</version>
</dependency>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>${orika.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>${aliyun-dysmsapi.version}</version>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>${emoji.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- 使用redisson集成分布式锁等 -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<!-- 用于序列化和反序列化-->
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>${fst.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER opgames(opgames.cn@gmail.com)
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /opt/projects/mall4j
WORKDIR /opt/projects/mall4j
ADD ./yami-shop-admin/target/yami-shop-admin-0.0.1-SNAPSHOT.jar ./
EXPOSE 8085
CMD java -jar -Xms512m -Xmx512m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -Dspring.profiles.active=docker,quartz yami-shop-admin-0.0.1-SNAPSHOT.jar
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>yami-shop-admin</artifactId>
<parent>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-service</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-sys</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-security</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-quartz</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-mp</artifactId>
<version>${yami.shop.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
/**
* @author lgh
*/
@SpringBootApplication
@ComponentScan("com.yami.shop")
public class WebApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebApplication.class);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.config;
import cn.hutool.core.lang.Snowflake;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@AllArgsConstructor
public class AdminBeanConfig {
private final AdminConfig adminConfig;
@Bean
public Snowflake snowflake() {
return new Snowflake(adminConfig.getWorkerId(), adminConfig.getDatacenterId());
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* 商城配置文件
* @author lgh
*/
@Data
@Component
@PropertySource("classpath:admin.properties")
@ConfigurationProperties(prefix = "admin")
public class AdminConfig {
/**
* 数据中心ID
*/
private Integer datacenterId;
/**
* 终端ID
*/
private Integer workerId;
}
package com.yami.shop.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @author XiaoTiJun
* @date 2020-02-23 10:30
*/
@Component
@Configuration
public class GateWayCorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedMethod("*");
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger文档,只有在测试环境才会使用
* @author LGH
*/
//@Profile("dev")
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.yami"))
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("亚米管理系统接口文档")
.description("亚米商城接口文档Swagger版")
.termsOfServiceUrl("https://www.gz-yami.com/")
.contact(new Contact("广州亚米信息科技有限公司","https://www.gz-yami.com/", ""))
.version("1.0")
.build();
}
}
\ No newline at end of file
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.Area;
import com.yami.shop.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
* @author lgh on 2018/10/26.
*/
@RestController
@RequestMapping("/admin/area")
public class AreaController {
@Autowired
private AreaService areaService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:area:page')")
public ResponseEntity<IPage<Area>> page(Area area,PageParam<Area> page) {
IPage<Area> sysUserPage = areaService.page(page, new LambdaQueryWrapper<Area>());
return ResponseEntity.ok(sysUserPage);
}
/**
* 获取省市
*/
@GetMapping("/list")
@PreAuthorize("@pms.hasPermission('admin:area:list')")
public ResponseEntity<List<Area>> list(Area area) {
List<Area> areas = areaService.list(new LambdaQueryWrapper<Area>()
.like(area.getAreaName() != null, Area::getAreaName, area.getAreaName()));
return ResponseEntity.ok(areas);
}
/**
* 通过父级id获取区域列表
*/
@GetMapping("/listByPid")
public ResponseEntity<List<Area>> listByPid(Long pid) {
List<Area> list = areaService.listByPid(pid);
return ResponseEntity.ok(list);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('admin:area:info')")
public ResponseEntity<Area> info(@PathVariable("id") Long id) {
Area area = areaService.getById(id);
return ResponseEntity.ok(area);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:area:save')")
public ResponseEntity<Void> save(@Valid @RequestBody Area area) {
if (area.getParentId() != null) {
Area parentArea = areaService.getById(area.getParentId());
area.setLevel(parentArea.getLevel() + 1);
areaService.removeAreaCacheByParentId(area.getParentId());
}
areaService.save(area);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:area:update')")
public ResponseEntity<Void> update(@Valid @RequestBody Area area) {
areaService.updateById(area);
areaService.removeAreaCacheByParentId(area.getParentId());
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('admin:area:delete')")
public ResponseEntity<Void> delete(@PathVariable Long id) {
Area area = areaService.getById(id);
areaService.removeById(id);
areaService.removeAreaCacheByParentId(area.getParentId());
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Objects;
import javax.validation.Valid;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.enums.YamiHttpStatus;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.enums.ProdPropRule;
import com.yami.shop.bean.model.ProdProp;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.service.ProdPropService;
import com.baomidou.mybatisplus.core.metadata.IPage;
/**
* 参数管理
* @author lgh
*/
@RestController
@RequestMapping("/admin/attribute")
public class AttributeController {
@Autowired
private ProdPropService prodPropService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:attribute:page')")
public ResponseEntity<IPage<ProdProp>> page(ProdProp prodProp,PageParam<ProdProp> page){
prodProp.setRule(ProdPropRule.ATTRIBUTE.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
IPage<ProdProp> prodPropIPage = prodPropService.pagePropAndValue(prodProp,page);
return ResponseEntity.ok(prodPropIPage);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('admin:attribute:info')")
public ResponseEntity<ProdProp> info(@PathVariable("id") Long id){
ProdProp prodProp = prodPropService.getById(id);
return ResponseEntity.ok(prodProp);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:attribute:save')")
public ResponseEntity<Void> save(@Valid ProdProp prodProp){
prodProp.setRule(ProdPropRule.ATTRIBUTE.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
prodPropService.saveProdPropAndValues(prodProp);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:attribute:update')")
public ResponseEntity<Void> update(@Valid ProdProp prodProp){
ProdProp dbProdProp = prodPropService.getById(prodProp.getPropId());
if (!Objects.equals(dbProdProp.getShopId(), SecurityUtils.getSysUser().getShopId())) {
throw new YamiShopBindException("没有权限获取该商品规格信息");
}
prodProp.setRule(ProdPropRule.ATTRIBUTE.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
prodPropService.updateProdPropAndValues(prodProp);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('admin:attribute:delete')")
public ResponseEntity<Void> delete(@PathVariable Long id){
prodPropService.deleteProdPropAndValues(id,ProdPropRule.ATTRIBUTE.value(),SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.Brand;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.service.BrandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
* 品牌管理
*
* @author lgh
*/
@RestController
@RequestMapping("/admin/brand")
public class BrandController {
@Autowired
private BrandService brandService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:brand:page')")
public ResponseEntity<IPage<Brand>> page(Brand brand,PageParam<Brand> page) {
page.setAsc("first_char");
IPage<Brand> brands = brandService.page(page,
new LambdaQueryWrapper<Brand>()
.like(StrUtil.isNotBlank(brand.getBrandName()), Brand::getBrandName, brand.getBrandName()));
return ResponseEntity.ok(brands);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('admin:brand:info')")
public ResponseEntity<Brand> info(@PathVariable("id") Long id) {
Brand brand = brandService.getById(id);
return ResponseEntity.ok(brand);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:brand:save')")
public ResponseEntity<Void> save(@Valid Brand brand) {
Brand dbBrand = brandService.getByBrandName(brand.getBrandName());
if (dbBrand != null) {
throw new YamiShopBindException("该品牌名称已存在");
}
brandService.save(brand);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:brand:update')")
public ResponseEntity<Void> update(@Valid Brand brand) {
Brand dbBrand = brandService.getByBrandName(brand.getBrandName());
if (dbBrand != null && !Objects.equals(dbBrand.getBrandId(), brand.getBrandId())) {
throw new YamiShopBindException("该品牌名称已存在");
}
brandService.updateById(brand);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('admin:brand:delete')")
public ResponseEntity<Void> delete(@PathVariable Long id) {
brandService.deleteByBrand(id);
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.model.Category;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.service.BrandService;
import com.yami.shop.service.CategoryService;
import com.yami.shop.service.ProdPropService;
import cn.hutool.core.collection.CollectionUtil;
/**
* 分类管理
* @author lgh
*
*/
@RestController
@RequestMapping("/prod/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 获取菜单页面的表
* @return
*/
@GetMapping("/table")
@PreAuthorize("@pms.hasPermission('prod:category:page')")
public ResponseEntity<List<Category>> table(){
List<Category> categoryMenuList = categoryService.tableCategory(SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok(categoryMenuList);
}
/**
* 获取分类信息
*/
@GetMapping("/info/{categoryId}")
public ResponseEntity<Category> info(@PathVariable("categoryId") Long categoryId){
Category category = categoryService.getById(categoryId);
return ResponseEntity.ok(category);
}
/**
* 保存分类
*/
@SysLog("保存分类")
@PostMapping
@PreAuthorize("@pms.hasPermission('prod:category:save')")
public ResponseEntity<Void> save(@RequestBody Category category){
category.setShopId(SecurityUtils.getSysUser().getShopId());
category.setRecTime(new Date());
Category categoryName = categoryService.getOne(new LambdaQueryWrapper<Category>().eq(Category::getCategoryName,category.getCategoryName())
.eq(Category::getShopId,category.getShopId()));
if(categoryName != null){
throw new YamiShopBindException("类目名称已存在!");
}
categoryService.saveCategroy(category);
return ResponseEntity.ok().build();
}
/**
* 更新分类
*/
@SysLog("更新分类")
@PutMapping
@PreAuthorize("@pms.hasPermission('prod:category:update')")
public ResponseEntity<String> update(@RequestBody Category category){
category.setShopId(SecurityUtils.getSysUser().getShopId());
if (Objects.equals(category.getParentId(),category.getCategoryId())) {
return ResponseEntity.badRequest().body("分类的上级不能是自己本身");
}
Category categoryName = categoryService.getOne(new LambdaQueryWrapper<Category>().eq(Category::getCategoryName,category.getCategoryName())
.eq(Category::getShopId,category.getShopId()).ne(Category::getCategoryId,category.getCategoryId()));
if(categoryName != null){
throw new YamiShopBindException("类目名称已存在!");
}
categoryService.updateCategroy(category);
return ResponseEntity.ok().build();
}
/**
* 删除分类
*/
@SysLog("删除分类")
@DeleteMapping("/{categoryId}")
@PreAuthorize("@pms.hasPermission('prod:category:delete')")
public ResponseEntity<String> delete(@PathVariable("categoryId") Long categoryId){
if (categoryService.count(new LambdaQueryWrapper<Category>().eq(Category::getParentId,categoryId)) >0) {
return ResponseEntity.badRequest().body("请删除子分类,再删除该分类");
}
categoryService.deleteCategroy(categoryId);
return ResponseEntity.ok().build();
}
/**
* 所有的
*/
@GetMapping("/listCategory")
public ResponseEntity<List<Category>> listCategory(){
return ResponseEntity.ok(categoryService.list(new LambdaQueryWrapper<Category>()
.le(Category::getGrade, 2)
.eq(Category::getShopId, SecurityUtils.getSysUser().getShopId())
.orderByAsc(Category::getSeq)));
}
/**
* 所有的产品分类
*/
@GetMapping("/listProdCategory")
public ResponseEntity<List<Category>> listProdCategory(){
List<Category> categories = categoryService.treeSelect(SecurityUtils.getSysUser().getShopId(),2);
return ResponseEntity.ok(categories);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.model.Delivery;
import com.yami.shop.service.DeliveryService;
/**
*
* @author lgh on 2018/11/26.
*/
@RestController
@RequestMapping("/admin/delivery")
public class DeliveryController {
@Autowired
private DeliveryService deliveryService;
/**
* 分页获取
*/
@GetMapping("/list")
public ResponseEntity<List<Delivery>> page(){
List<Delivery> list = deliveryService.list();
return ResponseEntity.ok(list);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.yami.shop.bean.dto.TinymceEditorDto;
import com.yami.shop.common.bean.Qiniu;
import com.yami.shop.service.AttachFileService;
/**
* 文件上传 controller
* @author lgh
*
*/
@RestController
@RequestMapping("/admin/file")
public class FileController {
@Autowired
private AttachFileService attachFileService;
@Autowired
private Qiniu qiniu;
@PostMapping("/upload/element")
public ResponseEntity<String> uploadElementFile(@RequestParam("file") MultipartFile file) throws IOException{
if(file.isEmpty()){
return ResponseEntity.noContent().build();
}
String fileName = attachFileService.uploadFile(file.getBytes(),file.getOriginalFilename());
return ResponseEntity.ok(fileName);
}
@PostMapping("/upload/tinymceEditor")
public ResponseEntity<String> uploadTinymceEditorImages(@RequestParam("editorFile") MultipartFile editorFile) throws IOException{
String fileName = attachFileService.uploadFile(editorFile.getBytes(),editorFile.getOriginalFilename());
return ResponseEntity.ok(qiniu.getResourcesUrl() + fileName);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.service.HotSearchService;
import com.yami.shop.bean.model.HotSearch;
/**
*
* @author lgh on 2019/03/27.
*/
@RestController
@RequestMapping("/admin/hotSearch")
public class HotSearchController {
@Autowired
private HotSearchService hotSearchService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:hotSearch:page')")
public ResponseEntity<IPage<HotSearch>> page(HotSearch hotSearch,PageParam<HotSearch> page){
IPage<HotSearch> hotSearchs = hotSearchService.page(page,new LambdaQueryWrapper<HotSearch>()
.eq(HotSearch::getShopId, SecurityUtils.getSysUser().getShopId())
.like(StrUtil.isNotBlank(hotSearch.getContent()), HotSearch::getContent,hotSearch.getContent())
.like(StrUtil.isNotBlank(hotSearch.getTitle()), HotSearch::getTitle,hotSearch.getTitle())
.eq(hotSearch.getStatus()!=null, HotSearch::getStatus,hotSearch.getStatus())
);
return ResponseEntity.ok(hotSearchs);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('admin:hotSearch:info')")
public ResponseEntity<HotSearch> info(@PathVariable("id") Long id){
HotSearch hotSearch = hotSearchService.getById(id);
return ResponseEntity.ok(hotSearch);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:hotSearch:save')")
public ResponseEntity<Void> save(@RequestBody @Valid HotSearch hotSearch){
hotSearch.setRecDate(new Date());
hotSearch.setShopId(SecurityUtils.getSysUser().getShopId());
hotSearchService.save(hotSearch);
//清除缓存
hotSearchService.removeHotSearchDtoCacheByshopId(SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:hotSearch:update')")
public ResponseEntity<Void> update(@RequestBody @Valid HotSearch hotSearch){
hotSearchService.updateById(hotSearch);
//清除缓存
hotSearchService.removeHotSearchDtoCacheByshopId(SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('admin:hotSearch:delete')")
public ResponseEntity<Void> delete(@RequestBody List<Long> ids){
hotSearchService.removeByIds(ids);
//清除缓存
hotSearchService.removeHotSearchDtoCacheByshopId(SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.IndexImg;
import com.yami.shop.bean.model.Product;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.IndexImgService;
import com.yami.shop.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.Objects;
/**
* @author lgh on 2018/11/26.
*/
@RestController
@RequestMapping("/admin/indexImg")
public class IndexImgController {
@Autowired
private IndexImgService indexImgService;
@Autowired
private ProductService productService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:indexImg:page')")
public ResponseEntity<IPage<IndexImg>> page(IndexImg indexImg, PageParam<IndexImg> page) {
IPage<IndexImg> indexImgIPage = indexImgService.page(page,
new LambdaQueryWrapper<IndexImg>()
.eq(indexImg.getStatus() != null, IndexImg::getStatus, indexImg.getStatus())
.orderByDesc(IndexImg::getSeq));
return ResponseEntity.ok(indexImgIPage);
}
/**
* 获取信息
*/
@GetMapping("/info/{imgId}")
@PreAuthorize("@pms.hasPermission('admin:indexImg:info')")
public ResponseEntity<IndexImg> info(@PathVariable("imgId") Long imgId) {
Long shopId = SecurityUtils.getSysUser().getShopId();
IndexImg indexImg = indexImgService.getOne(new LambdaQueryWrapper<IndexImg>().eq(IndexImg::getShopId, shopId).eq(IndexImg::getImgId, imgId));
if (Objects.nonNull(indexImg.getRelation())) {
Product product = productService.getProductByProdId(indexImg.getRelation());
indexImg.setPic(product.getPic());
indexImg.setProdName(product.getProdName());
}
return ResponseEntity.ok(indexImg);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:indexImg:save')")
public ResponseEntity<Void> save(@RequestBody @Valid IndexImg indexImg) {
Long shopId = SecurityUtils.getSysUser().getShopId();
indexImg.setShopId(shopId);
indexImg.setUploadTime(new Date());
indexImgService.save(indexImg);
indexImgService.removeIndexImgCache();
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:indexImg:update')")
public ResponseEntity<Void> update(@RequestBody @Valid IndexImg indexImg) {
indexImgService.updateById(indexImg);
indexImgService.removeIndexImgCache();
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('admin:indexImg:delete')")
public ResponseEntity<Void> delete(@RequestBody Long[] ids) {
indexImgService.deleteIndexImgsByIds(ids);
indexImgService.removeIndexImgCache();
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Arrays;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.MessageStatus;
import com.yami.shop.bean.model.Message;
import com.yami.shop.service.MessageService;
import cn.hutool.core.util.StrUtil;
/**
* @author lgh on 2018/10/15.
*/
@RestController
@RequestMapping("/admin/message")
public class MessageController {
@Autowired
private MessageService messageService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:message:page')")
public ResponseEntity<IPage<Message>> page(Message message,PageParam<Message> page) {
IPage<Message> messages = messageService.page(page, new LambdaQueryWrapper<Message>()
.like(StrUtil.isNotBlank(message.getUserName()), Message::getUserName, message.getUserName())
.eq(message.getStatus() != null, Message::getStatus, message.getStatus()));
return ResponseEntity.ok(messages);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('admin:message:info')")
public ResponseEntity<Message> info(@PathVariable("id") Long id) {
Message message = messageService.getById(id);
return ResponseEntity.ok(message);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('admin:message:save')")
public ResponseEntity<Void> save(@RequestBody Message message) {
messageService.save(message);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:message:update')")
public ResponseEntity<Void> update(@RequestBody Message message) {
messageService.updateById(message);
return ResponseEntity.ok().build();
}
/**
* 公开留言
*/
@PutMapping("/release/{id}")
@PreAuthorize("@pms.hasPermission('admin:message:release')")
public ResponseEntity<Void> release(@PathVariable("id") Long id) {
Message message = new Message();
message.setId(id);
message.setStatus(MessageStatus.RELEASE.value());
messageService.updateById(message);
return ResponseEntity.ok().build();
}
/**
* 取消公开留言
*/
@PutMapping("/cancel/{id}")
@PreAuthorize("@pms.hasPermission('admin:message:cancel')")
public ResponseEntity<Void> cancel(@PathVariable("id") Long id) {
Message message = new Message();
message.setId(id);
message.setStatus(MessageStatus.CANCEL.value());
messageService.updateById(message);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{ids}")
@PreAuthorize("@pms.hasPermission('admin:message:delete')")
public ResponseEntity<Void> delete(@PathVariable Long[] ids) {
messageService.removeByIds(Arrays.asList(ids));
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.Notice;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.NoticeService;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
/**
* 公告管理
*
* @author hzm
* @date
*/
@RestController
@AllArgsConstructor
@RequestMapping("/shop/notice")
public class NoticeController {
private final NoticeService noticeService;
/**
* 分页查询
*
* @param page 分页对象
* @param notice 公告管理
* @return 分页数据
*/
@GetMapping("/page")
public ResponseEntity<IPage<Notice>> getNoticePage(PageParam<Notice> page, Notice notice) {
IPage<Notice> noticeIPage = noticeService.page(page, new LambdaQueryWrapper<Notice>()
.eq(notice.getStatus() != null, Notice::getStatus, notice.getStatus())
.like(notice.getTitle() != null, Notice::getTitle, notice.getTitle()).orderByDesc(Notice::getUpdateTime));
return ResponseEntity.ok(noticeIPage);
}
/**
* 通过id查询公告管理
*
* @param id id
* @return 单个数据
*/
@GetMapping("/info/{id}")
public ResponseEntity<Notice> getById(@PathVariable("id") Long id) {
return ResponseEntity.ok(noticeService.getById(id));
}
/**
* 新增公告管理
*
* @param notice 公告管理
* @return 是否新增成功
*/
@SysLog("新增公告管理")
@PostMapping
@PreAuthorize("@pms.hasPermission('shop:notice:save')")
public ResponseEntity<Boolean> save(@RequestBody @Valid Notice notice) {
notice.setShopId(SecurityUtils.getSysUser().getShopId());
if (notice.getStatus() == 1) {
notice.setPublishTime(new Date());
}
notice.setUpdateTime(new Date());
noticeService.removeNoticeList();
return ResponseEntity.ok(noticeService.save(notice));
}
/**
* 修改公告管理
*
* @param notice 公告管理
* @return 是否修改成功
*/
@SysLog("修改公告管理")
@PutMapping
@PreAuthorize("@pms.hasPermission('shop:notice:update')")
public ResponseEntity<Boolean> updateById(@RequestBody @Valid Notice notice) {
Notice oldNotice = noticeService.getById(notice.getId());
if (oldNotice.getStatus() == 0 && notice.getStatus() == 1) {
notice.setPublishTime(new Date());
}
notice.setUpdateTime(new Date());
noticeService.removeNoticeList();
noticeService.removeNoticeById(notice.getId());
return ResponseEntity.ok(noticeService.updateById(notice));
}
/**
* 通过id删除公告管理
*
* @param id id
* @return 是否删除成功
*/
@SysLog("删除公告管理")
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('shop:notice:delete')")
public ResponseEntity<Boolean> removeById(@PathVariable Long id) {
noticeService.removeNoticeList();
noticeService.removeNoticeById(id);
return ResponseEntity.ok(noticeService.removeById(id));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.validation.Valid;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.enums.YamiHttpStatus;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.PickAddr;
import com.yami.shop.service.PickAddrService;
import cn.hutool.core.util.StrUtil;
/**
*
* @author lgh on 2018/10/17.
*/
@RestController
@RequestMapping("/shop/pickAddr")
public class PickAddrController {
@Autowired
private PickAddrService pickAddrService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('shop:pickAddr:page')")
public ResponseEntity<IPage<PickAddr>> page(PickAddr pickAddr,PageParam<PickAddr> page){
IPage<PickAddr> pickAddrs = pickAddrService.page(page,new LambdaQueryWrapper<PickAddr>()
.like(StrUtil.isNotBlank(pickAddr.getAddrName()),PickAddr::getAddrName,pickAddr.getAddrName())
.orderByDesc(PickAddr::getAddrId));
return ResponseEntity.ok(pickAddrs);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('shop:pickAddr:info')")
public ResponseEntity<PickAddr> info(@PathVariable("id") Long id){
PickAddr pickAddr = pickAddrService.getById(id);
return ResponseEntity.ok(pickAddr);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('shop:pickAddr:save')")
public ResponseEntity<Void> save(@Valid @RequestBody PickAddr pickAddr){
pickAddr.setShopId(SecurityUtils.getSysUser().getShopId());
pickAddrService.save(pickAddr);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('shop:pickAddr:update')")
public ResponseEntity<Void> update(@Valid @RequestBody PickAddr pickAddr){
PickAddr dbPickAddr = pickAddrService.getById(pickAddr.getAddrId());
if (!Objects.equals(dbPickAddr.getShopId(),pickAddr.getShopId())) {
throw new YamiShopBindException(YamiHttpStatus.UNAUTHORIZED);
}
pickAddrService.updateById(pickAddr);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('shop:pickAddr:delete')")
public ResponseEntity<Void> delete(@RequestBody Long[] ids){
pickAddrService.removeByIds(Arrays.asList(ids));
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yami.shop.bean.model.ProdComm;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.util.Json;
import com.yami.shop.service.ProdCommService;
import lombok.AllArgsConstructor;
import javax.validation.Valid;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.ArrayList;
import java.util.Date;
/**
* 商品评论
*
* @author xwc
* @date 2019-04-19 10:43:57
*/
@RestController
@AllArgsConstructor
@RequestMapping("/prod/prodComm" )
public class ProdCommController {
private final ProdCommService prodCommService;
/**
* 分页查询
* @param page 分页对象
* @param prodComm 商品评论
* @return 分页数据
*/
@GetMapping("/page" )
@PreAuthorize("@pms.hasPermission('prod:prodComm:page')" )
public ResponseEntity<IPage<ProdComm>> getProdCommPage(PageParam page, ProdComm prodComm) {
return ResponseEntity.ok(prodCommService.getProdCommPage(page,prodComm));
}
/**
* 通过id查询商品评论
* @param prodCommId id
* @return 单个数据
*/
@GetMapping("/info/{prodCommId}" )
@PreAuthorize("@pms.hasPermission('prod:prodComm:info')" )
public ResponseEntity<ProdComm> getById(@PathVariable("prodCommId" ) Long prodCommId) {
return ResponseEntity.ok(prodCommService.getById(prodCommId));
}
/**
* 新增商品评论
* @param prodComm 商品评论
* @return 是否新增成功
*/
@SysLog("新增商品评论" )
@PostMapping
@PreAuthorize("@pms.hasPermission('prod:prodComm:save')" )
public ResponseEntity<Boolean> save(@RequestBody @Valid ProdComm prodComm) {
return ResponseEntity.ok(prodCommService.save(prodComm));
}
/**
* 修改商品评论
* @param prodComm 商品评论
* @return 是否修改成功
*/
@SysLog("修改商品评论" )
@PutMapping
@PreAuthorize("@pms.hasPermission('prod:prodComm:update')" )
public ResponseEntity<Boolean> updateById(@RequestBody @Valid ProdComm prodComm) {
prodComm.setReplyTime(new Date());
return ResponseEntity.ok(prodCommService.updateById(prodComm));
}
/**
* 通过id删除商品评论
* @param prodCommId id
* @return 是否删除成功
*/
@SysLog("删除商品评论" )
@DeleteMapping("/{prodCommId}" )
@PreAuthorize("@pms.hasPermission('prod:prodComm:delete')" )
public ResponseEntity<Boolean> removeById(@PathVariable Long prodCommId) {
return ResponseEntity.ok(prodCommService.removeById(prodCommId));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.ProdTag;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.ProdTagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
/**
* 商品分组
*
* @author hzm
* @date 2019-04-18 09:08:36
*/
@RestController
@RequestMapping("/prod/prodTag")
public class ProdTagController {
@Autowired
private ProdTagService prodTagService;
/**
* 分页查询
*
* @param page 分页对象
* @param prodTag 商品分组标签
* @return 分页数据
*/
@GetMapping("/page")
public ResponseEntity<IPage<ProdTag>> getProdTagPage(PageParam<ProdTag> page, ProdTag prodTag) {
IPage<ProdTag> tagIPage = prodTagService.page(
page, new LambdaQueryWrapper<ProdTag>()
.eq(prodTag.getStatus() != null, ProdTag::getStatus, prodTag.getStatus())
.like(prodTag.getTitle() != null, ProdTag::getTitle, prodTag.getTitle())
.orderByDesc(ProdTag::getSeq));
return ResponseEntity.ok(tagIPage);
}
/**
* 通过id查询商品分组标签
*
* @param id id
* @return 单个数据
*/
@GetMapping("/info/{id}")
public ResponseEntity<ProdTag> getById(@PathVariable("id") Long id) {
return ResponseEntity.ok(prodTagService.getById(id));
}
/**
* 新增商品分组标签
*
* @param prodTag 商品分组标签
* @return 是否新增成功
*/
@SysLog("新增商品分组标签")
@PostMapping
@PreAuthorize("@pms.hasPermission('prod:prodTag:save')")
public ResponseEntity<Boolean> save(@RequestBody @Valid ProdTag prodTag) {
// 查看是否相同的标签
List<ProdTag> list = prodTagService.list(new LambdaQueryWrapper<ProdTag>().like(ProdTag::getTitle, prodTag.getTitle()));
if (CollectionUtil.isNotEmpty(list)) {
throw new YamiShopBindException("标签名称已存在,不能添加相同的标签");
}
prodTag.setIsDefault(0);
prodTag.setProdCount(0L);
prodTag.setCreateTime(new Date());
prodTag.setUpdateTime(new Date());
prodTag.setShopId(SecurityUtils.getSysUser().getShopId());
prodTagService.removeProdTag();
return ResponseEntity.ok(prodTagService.save(prodTag));
}
/**
* 修改商品分组标签
*
* @param prodTag 商品分组标签
* @return 是否修改成功
*/
@SysLog("修改商品分组标签")
@PutMapping
@PreAuthorize("@pms.hasPermission('prod:prodTag:update')")
public ResponseEntity<Boolean> updateById(@RequestBody @Valid ProdTag prodTag) {
prodTag.setUpdateTime(new Date());
prodTagService.removeProdTag();
return ResponseEntity.ok(prodTagService.updateById(prodTag));
}
/**
* 通过id删除商品分组标签
*
* @param id id
* @return 是否删除成功
*/
@SysLog("删除商品分组标签")
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('prod:prodTag:delete')")
public ResponseEntity<Boolean> removeById(@PathVariable Long id) {
ProdTag prodTag = prodTagService.getById(id);
if (prodTag.getIsDefault() != 0) {
throw new YamiShopBindException("默认标签不能删除");
}
prodTagService.removeProdTag();
return ResponseEntity.ok(prodTagService.removeById(id));
}
@GetMapping("/listTagList")
public ResponseEntity<List<ProdTag>> listTagList() {
return ResponseEntity.ok(prodTagService.listProdTag());
}
}
\ No newline at end of file
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.ProdTagReference;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.service.ProdTagReferenceService;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* 分组标签引用
*
* @author hzm
* @date 2019-04-18 16:28:01
*/
@RestController
@AllArgsConstructor
@RequestMapping("/generator/prodTagReference" )
public class ProdTagReferenceController {
private final ProdTagReferenceService prodTagReferenceService;
/**
* 分页查询
* @param page 分页对象
* @param prodTagReference 分组标签引用
* @return 分页数据
*/
@GetMapping("/page" )
public ResponseEntity<IPage<ProdTagReference>> getProdTagReferencePage(PageParam page, ProdTagReference prodTagReference) {
return ResponseEntity.ok(prodTagReferenceService.page(page, new LambdaQueryWrapper<ProdTagReference>()));
}
/**
* 通过id查询分组标签引用
* @param referenceId id
* @return 单个数据
*/
@GetMapping("/info/{referenceId}" )
public ResponseEntity<ProdTagReference> getById(@PathVariable("referenceId" ) Long referenceId) {
return ResponseEntity.ok(prodTagReferenceService.getById(referenceId));
}
/**
* 新增分组标签引用
* @param prodTagReference 分组标签引用
* @return 是否新增成功
*/
@SysLog("新增分组标签引用" )
@PostMapping
@PreAuthorize("@pms.hasPermission('generator:prodTagReference:save')" )
public ResponseEntity<Boolean> save(@RequestBody @Valid ProdTagReference prodTagReference) {
return ResponseEntity.ok(prodTagReferenceService.save(prodTagReference));
}
/**
* 修改分组标签引用
* @param prodTagReference 分组标签引用
* @return 是否修改成功
*/
@SysLog("修改分组标签引用" )
@PutMapping
@PreAuthorize("@pms.hasPermission('generator:prodTagReference:update')" )
public ResponseEntity<Boolean> updateById(@RequestBody @Valid ProdTagReference prodTagReference) {
return ResponseEntity.ok(prodTagReferenceService.updateById(prodTagReference));
}
/**
* 通过id删除分组标签引用
* @param referenceId id
* @return 是否删除成功
*/
@SysLog("删除分组标签引用" )
@DeleteMapping("/{referenceId}" )
@PreAuthorize("@pms.hasPermission('generator:prodTagReference:delete')" )
public ResponseEntity<Boolean> removeById(@PathVariable Long referenceId) {
return ResponseEntity.ok(prodTagReferenceService.removeById(referenceId));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.param.ProductParam;
import com.yami.shop.common.enums.YamiHttpStatus;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Json;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.BasketService;
import com.yami.shop.service.ProdTagReferenceService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.SkuService;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* 商品列表、商品发布controller
*
* @author lgh
*/
@Controller
@RequestMapping("/prod/prod")
public class ProductController {
@Autowired
private ProductService productService;
@Autowired
private MapperFacade mapperFacade;
@Autowired
private SkuService skuService;
@Autowired
private ProdTagReferenceService prodTagReferenceService;
@Autowired
private BasketService basketService;
/**
* 分页获取商品信息
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('prod:prod:page')")
public ResponseEntity<IPage<Product>> page(ProductParam product, PageParam<Product> page) {
IPage<Product> products = productService.page(page,
new LambdaQueryWrapper<Product>()
.like(StrUtil.isNotBlank(product.getProdName()), Product::getProdName, product.getProdName())
.eq(Product::getShopId, SecurityUtils.getSysUser().getShopId())
.eq(product.getStatus() != null, Product::getStatus, product.getStatus())
.orderByDesc(Product::getPutawayTime));
return ResponseEntity.ok(products);
}
/**
* 获取信息
*/
@GetMapping("/info/{prodId}")
@PreAuthorize("@pms.hasPermission('prod:prod:info')")
public ResponseEntity<Product> info(@PathVariable("prodId") Long prodId) {
Product prod = productService.getProductByProdId(prodId);
if (!Objects.equals(prod.getShopId(), SecurityUtils.getSysUser().getShopId())) {
throw new YamiShopBindException("没有权限获取该商品规格信息");
}
List<Sku> skuList = skuService.listByProdId(prodId);
prod.setSkuList(skuList);
//获取分组标签
List<Long> listTagId = prodTagReferenceService.listTagIdByProdId(prodId);
prod.setTagList(listTagId);
return ResponseEntity.ok(prod);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('prod:prod:save')")
public ResponseEntity<String> save(@Valid @RequestBody ProductParam productParam) {
checkParam(productParam);
Product product = mapperFacade.map(productParam, Product.class);
product.setDeliveryMode(Json.toJsonString(productParam.getDeliveryModeVo()));
product.setShopId(SecurityUtils.getSysUser().getShopId());
product.setUpdateTime(new Date());
if (product.getStatus() == 1) {
product.setPutawayTime(new Date());
}
product.setCreateTime(new Date());
productService.saveProduct(product);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('prod:prod:update')")
public ResponseEntity<String> update(@Valid @RequestBody ProductParam productParam) {
checkParam(productParam);
Product dbProduct = productService.getProductByProdId(productParam.getProdId());
if (!Objects.equals(dbProduct.getShopId(), SecurityUtils.getSysUser().getShopId())) {
return ResponseEntity.badRequest().body("无法修改非本店铺商品信息");
}
List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId());
Product product = mapperFacade.map(productParam, Product.class);
product.setDeliveryMode(Json.toJsonString(productParam.getDeliveryModeVo()));
product.setUpdateTime(new Date());
if (dbProduct.getStatus() == 0 || productParam.getStatus() == 1) {
product.setPutawayTime(new Date());
}
dbProduct.setSkuList(dbSkus);
productService.updateProduct(product, dbProduct);
List<String> userIds = basketService.listUserIdByProdId(product.getProdId());
for (String userId : userIds) {
basketService.removeShopCartItemsCacheByUserId(userId);
}
for (Sku sku : dbSkus) {
skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
}
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{prodId}")
@PreAuthorize("@pms.hasPermission('prod:prod:delete')")
public ResponseEntity<Void> delete(@PathVariable("prodId") Long prodId) {
Product dbProduct = productService.getProductByProdId(prodId);
if (!Objects.equals(dbProduct.getShopId(), SecurityUtils.getSysUser().getShopId())) {
throw new YamiShopBindException("无法获取非本店铺商品信息");
}
List<Sku> dbSkus = skuService.listByProdId(dbProduct.getProdId());
// 删除商品
productService.removeProductByProdId(prodId);
for (Sku sku : dbSkus) {
skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
}
List<String> userIds = basketService.listUserIdByProdId(prodId);
for (String userId : userIds) {
basketService.removeShopCartItemsCacheByUserId(userId);
}
return ResponseEntity.ok().build();
}
/**
* 更新商品状态
*/
@PutMapping("/prodStatus")
@PreAuthorize("@pms.hasPermission('prod:prod:status')")
public ResponseEntity<Void> shopStatus(@RequestParam Long prodId, @RequestParam Integer prodStatus) {
Product product = new Product();
product.setProdId(prodId);
product.setStatus(prodStatus);
if (prodStatus == 1) {
product.setPutawayTime(new Date());
}
productService.updateById(product);
productService.removeProductCacheByProdId(prodId);
List<String> userIds = basketService.listUserIdByProdId(prodId);
for (String userId : userIds) {
basketService.removeShopCartItemsCacheByUserId(userId);
}
return ResponseEntity.ok().build();
}
private void checkParam(ProductParam productParam) {
if (CollectionUtil.isEmpty(productParam.getTagList())) {
throw new YamiShopBindException("请选择产品分组");
}
Product.DeliveryModeVO deliveryMode = productParam.getDeliveryModeVo();
boolean hasDeliverMode = deliveryMode != null
&& (deliveryMode.getHasShopDelivery() || deliveryMode.getHasUserPickUp());
if (!hasDeliverMode) {
throw new YamiShopBindException("请选择配送方式");
}
List<Sku> skuList = productParam.getSkuList();
boolean isAllUnUse = true;
for (Sku sku : skuList) {
if (sku.getStatus() == 1) {
isAllUnUse = false;
}
}
if (isAllUnUse) {
throw new YamiShopBindException("至少要启用一种商品规格");
}
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.param.ShopDetailParam;
import com.yami.shop.service.ShopDetailService;
import cn.hutool.core.util.StrUtil;
import ma.glasnost.orika.MapperFacade;
/**
*
* @author lgh on 2018/08/29.
*/
@Controller
@RequestMapping("/shop/shopDetail")
public class ShopDetailController {
@Autowired
private ShopDetailService shopDetailService;
@Autowired
private MapperFacade mapperFacade;
/**
* 修改分销开关
*/
@PutMapping("/isDistribution")
//@PreAuthorize("@pms.hasPermission('shop:shopDetail:update')")
public ResponseEntity<Void> updateIsDistribution(@RequestParam Integer isDistribution){
ShopDetail shopDetail=new ShopDetail();
shopDetail.setShopId(SecurityUtils.getSysUser().getShopId());
shopDetail.setIsDistribution(isDistribution);
shopDetailService.updateById(shopDetail);
// 更新完成后删除缓存
shopDetailService.removeShopDetailCacheByShopId(shopDetail.getShopId());
return ResponseEntity.ok().build();
}
/**
* 获取信息
*/
@GetMapping("/info")
@PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
public ResponseEntity<ShopDetail> info(){
ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok(shopDetail);
}
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('shop:shopDetail:page')")
public ResponseEntity<IPage<ShopDetail>> page(ShopDetail shopDetail,PageParam<ShopDetail> page){
IPage<ShopDetail> shopDetails = shopDetailService.page(page,
new LambdaQueryWrapper<ShopDetail>()
.like(StrUtil.isNotBlank(shopDetail.getShopName()),ShopDetail::getShopName,shopDetail.getShopName())
.orderByDesc(ShopDetail::getShopId));
return ResponseEntity.ok(shopDetails);
}
/**
* 获取信息
*/
@GetMapping("/info/{shopId}")
@PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
public ResponseEntity<ShopDetail> info(@PathVariable("shopId") Long shopId){
ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
// 店铺图片
return ResponseEntity.ok(shopDetail);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('shop:shopDetail:save')")
public ResponseEntity<Void> save(@Valid ShopDetailParam shopDetailParam){
ShopDetail shopDetail = mapperFacade.map(shopDetailParam, ShopDetail.class);
shopDetail.setCreateTime(new Date());
shopDetail.setShopStatus(1);
shopDetailService.save(shopDetail);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('shop:shopDetail:update')")
public ResponseEntity<Void> update(@Valid ShopDetailParam shopDetailParam){
ShopDetail daShopDetail = shopDetailService.getShopDetailByShopId(shopDetailParam.getShopId());
ShopDetail shopDetail = mapperFacade.map(shopDetailParam, ShopDetail.class);
shopDetail.setUpdateTime(new Date());
shopDetailService.updateShopDetail(shopDetail,daShopDetail);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('shop:shopDetail:delete')")
public ResponseEntity<Void> delete(@PathVariable Long id){
shopDetailService.deleteShopDetailByShopId(id);
return ResponseEntity.ok().build();
}
/**
* 更新店铺状态
*/
@PutMapping("/shopStatus")
@PreAuthorize("@pms.hasPermission('shop:shopDetail:shopStatus')")
public ResponseEntity<Void> shopStatus(@RequestParam Long shopId,@RequestParam Integer shopStatus){
ShopDetail shopDetail = new ShopDetail();
shopDetail.setShopId(shopId);
shopDetail.setShopStatus(shopStatus);
shopDetailService.updateById(shopDetail);
// 更新完成后删除缓存
shopDetailService.removeShopDetailCacheByShopId(shopDetail.getShopId());
return ResponseEntity.ok().build();
}
/**
* 获取所有的店铺名称
*/
@GetMapping("/listShopName")
public ResponseEntity<List<ShopDetail>> listShopName(){
List<ShopDetail> list = shopDetailService.list().stream().map((dbShopDetail) ->{
ShopDetail shopDetail = new ShopDetail();
shopDetail.setShopId(dbShopDetail.getShopId());
shopDetail.setShopName(dbShopDetail.getShopName());
return shopDetail;
}).collect(Collectors.toList());
return ResponseEntity.ok(list);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.List;
import java.util.Objects;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.enums.YamiHttpStatus;
import com.yami.shop.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.ProdPropRule;
import com.yami.shop.bean.model.ProdProp;
import com.yami.shop.bean.model.ProdPropValue;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.service.ProdPropService;
import com.yami.shop.service.ProdPropValueService;
import javax.validation.Valid;
/**
* 规格管理
*
* @author lgh
*/
@RestController
@RequestMapping("/prod/spec")
public class SpecController {
@Autowired
private ProdPropService prodPropService;
@Autowired
private ProdPropValueService prodPropValueService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('prod:spec:page')")
public ResponseEntity<IPage<ProdProp>> page(ProdProp prodProp,PageParam<ProdProp> page) {
prodProp.setRule(ProdPropRule.SPEC.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
IPage<ProdProp> list = prodPropService.pagePropAndValue(prodProp, page);
return ResponseEntity.ok(list);
}
/**
* 获取所有的规格
*/
@GetMapping("/list")
public ResponseEntity<List<ProdProp>> list() {
List<ProdProp> list = prodPropService.list(new LambdaQueryWrapper<ProdProp>().eq(ProdProp::getRule, ProdPropRule.SPEC.value()).eq(ProdProp::getShopId, SecurityUtils.getSysUser().getShopId()));
return ResponseEntity.ok(list);
}
/**
* 根据规格id获取规格值
*/
@GetMapping("/listSpecValue/{specId}")
public ResponseEntity<List<ProdPropValue>> listSpecValue(@PathVariable("specId") Long specId) {
List<ProdPropValue> list = prodPropValueService.list(new LambdaQueryWrapper<ProdPropValue>().eq(ProdPropValue::getPropId, specId));
return ResponseEntity.ok(list);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('prod:spec:save')")
public ResponseEntity<Void> save(@Valid @RequestBody ProdProp prodProp) {
prodProp.setRule(ProdPropRule.SPEC.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
prodPropService.saveProdPropAndValues(prodProp);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('prod:spec:update')")
public ResponseEntity<Void> update(@Valid @RequestBody ProdProp prodProp) {
ProdProp dbProdProp = prodPropService.getById(prodProp.getPropId());
if (!Objects.equals(dbProdProp.getShopId(), SecurityUtils.getSysUser().getShopId())) {
throw new YamiShopBindException("没有权限获取该商品规格信息");
}
prodProp.setRule(ProdPropRule.SPEC.value());
prodProp.setShopId(SecurityUtils.getSysUser().getShopId());
prodPropService.updateProdPropAndValues(prodProp);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping("/{id}")
@PreAuthorize("@pms.hasPermission('prod:spec:delete')")
public ResponseEntity<Void> delete(@PathVariable Long id) {
prodPropService.deleteProdPropAndValues(id, ProdPropRule.SPEC.value(), SecurityUtils.getSysUser().getShopId());
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.security.util.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.Transport;
import com.yami.shop.service.TransportService;
/**
* @author lgh on 2018/11/16.
*/
@RestController
@RequestMapping("/shop/transport")
public class TransportController {
@Autowired
private TransportService transportService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('shop:transport:page')")
public ResponseEntity<IPage<Transport>> page(Transport transport,PageParam<Transport> page) {
Long shopId = SecurityUtils.getSysUser().getShopId();
IPage<Transport> transports = transportService.page(page,
new LambdaQueryWrapper<Transport>()
.eq(Transport::getShopId, shopId)
.like(StringUtils.isNotBlank(transport.getTransName()), Transport::getTransName, transport.getTransName()));
return ResponseEntity.ok(transports);
}
/**
* 获取信息
*/
@GetMapping("/info/{id}")
@PreAuthorize("@pms.hasPermission('shop:transport:info')")
public ResponseEntity<Transport> info(@PathVariable("id") Long id) {
Transport transport = transportService.getTransportAndAllItems(id);
return ResponseEntity.ok(transport);
}
/**
* 保存
*/
@PostMapping
@PreAuthorize("@pms.hasPermission('shop:transport:save')")
public ResponseEntity<Void> save(@RequestBody Transport transport) {
Long shopId = SecurityUtils.getSysUser().getShopId();
transport.setShopId(shopId);
Date createTime = new Date();
transport.setCreateTime(createTime);
transportService.insertTransportAndTransfee(transport);
return ResponseEntity.ok().build();
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('shop:transport:update')")
public ResponseEntity<Void> update(@RequestBody Transport transport) {
transportService.updateTransportAndTransfee(transport);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('shop:transport:delete')")
public ResponseEntity<Void> delete(@RequestBody Long[] ids) {
transportService.deleteTransportAndTransfeeAndTranscity(ids);
// 删除运费模板的缓存
for (Long id : ids) {
transportService.removeTransportAndAllItemsCache(id);
}
return ResponseEntity.ok().build();
}
/**
* 获取运费模板列表
*/
@GetMapping("/list")
public ResponseEntity<List<Transport>> list() {
Long shopId = SecurityUtils.getSysUser().getShopId();
List<Transport> list = transportService.list(new LambdaQueryWrapper<Transport>().eq(Transport::getShopId, shopId));
return ResponseEntity.ok(list);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.service.UserAddrService;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* 用户地址管理
*
* @author hzm
* @date 2019-04-15 10:49:40
*/
@RestController
@AllArgsConstructor
@RequestMapping("/user/addr")
public class UserAddrController {
private final UserAddrService userAddrService;
/**
* 分页查询
*
* @param page 分页对象
* @param userAddr 用户地址管理
* @return 分页数据
*/
@GetMapping("/page")
public ResponseEntity<IPage<UserAddr>> getUserAddrPage(PageParam page, UserAddr userAddr) {
return ResponseEntity.ok(userAddrService.page(page, new LambdaQueryWrapper<UserAddr>()));
}
/**
* 通过id查询用户地址管理
*
* @param addrId id
* @return 单个数据
*/
@GetMapping("/info/{addrId}")
public ResponseEntity<UserAddr> getById(@PathVariable("addrId") Long addrId) {
return ResponseEntity.ok(userAddrService.getById(addrId));
}
/**
* 新增用户地址管理
*
* @param userAddr 用户地址管理
* @return 是否新增成功
*/
@SysLog("新增用户地址管理")
@PostMapping
@PreAuthorize("@pms.hasPermission('user:addr:save')")
public ResponseEntity<Boolean> save(@RequestBody @Valid UserAddr userAddr) {
return ResponseEntity.ok(userAddrService.save(userAddr));
}
/**
* 修改用户地址管理
*
* @param userAddr 用户地址管理
* @return 是否修改成功
*/
@SysLog("修改用户地址管理")
@PutMapping
@PreAuthorize("@pms.hasPermission('user:addr:update')")
public ResponseEntity<Boolean> updateById(@RequestBody @Valid UserAddr userAddr) {
return ResponseEntity.ok(userAddrService.updateById(userAddr));
}
/**
* 通过id删除用户地址管理
*
* @param addrId id
* @return 是否删除成功
*/
@SysLog("删除用户地址管理")
@DeleteMapping("/{addrId}")
@PreAuthorize("@pms.hasPermission('user:addr:delete')")
public ResponseEntity<Boolean> removeById(@PathVariable Long addrId) {
return ResponseEntity.ok(userAddrService.removeById(addrId));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.controller;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.User;
import com.yami.shop.service.UserService;
import cn.hutool.extra.emoji.EmojiUtil;
/**
* @author lgh on 2018/10/16.
*/
@RestController
@RequestMapping("/admin/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 分页获取
*/
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('admin:user:page')")
public ResponseEntity<IPage<User>> page(User user,PageParam<User> page) {
IPage<User> userIPage = userService.page(page, new LambdaQueryWrapper<User>()
.like(StrUtil.isNotBlank(user.getNickName()), User::getNickName, user.getNickName())
.eq(user.getStatus() != null, User::getStatus, user.getStatus())
);
for (User userResult : userIPage.getRecords()) {
userResult.setNickName(EmojiUtil.toUnicode(userResult.getNickName() == null ? "" : userResult.getNickName()));
}
return ResponseEntity.ok(userIPage);
}
/**
* 获取信息
*/
@GetMapping("/info/{userId}")
@PreAuthorize("@pms.hasPermission('admin:user:info')")
public ResponseEntity<User> info(@PathVariable("userId") String userId) {
User user = userService.getById(userId);
user.setNickName(EmojiUtil.toUnicode(user.getNickName() == null ? "" : user.getNickName()));
return ResponseEntity.ok(user);
}
/**
* 修改
*/
@PutMapping
@PreAuthorize("@pms.hasPermission('admin:user:update')")
public ResponseEntity<Void> update(@RequestBody User user) {
user.setModifyTime(new Date());
user.setNickName(EmojiUtil.toAlias(user.getNickName() == null ? "" : user.getNickName()));
userService.updateById(user);
return ResponseEntity.ok().build();
}
/**
* 删除
*/
@DeleteMapping
@PreAuthorize("@pms.hasPermission('admin:user:delete')")
public ResponseEntity<Void> delete(@RequestBody String[] userIds) {
userService.removeByIds(Arrays.asList(userIds));
return ResponseEntity.ok().build();
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.security;
import cn.hutool.core.util.StrUtil;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.security.constants.SecurityConstants;
import com.yami.shop.security.enums.App;
import com.yami.shop.security.exception.BadCredentialsExceptionBase;
import com.yami.shop.security.exception.ImageCodeNotMatchExceptionBase;
import com.yami.shop.security.exception.UsernameNotFoundExceptionBase;
import com.yami.shop.security.exception.BaseYamiAuth2Exception;
import com.yami.shop.security.provider.AbstractUserDetailsAuthenticationProvider;
import com.yami.shop.security.service.YamiUserDetailsService;
import lombok.AllArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
/**
* 后台管理员账号密码登陆
* @author LGH
*/
@Component
@AllArgsConstructor
public class AdminAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private final YamiUserDetailsService yamiUserDetailsService;
private final PasswordEncoder passwordEncoder;
@Override
protected UserDetails retrieveUser(String username, Authentication authentication) throws BaseYamiAuth2Exception {
AdminAuthenticationToken adminAuthenticationToken = (AdminAuthenticationToken) authentication;
String kaptchaKey = SecurityConstants.SPRING_SECURITY_RESTFUL_IMAGE_CODE + adminAuthenticationToken.getSessionUUID();
String kaptcha = RedisUtil.get(kaptchaKey);
RedisUtil.del(kaptchaKey);
if(StrUtil.isBlank(adminAuthenticationToken.getImageCode()) || !adminAuthenticationToken.getImageCode().equalsIgnoreCase(kaptcha)){
throw new ImageCodeNotMatchExceptionBase("验证码有误");
}
UserDetails user;
try {
user = yamiUserDetailsService.loadUserByUsername(username);
} catch (UsernameNotFoundExceptionBase var6) {
throw new UsernameNotFoundExceptionBase("账号或密码不正确");
}
String encodedPassword = user.getPassword();
String rawPassword = authentication.getCredentials().toString();
String encode = passwordEncoder.encode(rawPassword);
// 密码不正确
if (!passwordEncoder.matches(rawPassword,encodedPassword)){
throw new BadCredentialsExceptionBase("账号或密码不正确");
}
if (!user.isEnabled()) {
throw new UsernameNotFoundExceptionBase("账号已被锁定,请联系管理员");
}
return user;
}
@Override
protected Authentication createSuccessAuthentication(Authentication authentication, UserDetails user) {
AdminAuthenticationToken result = new AdminAuthenticationToken(user, authentication.getCredentials());
result.setDetails(authentication.getDetails());
return result;
}
@Override
public boolean supports(Class<?> authentication) {
return AdminAuthenticationToken.class.isAssignableFrom(authentication);
}
@Override
protected App getAppInfo() {
return null;
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.security;
import com.yami.shop.security.token.MyAuthenticationToken;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.security.core.userdetails.UserDetails;
/**
* 系统用户账号密码登陆
*/
@Getter
@Setter
@NoArgsConstructor
public class AdminAuthenticationToken extends MyAuthenticationToken {
private String sessionUUID;
private String imageCode;
public AdminAuthenticationToken(UserDetails principal, Object credentials) {
super(principal, credentials, principal.getAuthorities());
}
}
package com.yami.shop.admin.security;
import com.yami.shop.common.util.Json;
import com.yami.shop.security.provider.AuthenticationTokenParser;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.stereotype.Component;
/**
* AdminAuthenticationTokenParser
*
* @author hanfeng
* @date 2019-08-21
*/
@Component
public class AdminAuthenticationTokenParser implements AuthenticationTokenParser {
@Override
public AbstractAuthenticationToken parse(String authenticationTokenStr) {
AdminAuthenticationToken authRequest = Json.parseObject(authenticationTokenStr, AdminAuthenticationToken.class);
return authRequest;
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.security;
import com.yami.shop.security.constants.SecurityConstants;
import com.yami.shop.security.service.YamiClientDetailsService;
import com.yami.shop.security.service.YamiSysUser;
import com.yami.shop.security.service.YamiUser;
import com.yami.shop.security.service.YamiUserDetailsService;
import com.yami.shop.security.util.YamiTokenServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import javax.sql.DataSource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Configuration
//@Order(2)
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private YamiUserDetailsService yamiUserDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private DataSource dataSource;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
private AuthorizationServerEndpointsConfigurer endpoints;
@Bean
public TokenStore tokenStore() {
RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
tokenStore.setPrefix(SecurityConstants.YAMI_PREFIX + SecurityConstants.OAUTH_PREFIX);
return tokenStore;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// 使用JdbcClientDetailsService客户端详情服务
YamiClientDetailsService clientDetailsService = new YamiClientDetailsService(dataSource);
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer())
.reuseRefreshTokens(false)
.userDetailsService(yamiUserDetailsService);
this.endpoints = endpoints;
endpoints.tokenServices(yamiTokenServices());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer
// 开启/oauth/token_key验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()");
}
/**
* token增强。
*
* @return TokenEnhancer
*/
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
final Map<String, Object> additionalInfo = new HashMap<>(8);
YamiSysUser yamiSysUser = (YamiSysUser) authentication.getUserAuthentication().getPrincipal();
additionalInfo.put("shopId", yamiSysUser.getShopId());
additionalInfo.put("userId", yamiSysUser.getUserId());
additionalInfo.put("authorities", yamiSysUser.getAuthorities());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
}
@Primary
@Bean
@Lazy
public AuthorizationServerTokenServices yamiTokenServices() {
YamiTokenServices tokenServices = new YamiTokenServices();
tokenServices.setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);//支持刷新token
tokenServices.setReuseRefreshToken(true);
// tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());
addUserDetailsService(tokenServices);
return tokenServices;
}
private void addUserDetailsService(YamiTokenServices tokenServices) {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(
yamiUserDetailsService));
tokenServices.setAuthenticationManager(new ProviderManager(Collections.singletonList(provider)));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.security;
import com.yami.shop.security.filter.LoginAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private LoginAuthenticationFilter loginAuthenticationFilter;
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
// Since we want the protected resources to be accessible in the UI as well we need
// session creation to be allowed (it's disabled by default in 2.0.6)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.requestMatchers().anyRequest()
.and()
.anonymous()
.and()
.authorizeRequests()
.antMatchers(
"/webjars/**",
"/swagger/**",
"/v2/api-docs",
"/doc.html",
"/swagger-ui.html",
"/swagger-resources/**",
"/captcha.jpg").permitAll()
.and()
.authorizeRequests()
.antMatchers("/**").authenticated();//配置所有访问控制,必须认证过后才可以访问
// @formatter:on
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.security;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.util.CacheManagerUtil;
import com.yami.shop.sys.constant.Constant;
import com.yami.shop.security.enums.App;
import com.yami.shop.security.exception.UsernameNotFoundExceptionBase;
import com.yami.shop.security.model.AppConnect;
import com.yami.shop.security.service.YamiSysUser;
import com.yami.shop.security.service.YamiUser;
import com.yami.shop.security.service.YamiUserDetailsService;
import com.yami.shop.sys.dao.SysMenuMapper;
import com.yami.shop.sys.dao.SysUserMapper;
import com.yami.shop.sys.model.SysMenu;
import com.yami.shop.sys.model.SysUser;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 用户详细信息
*
* @author
*/
@Slf4j
@Service
@AllArgsConstructor
public class YamiSysUserDetailsServiceImpl implements YamiUserDetailsService {
private final SysMenuMapper sysMenuMapper;
private final SysUserMapper sysUserMapper;
private final CacheManagerUtil cacheManagerUtil;
/**
* 用户密码登录
*
* @param username 用户名
* @return
* @throws UsernameNotFoundExceptionBase
*/
@Override
@SneakyThrows
public YamiSysUser loadUserByUsername(String username) {
return getUserDetails(username);
}
/**
* 构建userdetails
*
* @param username 用户名称
* @return
*/
private YamiSysUser getUserDetails(String username) {
SysUser sysUser = sysUserMapper.selectByUsername(username);
if (sysUser == null) {
throw new UsernameNotFoundExceptionBase("用户不存在");
}
Collection<? extends GrantedAuthority> authorities
= AuthorityUtils.createAuthorityList(getUserPermissions(sysUser.getUserId()).toArray(new String[0]));
// 构造security用户
return new YamiSysUser(sysUser.getUserId(), sysUser.getShopId(), sysUser.getUsername(), sysUser.getPassword(), sysUser.getStatus() == 1,
true, true, true , authorities);
}
private Set<String> getUserPermissions(Long userId) {
List<String> permsList;
//系统管理员,拥有最高权限
if(userId == Constant.SUPER_ADMIN_ID){
List<SysMenu> menuList = sysMenuMapper.selectList(Wrappers.emptyWrapper());
permsList = menuList.stream().map(SysMenu::getPerms).collect(Collectors.toList());
}else{
permsList = sysUserMapper.queryAllPerms(userId);
}
Set<String> permsSet = permsList.stream().flatMap((perms)->{
if (StrUtil.isBlank(perms)) {
return null;
}
return Arrays.stream(perms.trim().split(","));
}
).collect(Collectors.toSet());
return permsSet;
}
@Override
public YamiUser loadUserByAppIdAndBizUserId(App app, String bizUserId) {
return null;
}
@Override
public void insertUserIfNecessary(AppConnect appConnect) {
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.task;
import java.util.Date;
import java.util.List;
import com.yami.shop.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.User;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
@Component("orderTask")
public class OrderTask {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private OrderService orderService;
@Autowired
private ProductService productService;
@Autowired
private SkuService skuService;
public void cancelOrder(){
Date now = new Date();
logger.info("取消超时未支付订单。。。");
// 获取30分钟之前未支付的订单
List<Order> orders = orderService.listOrderAndOrderItems(OrderStatus.UNPAY.value(),DateUtil.offsetMinute(now, -30));
if (CollectionUtil.isEmpty(orders)) {
return;
}
orderService.cancelOrders(orders);
for (Order order : orders) {
List<OrderItem> orderItems = order.getOrderItems();
for (OrderItem orderItem : orderItems) {
productService.removeProductCacheByProdId(orderItem.getProdId());
skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId());
}
}
}
/**
* 确认收货
*/
public void confirmOrder(){
Date now = new Date();
logger.info("系统自动确认收货订单。。。");
// 获取15天之前未支付的订单
List<Order> orders = orderService.listOrderAndOrderItems(OrderStatus.CONSIGNMENT.value(),DateUtil.offsetDay(now, -15));
if (CollectionUtil.isEmpty(orders)) {
return;
}
orderService.confirmOrder(orders);
for (Order order : orders) {
List<OrderItem> orderItems = order.getOrderItems();
for (OrderItem orderItem : orderItems) {
productService.removeProductCacheByProdId(orderItem.getProdId());
skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId());
}
}
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.admin.task;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class TestTask {
public void test1(){
System.out.println(DateUtil.now() + ": test1 running.................");
}
public void test2(String param){
System.out.println(DateUtil.now() + ": test2 running.................");
}
}
admin.datacenterId=1
admin.workerId=0
server:
port: 8085
spring:
datasource:
url: jdbc:mysql://rm-m5ee12omj4y0g741d0o.mysql.rds.aliyuncs.com:3306/retail_shops?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
username: kszzshop
password: eE12omj4y0g7#
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 0
maximum-pool-size: 20
idle-timeout: 10000
auto-commit: true
connection-test-query: SELECT 1
cache:
type: redis
redis:
cache-null-values: true
redis:
redisson:
config: classpath:redisson.yml
logging:
config: classpath:log4j2_dev.xml
\ No newline at end of file
server:
port: 8085
spring:
datasource:
url: jdbc:mysql://mall4j-mysql:3306/yami_shops?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 0
maximum-pool-size: 20
idle-timeout: 25000
auto-commit: true
connection-test-query: SELECT 1
redis:
redisson:
config: classpath:redisson-docker.yml
logging:
config: classpath:log4j2_prod.xml
\ No newline at end of file
server:
port: 8211
spring:
datasource:
url: jdbc:mysql://rm-m5ee12omj4y0g741d.mysql.rds.aliyuncs.com:3306/retail_shops?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
username: kszzshop
password: eE12omj4y0g7#
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 0
maximum-pool-size: 20
idle-timeout: 25000
auto-commit: true
connection-test-query: SELECT 1
cache:
type: redis
redis:
cache-null-values: true
redis:
redisson:
config: classpath:redisson.yml
logging:
config: classpath:log4j2_prod.xml
\ No newline at end of file
spring:
# 环境 dev|test|prod quart定时任务
profiles:
active: dev,quartz
#文件上传设置
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
enabled: true
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# mybaits-plus配置
mybatis-plus:
# MyBatis Mapper所对应的XML文件位置
mapper-locations: classpath*:/mapper/*Mapper.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
# 主键类型 0:数据库ID自增 1.未定义 2.用户输入 3 id_worker 4.uuid 5.id_worker字符串表示
id-type: AUTO
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: NOT_NULL
# 默认数据库表下划线命名
table-underline: true
.----------------. .----------------. .----------------. .----------------.
| .--------------. || .--------------. || .--------------. || .--------------. |
| | ____ ____ | || | __ | || | ____ ____ | || | _____ | |
| | |_ _||_ _| | || | / \ | || ||_ \ / _|| || | |_ _| | |
| | \ \ / / | || | / /\ \ | || | | \/ | | || | | | | |
| | \ \/ / | || | / ____ \ | || | | |\ /| | | || | | | | |
| | _| |_ | || | _/ / \ \_ | || | _| |_\/_| |_ | || | _| |_ | |
| | |______| | || ||____| |____|| || ||_____||_____|| || | |_____| | |
| | | || | | || | | || | | |
| '--------------' || '--------------' || '--------------' || '--------------' |
'----------------' '----------------' '----------------' '----------------'
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="60">
<Properties>
<Property name="PID">????</Property>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
<!-- 控制台日志格式化,包含颜色-->
<Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
</Properties>
<!--定义appender -->
<Appenders>
<!-- 默认的控制台日志输出,一般生产环境都是后台启动,这个没太大作用 -->
<Console name="Console" target="SYSTEM_OUT" follow="false">
<PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.mybatis" level="debug"/>
<Logger name="com.yami.shop" level="debug"/>
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
<Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
<Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
<Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
<Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<!--关闭swagger的类型转换异常的日志 https://github.com/springfox/springfox/issues/2528-->
<Logger name="springfox.documentation.swagger2" level="off"/>
<Logger name="io.swagger.models.parameters" level="off"/>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="60">
<Properties>
<Property name="PID">????</Property>
<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
<Property name="LOG_LEVEL_PATTERN">%5p</Property>
<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
<!-- 控制台日志格式化,包含颜色-->
<Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
<!-- 日志文件默认输出格式,不带行号输出(行号显示会影响日志输出性能);%C:大写,类名;%M:方法名;%m:错误信息;%n:换行 -->
<Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
<!-- 日志默认同类型日志,同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
<Property name="FILE_MAX_HISTORY">50</Property>
<Property name="FILE_MAX_SIZE">50MB</Property>
<Property name="PROJECT_PATH">..</Property>
</Properties>
<!--定义appender -->
<Appenders>
<!-- 默认的控制台日志输出,一般生产环境都是后台启动,这个没太大作用 -->
<Console name="Console" target="SYSTEM_OUT" follow="false">
<PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
</Console>
<!--fileName 文件名称-->
<!--filePattern 文件路径-->
<RollingFile name="DefaultFile" fileName="${PROJECT_PATH}/log/admin.log" filePattern="${PROJECT_PATH}/log/$${date:yyyy-MM}/admin-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<Pattern>${sys:FILE_LOG_PATTERN}</Pattern>
</PatternLayout>
<DefaultRolloverStrategy max="${FILE_MAX_HISTORY}"/>
<Policies>
<!--TimeBasedTriggeringPolicy 与 filePattern 结合使用,目前表示每间隔1天保存一遍日志-->
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="${FILE_MAX_SIZE}" />
</Policies>
</RollingFile>
<RollingFile name="ScheduleFile" fileName="${PROJECT_PATH}/log/schedule.log" filePattern="${PROJECT_PATH}/log/$${date:yyyy-MM}/schedule-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<Pattern>${sys:FILE_LOG_PATTERN}</Pattern>
</PatternLayout>
<DefaultRolloverStrategy max="${FILE_MAX_HISTORY}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="${FILE_MAX_SIZE}" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.mybatis" level="debug"/>
<Logger name="com.yami.shop" level="debug"/>
<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
<Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
<Logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
<Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
<Logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
<!--addtivity:用来描述是否向上级logger传递打印信息。默认是true。 -->
<!--指定定时任务在特定的log -->
<Logger name="com.yami.shop.sys.schedule" level="info" additivity="false">
<AppenderRef ref="ScheduleFile"/>
</Logger>
<!---->
<Root level="info">
<AppenderRef ref="DefaultFile" />
</Root>
</Loggers>
</configuration>
\ No newline at end of file
# 单节点设置
singleServerConfig:
address: redis://mall4j-redis:6379
database: 0
password: null
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
clientName: null
# 发布和订阅连接的最小空闲连接数 默认1
subscriptionConnectionMinimumIdleSize: 1
# 发布和订阅连接池大小 默认50
subscriptionConnectionPoolSize: 10
# 单个连接最大订阅数量 默认5
subscriptionsPerConnection: 5
# 最小空闲连接数 默认32,现在暂时不需要那么多的线程
connectionMinimumIdleSize: 4
# connectionPoolSize 默认64,现在暂时不需要那么多的线程
connectionPoolSize: 20
# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
threads: 0
# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
nettyThreads: 0
codec:
class: com.yami.shop.common.serializer.redisson.FstCodec
transportMode: NIO
\ No newline at end of file
# 单节点设置
singleServerConfig:
address: redis://47.104.110.168:6379
database: 0
password: retailmall@2020
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
clientName: null
# 发布和订阅连接的最小空闲连接数 默认1
subscriptionConnectionMinimumIdleSize: 1
# 发布和订阅连接池大小 默认50
subscriptionConnectionPoolSize: 10
# 单个连接最大订阅数量 默认5
subscriptionsPerConnection: 5
# 最小空闲连接数 默认32,现在暂时不需要那么多的线程
connectionMinimumIdleSize: 4
# connectionPoolSize 默认64,现在暂时不需要那么多的线程
connectionPoolSize: 20
# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
threads: 0
# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
nettyThreads: 0
codec:
class: com.yami.shop.common.serializer.redisson.FstCodec
transportMode: NIO
\ No newline at end of file
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER opgames(opgames.cn@gmail.com)
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /opt/projects/mall4j
WORKDIR /opt/projects/mall4j
EXPOSE 8086
ADD ./yami-shop-api/target/yami-shop-api-0.0.1-SNAPSHOT.jar ./
CMD java -jar -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -Dspring.profiles.active=docker yami-shop-api-0.0.1-SNAPSHOT.jar
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yami-shop</artifactId>
<groupId>com.yami.shop</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yami-shop-api</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-service</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-security</artifactId>
<version>${yami.shop.version}</version>
</dependency>
<dependency>
<groupId>com.yami.shop</groupId>
<artifactId>yami-shop-mp</artifactId>
<version>${yami.shop.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
/**
* @author lgh
*/
@SpringBootApplication
@ComponentScan(basePackages = {"com.yami.shop"})
public class ApiApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ApiApplication.class);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.config;
import cn.hutool.core.lang.Snowflake;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@AllArgsConstructor
public class ApiBeanConfig {
private final ApiConfig apiConfig;
@Bean
public Snowflake snowflake() {
return new Snowflake(apiConfig.getWorkerId(), apiConfig.getDatacenterId());
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* 商城配置文件
* @author lgh
*/
@Data
@Component
@PropertySource("classpath:api.properties")
@ConfigurationProperties(prefix = "api")
public class ApiConfig {
/**
* 数据中心ID
*/
private Integer datacenterId;
/**
* 终端ID
*/
private Integer workerId;
/**
* 域名
*/
private String domainName;
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger文档,只有在测试环境才会使用
* @author LGH
*/
//@Profile("dev")
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket baseRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("基础版")
.select()
.apis(RequestHandlerSelectors.basePackage("com.yami.shop.api"))
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("亚米商城接口文档")
.description("亚米商城接口文档Swagger版")
.termsOfServiceUrl("http://www.gz-yami.com/")
.contact(new Contact("广州亚米信息科技有限公司","https://www.gz-yami.com/", ""))
.version("1.0")
.build();
}
}
\ No newline at end of file
package com.yami.shop.api.config;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
import java.util.stream.Collectors;
@Configuration
@EnableConfigurationProperties(WxAppProperties.class)
public class WxAppConfiguration {
private WxAppProperties wxAppProperties;
private static Map<String, WxMaService> maServices = Maps.newHashMap();
private static Map<String, WxAppProperties.Config> maWxConfigs = Maps.newHashMap();
@Autowired
public WxAppConfiguration(WxAppProperties wxAppProperties) {
this.wxAppProperties = wxAppProperties;
}
public static WxMaService getMaService(String appid) {
WxMaService wxService = maServices.get(appid);
if (wxService == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxService;
}
public static WxAppProperties.Config getWxConfig(String appid) {
WxAppProperties.Config wxConfig = maWxConfigs.get(appid);
if (wxConfig == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxConfig;
}
@Bean
public Object services() {
maServices = this.wxAppProperties.getConfigs()
.stream()
.map(a -> {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(a.getAppid());
config.setSecret(a.getSecret());
config.setToken(a.getToken());
config.setAesKey(a.getAesKey());
config.setMsgDataFormat(a.getMsgDataFormat());
WxMaService maService = new WxMaServiceImpl();
maService.setWxMaConfig(config);
return maService;
}).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
maWxConfigs = this.wxAppProperties.getConfigs()
.stream()
.collect(Collectors.toMap(WxAppProperties.Config::getAppid, a -> a));
return Boolean.TRUE;
}
}
\ No newline at end of file
package com.yami.shop.api.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxAppProperties {
private List<Config> configs;
public List<Config> getConfigs() {
return configs;
}
@Data
public static class Config {
/**
* 设置微信小程序的appid
*/
private String appid;
/**
* 设置微信小程序的Secret
*/
private String secret;
/**
* 设置微信小程序消息服务器配置的token
*/
private String token;
/**
* 设置微信小程序消息服务器配置的EncodingAESKey
*/
private String aesKey;
/**
* 消息格式,XML或者JSON
*/
private String msgDataFormat;
/**
* 处于审核中的微信小程序版本号
*/
private String magicNumber;
private Long magicUserId;
private String magicUserType;
private String taskType;
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import java.util.Date;
import java.util.List;
import javax.validation.Valid;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.app.dto.UserAddrDto;
import com.yami.shop.bean.app.param.AddrParam;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.service.UserAddrService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
@RestController
@RequestMapping("/p/address")
@Api(tags = "地址接口")
@AllArgsConstructor
public class AddrController {
@Autowired
private MapperFacade mapperFacade;
@Autowired
private UserAddrService userAddrService;
/**
* 选择订单配送地址
*/
@GetMapping("/list")
@ApiOperation(value = "用户地址列表", notes = "获取用户的所有地址信息")
public ResponseEntity<List<UserAddrDto>> dvyList() {
String userId = SecurityUtils.getUser().getUserId();
List<UserAddr> userAddrs = userAddrService.list(new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, userId).orderByDesc(UserAddr::getCommonAddr).orderByDesc(UserAddr::getUpdateTime));
return ResponseEntity.ok(mapperFacade.mapAsList(userAddrs, UserAddrDto.class));
}
@PostMapping("/addAddr")
@ApiOperation(value = "新增用户地址", notes = "新增用户地址")
public ResponseEntity<String> addAddr(@Valid @RequestBody AddrParam addrParam) {
String userId = SecurityUtils.getUser().getUserId();
if (addrParam.getAddrId() != null && addrParam.getAddrId() != 0) {
return ResponseEntity.badRequest().body("该地址已存在");
}
int addrCount = userAddrService.count(new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, userId));
UserAddr userAddr = mapperFacade.map(addrParam, UserAddr.class);
if (addrCount == 0) {
userAddr.setCommonAddr(1);
} else {
userAddr.setCommonAddr(0);
}
userAddr.setUserId(userId);
userAddr.setStatus(1);
userAddr.setCreateTime(new Date());
userAddr.setUpdateTime(new Date());
userAddrService.save(userAddr);
if (userAddr.getCommonAddr() == 1) {
// 清除默认地址缓存
userAddrService.removeUserAddrByUserId(0L, userId);
}
return ResponseEntity.ok("添加地址成功");
}
/**
* 修改订单配送地址
*/
@PutMapping("/updateAddr")
@ApiOperation(value = "修改订单用户地址", notes = "修改用户地址")
public ResponseEntity<String> updateAddr(@Valid @RequestBody AddrParam addrParam) {
String userId = SecurityUtils.getUser().getUserId();
UserAddr dbUserAddr = userAddrService.getUserAddrByUserId(addrParam.getAddrId(), userId);
if (dbUserAddr == null) {
return ResponseEntity.badRequest().body("该地址已被删除");
}
UserAddr userAddr = mapperFacade.map(addrParam, UserAddr.class);
userAddr.setUserId(userId);
userAddr.setUpdateTime(new Date());
userAddrService.updateById(userAddr);
// 清除当前地址缓存
userAddrService.removeUserAddrByUserId(addrParam.getAddrId(), userId);
// 清除默认地址缓存
userAddrService.removeUserAddrByUserId(0L, userId);
return ResponseEntity.ok("修改地址成功");
}
/**
* 删除订单配送地址
*/
@DeleteMapping("/deleteAddr/{addrId}")
@ApiOperation(value = "删除订单用户地址", notes = "根据地址id,删除用户地址")
@ApiImplicitParam(name = "addrId", value = "地址ID", required = true, dataType = "Long")
public ResponseEntity<String> deleteDvy(@PathVariable("addrId") Long addrId) {
String userId = SecurityUtils.getUser().getUserId();
UserAddr userAddr = userAddrService.getUserAddrByUserId(addrId, userId);
if (userAddr == null) {
return ResponseEntity.badRequest().body("该地址已被删除");
}
if (userAddr.getCommonAddr() == 1) {
return ResponseEntity.badRequest().body("默认地址无法删除");
}
userAddrService.removeById(addrId);
userAddrService.removeUserAddrByUserId(addrId, userId);
return ResponseEntity.ok("删除地址成功");
}
/**
* 设置默认地址
*/
@PutMapping("/defaultAddr/{addrId}")
@ApiOperation(value = "设置默认地址", notes = "根据地址id,设置默认地址")
public ResponseEntity<String> defaultAddr(@PathVariable("addrId") Long addrId) {
String userId = SecurityUtils.getUser().getUserId();
userAddrService.updateDefaultUserAddr(addrId, userId);
userAddrService.removeUserAddrByUserId(0L, userId);
userAddrService.removeUserAddrByUserId(addrId, userId);
return ResponseEntity.ok("修改地址成功");
}
/**
* 获取地址信息订单配送地址
*/
@GetMapping("/addrInfo/{addrId}")
@ApiOperation(value = "获取地址信息", notes = "根据地址id,获取地址信息")
@ApiImplicitParam(name = "addrId", value = "地址ID", required = true, dataType = "Long")
public ResponseEntity<UserAddrDto> addrInfo(@PathVariable("addrId") Long addrId) {
String userId = SecurityUtils.getUser().getUserId();
UserAddr userAddr = userAddrService.getUserAddrByUserId(addrId, userId);
if (userAddr == null) {
throw new YamiShopBindException("该地址已被删除");
}
return ResponseEntity.ok(mapperFacade.map(userAddr, UserAddrDto.class));
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import java.util.List;
import com.yami.shop.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.model.Area;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
/**
*
* @author lgh on 2018/10/26.
*/
@RestController
@RequestMapping("/p/area")
@Api(tags="省市区接口")
public class AreaController {
@Autowired
private AreaService areaService;
/**
* 分页获取
*/
@GetMapping("/listByPid")
@ApiOperation(value="获取省市区信息", notes="根据省市区的pid获取地址信息")
@ApiImplicitParam(name = "pid", value = "省市区的pid(pid为0获取所有省份)", required = true, dataType = "String")
public ResponseEntity<List<Area>> listByPid(Long pid){
List<Area> list = areaService.listByPid(pid);
return ResponseEntity.ok(list);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.app.dto.CategoryDto;
import com.yami.shop.bean.model.Category;
import com.yami.shop.service.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
@RestController
@RequestMapping("/category")
@Api(tags = "分类接口")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@Autowired
private MapperFacade mapperFacade;
/**
* 分类信息列表接口
*/
@GetMapping("/categoryInfo")
@ApiOperation(value = "分类信息列表", notes = "获取所有的产品分类信息,顶级分类的parentId为0,默认为顶级分类")
@ApiImplicitParam(name = "parentId", value = "分类ID", required = false, dataType = "Long")
public ResponseEntity<List<CategoryDto>> categoryInfo(@RequestParam(value = "parentId", defaultValue = "0") Long parentId) {
List<Category> categories = categoryService.listByParentId(parentId);
List<CategoryDto> categoryDtos = mapperFacade.mapAsList(categories, CategoryDto.class);
return ResponseEntity.ok(categoryDtos);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import com.yami.shop.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.yami.shop.bean.app.dto.DeliveryDto;
import com.yami.shop.bean.model.Delivery;
import com.yami.shop.bean.model.Order;
import com.yami.shop.common.util.Json;
import com.yami.shop.service.DeliveryService;
import cn.hutool.http.HttpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@RestController
@RequestMapping("/delivery")
@Api(tags="查看物流接口")
public class DeliveryController {
@Autowired
private DeliveryService deliveryService;
@Autowired
private OrderService orderService;
/**
* 查看物流接口
*/
@GetMapping("/check")
@ApiOperation(value="查看物流", notes="根据订单号查看物流")
@ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
public ResponseEntity<DeliveryDto> checkDelivery(String orderNumber) {
Order order = orderService.getOrderByOrderNumber(orderNumber);
Delivery delivery = deliveryService.getById(order.getDvyId());
String url = delivery.getQueryUrl().replace("{dvyFlowId}", order.getDvyFlowId());
String deliveryJson = HttpUtil.get(url);
DeliveryDto deliveryDto = Json.parseObject(deliveryJson, DeliveryDto.class);
deliveryDto.setDvyFlowId(order.getDvyFlowId());
deliveryDto.setCompanyHomeUrl(delivery.getCompanyHomeUrl());
deliveryDto.setCompanyName(delivery.getDvyName());
return ResponseEntity.ok(deliveryDto);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import com.yami.shop.bean.app.dto.IndexImgDto;
import com.yami.shop.bean.model.IndexImg;
import com.yami.shop.service.IndexImgService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Api(tags = "首页轮播图接口")
public class IndexImgController {
@Autowired
private MapperFacade mapperFacade;
@Autowired
private IndexImgService indexImgService;
/**
* 首页轮播图接口
*/
@GetMapping("/indexImgs")
@ApiOperation(value = "首页轮播图", notes = "获取首页轮播图列表信息")
public ResponseEntity<List<IndexImgDto>> indexImgs() {
List<IndexImg> indexImgList = indexImgService.listIndexImgs();
List<IndexImgDto> indexImgDtos = mapperFacade.mapAsList(indexImgList, IndexImgDto.class);
return ResponseEntity.ok(indexImgDtos);
}
}
/*
* Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
*
* https://www.gz-yami.com/
*
* 未经允许,不可做商业用途!
*
* 版权所有,侵权必究!
*/
package com.yami.shop.api.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.dao.OrderMapper;
import com.yami.shop.security.util.SecurityUtils;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.UserAddrOrder;
import com.yami.shop.common.util.Arith;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
@RestController
@RequestMapping("/p/myOrder")
@Api(tags = "我的订单接口")
@AllArgsConstructor
public class MyOrderController {
private final OrderService orderService;
private final MapperFacade mapperFacade;
private final UserAddrOrderService userAddrOrderService;
private final ProductService productService;
private final SkuService skuService;
private final MyOrderService myOrderService;
private final ShopDetailService shopDetailService;
private final OrderItemService orderItemService;
/**
* 订单详情信息接口
*/
@GetMapping("/orderDetail")
@ApiOperation(value = "订单详情信息", notes = "根据订单号获取订单详情信息")
@ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
public ResponseEntity<OrderShopDto> orderDetail(@RequestParam(value = "orderNumber", required = true) String orderNumber) {
String userId = SecurityUtils.getUser().getUserId();
OrderShopDto orderShopDto = new OrderShopDto();
Order order = orderService.getOrderByOrderNumber(orderNumber);
if (order == null) {
throw new RuntimeException("该订单不存在");
}
if (!Objects.equals(order.getUserId(), userId)) {
throw new RuntimeException("你没有权限获取该订单信息");
}
ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(order.getShopId());
UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
UserAddrDto userAddrDto = mapperFacade.map(userAddrOrder, UserAddrDto.class);
List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
List<OrderItemDto> orderItemDtos = mapperFacade.mapAsList(orderItems, OrderItemDto.class);
orderShopDto.setShopId(shopDetail.getShopId());
orderShopDto.setShopName(shopDetail.getShopName());
orderShopDto.setActualTotal(order.getActualTotal());
orderShopDto.setUserAddrDto(userAddrDto);
orderShopDto.setOrderItemDtos(orderItemDtos);
orderShopDto.setTransfee(order.getFreightAmount());
orderShopDto.setReduceAmount(order.getReduceAmount());
orderShopDto.setCreateTime(order.getCreateTime());
orderShopDto.setRemarks(order.getRemarks());
orderShopDto.setStatus(order.getStatus());
double total = 0.0;
Integer totalNum = 0;
for (OrderItemDto orderItem : orderShopDto.getOrderItemDtos()) {
total = Arith.add(total, orderItem.getProductTotalAmount());
totalNum += orderItem.getProdCount();
}
orderShopDto.setTotal(total);
orderShopDto.setTotalNum(totalNum);
return ResponseEntity.ok(orderShopDto);
}
/**
* 订单列表接口
*/
@GetMapping("/myOrder")
@ApiOperation(value = "订单列表信息", notes = "根据订单状态获取订单列表信息,状态为0时获取所有订单")
@ApiImplicitParams({
@ApiImplicitParam(name = "status", value = "订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败", required = false, dataType = "Integer")
})
public ResponseEntity<IPage<MyOrderDto>> myOrder(@RequestParam(value = "status") Integer status,PageParam<MyOrderDto> page) {
String userId = SecurityUtils.getUser().getUserId();
IPage<MyOrderDto> myOrderDtoIpage = myOrderService.pageMyOrderByUserIdAndStatus(page, userId, status);
return ResponseEntity.ok(myOrderDtoIpage);
}
/**
* 取消订单
*/
@PutMapping("/cancel/{orderNumber}")
@ApiOperation(value = "根据订单号取消订单", notes = "根据订单号取消订单")
@ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
public ResponseEntity<String> cancel(@PathVariable("orderNumber") String orderNumber) {
String userId = SecurityUtils.getUser().getUserId();
Order order = orderService.getOrderByOrderNumber(orderNumber);
if (!Objects.equals(order.getUserId(), userId)) {
throw new YamiShopBindException("你没有权限获取该订单信息");
}
if (!Objects.equals(order.getStatus(), OrderStatus.UNPAY.value())) {
throw new YamiShopBindException("订单已支付,无法取消订单");
}
List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
order.setOrderItems(orderItems);
// 取消订单
orderService.cancelOrders(Arrays.asList(order));
// 清除缓存
for (OrderItem orderItem : orderItems) {
productService.removeProductCacheByProdId(orderItem.getProdId());
skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId());
}
return ResponseEntity.ok().build();
}
/**
* 确认收货
*/
@PutMapping("/receipt/{orderNumber}")
@ApiOperation(value = "根据订单号确认收货", notes = "根据订单号确认收货")
public ResponseEntity<String> receipt(@PathVariable("orderNumber") String orderNumber) {
String userId = SecurityUtils.getUser().getUserId();
Order order = orderService.getOrderByOrderNumber(orderNumber);
if (!Objects.equals(order.getUserId(), userId)) {
throw new YamiShopBindException("你没有权限获取该订单信息");
}
if (!Objects.equals(order.getStatus(), OrderStatus.CONSIGNMENT.value())) {
throw new YamiShopBindException("订单未发货,无法确认收货");
}
List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
order.setOrderItems(orderItems);
// 确认收货
orderService.confirmOrder(Arrays.asList(order));
for (OrderItem orderItem : orderItems) {
productService.removeProductCacheByProdId(orderItem.getProdId());
skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId());
}
return ResponseEntity.ok().build();
}
/**
* 删除订单
*/
@DeleteMapping("/{orderNumber}")
@ApiOperation(value = "根据订单号删除订单", notes = "根据订单号删除订单")
@ApiImplicitParam(name = "orderNumber", value = "订单号", required = true, dataType = "String")
public ResponseEntity<String> delete(@PathVariable("orderNumber") String orderNumber) {
String userId = SecurityUtils.getUser().getUserId();
Order order = orderService.getOrderByOrderNumber(orderNumber);
if (order == null) {
throw new YamiShopBindException("该订单不存在");
}
if (!Objects.equals(order.getUserId(), userId)) {
throw new YamiShopBindException("你没有权限获取该订单信息");
}
if (!Objects.equals(order.getStatus(), OrderStatus.SUCCESS.value()) || !Objects.equals(order.getStatus(), OrderStatus.CLOSE.value()) ) {
throw new YamiShopBindException("订单未完成或未关闭,无法删除订单");
}
// 删除订单
orderService.deleteOrders(Arrays.asList(order));
return ResponseEntity.ok("删除成功");
}
/**
* 获取我的订单订单数量
*/
@GetMapping("/orderCount")
@ApiOperation(value = "获取我的订单订单数量", notes = "获取我的订单订单数量")
public ResponseEntity<OrderCountData> getOrderCount() {
String userId = SecurityUtils.getUser().getUserId();
OrderCountData orderCountMap = orderService.getOrderCount(userId);
return ResponseEntity.ok(orderCountMap);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment