商城后端
parent
12fb035b2e
commit
4dfa2301df
|
|
@ -34,6 +34,11 @@ public class SysConfigController extends BaseController
|
|||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
@GetMapping("/test")
|
||||
public String list(){
|
||||
return "test";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数配置列表
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ public class SysLoginController
|
|||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
*
|
||||
|
|
@ -58,7 +61,7 @@ public class SysLoginController
|
|||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
// 生成令牌
|
||||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
|
||||
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(),
|
||||
loginBody.getUuid());
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
return ajax;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ spring:
|
|||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: password
|
||||
url: jdbc:mysql://193.112.94.36:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: ry-vue
|
||||
password: yKSYaNzYifKFNHHj
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ ruoyi:
|
|||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: D:/ruoyi/uploadPath
|
||||
profile: /home/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
|
|
@ -68,13 +68,13 @@ spring:
|
|||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: localhost
|
||||
host: 193.112.94.36
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password:
|
||||
password: 123456
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="/home/ruoyi/logs" />
|
||||
<property name="log.path" value="./logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,13 @@
|
|||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--新加Lombok包 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.24</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -15,6 +15,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
|||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
|
||||
public class SysDept extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ public class SysLoginService
|
|||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String username, String password, String code, String uuid)
|
||||
public String login(String username, String password, String uuid)
|
||||
{
|
||||
// 验证码校验
|
||||
validateCaptcha(username, code, uuid);
|
||||
// validateCaptcha(username, code, uuid);
|
||||
// 登录前置校验
|
||||
loginPreCheck(username, password);
|
||||
// 用户验证
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ public class VelocityUtils
|
|||
}
|
||||
else if (template.contains("mapper.java.vm"))
|
||||
{
|
||||
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
|
||||
fileName = StringUtils.format("{}/mapper/{}mapper.java", javaPath, className);
|
||||
}
|
||||
else if (template.contains("service.java.vm"))
|
||||
{
|
||||
|
|
@ -205,7 +205,7 @@ public class VelocityUtils
|
|||
}
|
||||
else if (template.contains("mapper.xml.vm"))
|
||||
{
|
||||
fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
|
||||
fileName = StringUtils.format("{}/{}mapper.xml", mybatisPath, className);
|
||||
}
|
||||
else if (template.contains("sql.vm"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
<?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>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.9.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>ruoyi-mall</artifactId>
|
||||
|
||||
<description>
|
||||
微店商城服务
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- spring-boot-devtools -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional> <!-- 表示依赖不会传递 -->
|
||||
</dependency>
|
||||
|
||||
<!-- swagger3-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
<version>1.6.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Mysql驱动包 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 核心模块-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-framework</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 定时任务-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成-->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.5.15</version>
|
||||
<configuration>
|
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<warName>${project.artifactId}</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
|
||||
/**
|
||||
* 启动程序
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||
public class MallApplication
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(MallApplication.class, args);
|
||||
System.out.println("商城Mall启动成功");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.ruoyi;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
/**
|
||||
* web容器中进行部署
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RuoYiServletInitializer extends SpringBootServletInitializer
|
||||
{
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
|
||||
{
|
||||
return application.sources(MallApplication.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.ruoyi.web.controller;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.web.domain.Brand;
|
||||
import com.ruoyi.web.service.BrandService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/mall/brand")
|
||||
public class BrandController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private BrandService brandService;
|
||||
|
||||
/**
|
||||
* 获取商品品牌树
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Anonymous
|
||||
@GetMapping("/tree")
|
||||
public AjaxResult getBrandTree() {
|
||||
return AjaxResult.success(brandService.getBrandTree());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品品牌
|
||||
*
|
||||
* @param brand
|
||||
* @return
|
||||
*/
|
||||
@Anonymous
|
||||
@Log(title = "商品品牌管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
public AjaxResult addBrand(@RequestBody Brand brand) {
|
||||
brand.setCreateBy(getUsername());
|
||||
return toAjax(brandService.addBrand(brand));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改商品品牌
|
||||
*
|
||||
* @param brand
|
||||
* @return
|
||||
*/
|
||||
@Anonymous
|
||||
@Log(title = "商品品牌管理", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public AjaxResult updateBrand(@RequestBody Brand brand) {
|
||||
return toAjax(brandService.updateBrand(brand));
|
||||
}
|
||||
|
||||
// 删除品牌
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public String deleteBrand(@PathVariable Long id) {
|
||||
brandService.deleteBrand(id);
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
package com.ruoyi.web.controller;
|
||||
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.common.utils.file.MimeTypeUtils;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.web.domain.Product;
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import com.ruoyi.web.dto.BatchStoreDTO;
|
||||
import com.ruoyi.web.service.ProductService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品管理
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/mall/product")
|
||||
public class ProductStoreController extends BaseController {
|
||||
@Autowired
|
||||
private ProductService productService;
|
||||
|
||||
/**
|
||||
* 获取商品列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('product:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(Product product) {
|
||||
return AjaxResult.success(productService.selectList(product));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除商品
|
||||
*/
|
||||
@Anonymous
|
||||
@DeleteMapping("/batchDelete")
|
||||
public AjaxResult batchDelete(@RequestBody BatchStoreDTO dto) {
|
||||
return toAjax(productService.batchProductById(dto));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据商品id 获取商品详情
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('product:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable Long id) {
|
||||
return success(productService.selectProductBarCode(id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 新增商品
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('product:add')")
|
||||
@Log(title = "商品管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
public AjaxResult add(@Validated Product product,
|
||||
@RequestParam("file") MultipartFile file) throws IOException, InvalidExtensionException {
|
||||
|
||||
if (!productService.checkProductCodeUnique(product)) {
|
||||
return error("新增商品条码'" + product.getProductBarCode() + "'失败,商品条码已存在");
|
||||
}
|
||||
// TODO: 2026/1/14 这个file 为空的时候 就使用国码里面的图片,不为空代表用户自己选择了图片上传 用自己服务器上的
|
||||
//国码后续添加
|
||||
if (!file.isEmpty()) {
|
||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
|
||||
if (StringUtils.isNotEmpty(avatar)) {
|
||||
product.setMainImage(avatar);
|
||||
}
|
||||
}
|
||||
product.setCreateBy(getUsername());
|
||||
return toAjax(productService.insertProductStore(product));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改商品信息
|
||||
*/
|
||||
// @PreAuthorize("@ss.hasPermi('product:edit')")
|
||||
@Anonymous
|
||||
@Log(title = "商品管理", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public AjaxResult edit(@Validated Product product,
|
||||
@RequestParam("file") MultipartFile file) throws IOException, InvalidExtensionException {
|
||||
if (!productService.checkProductCodeUnique(product)) {
|
||||
return error("修改商品条码'" + product.getProductBarCode() + "'失败,商品条码已存在");
|
||||
}
|
||||
// TODO: 2026/1/14 这个file 为空的时候 就使用国码里面的图片,不为空代表用户自己选择了图片上传 用自己服务器上的
|
||||
//然后修改的时候 这个file不为空代表用户又修改了图片需要更新,为空的话之前图片保持不变
|
||||
if (!file.isEmpty()) {
|
||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
|
||||
if (StringUtils.isNotEmpty(avatar)) {
|
||||
product.setMainImage(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
//todo 这里可以国码有的时候使用国码的图片路径
|
||||
|
||||
|
||||
product.setUpdateBy(getUsername());
|
||||
return toAjax(productService.updateProduct(product));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('product:delete')")
|
||||
@Log(title = "商品管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/delete/{id}")
|
||||
public AjaxResult remove(@PathVariable Long id) {
|
||||
return toAjax(productService.deleteProductById(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商品导入excel
|
||||
*/
|
||||
@Log(title = "商品管理", businessType = BusinessType.IMPORT)
|
||||
@PreAuthorize("@ss.hasPermi('product:import')")
|
||||
@PostMapping("/importData")
|
||||
public AjaxResult importData(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam("storeId") Integer storeId) throws Exception {
|
||||
ExcelUtil<Product> util = new ExcelUtil<Product>(Product.class);
|
||||
List<Product> productList = util.importExcel(file.getInputStream());
|
||||
return AjaxResult.success(productService.importProduct(productList,storeId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.ruoyi.web.controller;
|
||||
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import com.ruoyi.web.dto.UserStoreAssignDTO;
|
||||
import com.ruoyi.web.service.StoreService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门店管理
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/mall/store")
|
||||
public class StoreController extends BaseController {
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
|
||||
/**
|
||||
* 查询门店管理
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('store:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(Store store) {
|
||||
startPage();
|
||||
List<Store> list = storeService.selectList(store);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增门店
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('store:add')")
|
||||
@Log(title = "门店管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/add")
|
||||
public AjaxResult add(@Validated @RequestBody Store store) {
|
||||
if (!storeService.checkStoreNameUnique(store)) {
|
||||
return error("新增门店'" + store.getStoreCode() + "'失败,门店编码已存在");
|
||||
}
|
||||
store.setCreateBy(getUsername());
|
||||
return toAjax(storeService.insertStore(store));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除门店
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('store:delete')")
|
||||
@Log(title = "门店管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/delete/{storeId}")
|
||||
public AjaxResult remove(@PathVariable Long storeId) {
|
||||
return toAjax(storeService.deleteStoreById(storeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改门店信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('store:edit')")
|
||||
@Log(title = "门店管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("update")
|
||||
public AjaxResult edit(@Validated @RequestBody Store store) {
|
||||
if (!storeService.checkStoreNameUnique(store)) {
|
||||
return error("修改门店编码'" + store.getStoreCode() + "'失败,门店编码已存在");
|
||||
}
|
||||
store.setUpdateBy(getUsername());
|
||||
return toAjax(storeService.updateStore(store));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户关联门店 包含 修改 删除
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('user:store:edit')")
|
||||
@Log(title = "用户关联门店", businessType = BusinessType.GRANT)
|
||||
@PutMapping("/userCorrelationStore")
|
||||
public AjaxResult userCorrelationStore(@RequestBody UserStoreAssignDTO dto) {
|
||||
return toAjax(storeService.insertUserStores(dto.getUserId(), dto.getStoreIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id 获取关联的门店
|
||||
*/
|
||||
// @PreAuthorize("@ss.hasPermi('product:query')")
|
||||
@GetMapping(value = "/getUserStore/{userId}")
|
||||
public AjaxResult getUserStore(@PathVariable String userId) {
|
||||
return success(storeService.getUserStore(userId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package com.ruoyi.web.core.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.models.auth.In;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.ApiKey;
|
||||
import springfox.documentation.service.AuthorizationScope;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.service.SecurityReference;
|
||||
import springfox.documentation.service.SecurityScheme;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
/**
|
||||
* Swagger2的接口配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class SwaggerConfig
|
||||
{
|
||||
/** 系统基础配置 */
|
||||
@Autowired
|
||||
private RuoYiConfig ruoyiConfig;
|
||||
|
||||
/** 是否开启swagger */
|
||||
@Value("${swagger.enabled}")
|
||||
private boolean enabled;
|
||||
|
||||
/** 设置请求的统一前缀 */
|
||||
@Value("${swagger.pathMapping}")
|
||||
private String pathMapping;
|
||||
|
||||
/**
|
||||
* 创建API
|
||||
*/
|
||||
@Bean
|
||||
public Docket createRestApi()
|
||||
{
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
// 是否启用Swagger
|
||||
.enable(enabled)
|
||||
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
|
||||
.apiInfo(apiInfo())
|
||||
// 设置哪些接口暴露给Swagger展示
|
||||
.select()
|
||||
// 扫描所有有注解的api,用这种方式更灵活
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
// 扫描指定包中的swagger注解
|
||||
// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
|
||||
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
/* 设置安全模式,swagger可以设置访问token */
|
||||
.securitySchemes(securitySchemes())
|
||||
.securityContexts(securityContexts())
|
||||
.pathMapping(pathMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全模式,这里指定token通过Authorization头请求头传递
|
||||
*/
|
||||
private List<SecurityScheme> securitySchemes()
|
||||
{
|
||||
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
|
||||
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
|
||||
return apiKeyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全上下文
|
||||
*/
|
||||
private List<SecurityContext> securityContexts()
|
||||
{
|
||||
List<SecurityContext> securityContexts = new ArrayList<>();
|
||||
securityContexts.add(
|
||||
SecurityContext.builder()
|
||||
.securityReferences(defaultAuth())
|
||||
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
|
||||
.build());
|
||||
return securityContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认的安全上引用
|
||||
*/
|
||||
private List<SecurityReference> defaultAuth()
|
||||
{
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
List<SecurityReference> securityReferences = new ArrayList<>();
|
||||
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
|
||||
return securityReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加摘要信息
|
||||
*/
|
||||
private ApiInfo apiInfo()
|
||||
{
|
||||
// 用ApiInfoBuilder进行定制
|
||||
return new ApiInfoBuilder()
|
||||
// 设置标题
|
||||
.title("标题:若依管理系统_接口文档")
|
||||
// 描述
|
||||
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
|
||||
// 作者信息
|
||||
.contact(new Contact(ruoyiConfig.getName(), null, null))
|
||||
// 版本
|
||||
.version("版本号:" + ruoyiConfig.getVersion())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi.web.domain;
|
||||
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品品牌表 mall_brand
|
||||
*/
|
||||
@Data
|
||||
public class Brand extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
private Long parentId = 0L; // 0表示一级品牌
|
||||
private String brandName; // 品牌名称
|
||||
private Integer storeId; //门店id
|
||||
// 非数据库字段:子商品品牌列表
|
||||
private List<Brand> children;
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package com.ruoyi.web.domain;
|
||||
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 商品门店库存表 mall_product_store
|
||||
*/
|
||||
@Data
|
||||
public class Product extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品编码
|
||||
*/
|
||||
@Excel(name = "商品编码")
|
||||
private String productCode;
|
||||
|
||||
/**
|
||||
* 货架码
|
||||
*/
|
||||
@Excel(name = "货架码")
|
||||
private String shelfCode;
|
||||
|
||||
/**
|
||||
* 保质期天数
|
||||
*/
|
||||
private Integer shelfLife;
|
||||
|
||||
/**
|
||||
* 生产日期
|
||||
*/
|
||||
private String productionDate;
|
||||
|
||||
/**
|
||||
* 临期天数
|
||||
*/
|
||||
private Integer approaching;
|
||||
|
||||
/**
|
||||
* 商品条码
|
||||
*/
|
||||
@NotBlank(message = "商品条码不能为空")
|
||||
@Excel(name = "商品条码")
|
||||
private String productBarCode;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@NotBlank(message = "商品名称不能为空")
|
||||
@Excel(name = "商品名称")
|
||||
private String productName;
|
||||
/**
|
||||
* 商品描述
|
||||
*/
|
||||
@Excel(name = "商品描述")
|
||||
private String productDesc;
|
||||
/**
|
||||
* 主图
|
||||
*/
|
||||
private String mainImage;
|
||||
/**
|
||||
* 门店销售价
|
||||
*/
|
||||
private BigDecimal storePrice;
|
||||
/**
|
||||
* 成本价
|
||||
*/
|
||||
private BigDecimal costPrice;
|
||||
|
||||
/**
|
||||
* 市场价
|
||||
*/
|
||||
private Long originalPrice;
|
||||
|
||||
/**
|
||||
* 门店ID
|
||||
*/
|
||||
private Integer storeId;
|
||||
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
@NotNull(message = "库存数量不能为空")
|
||||
@Excel(name = "库存数量")
|
||||
private Integer stockQuantity;
|
||||
/**
|
||||
* 已售数量
|
||||
*/
|
||||
private Integer soldQuantity;
|
||||
|
||||
/**
|
||||
* 状态(0上架 1下架)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.ruoyi.web.domain;
|
||||
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 门店表 mall_store
|
||||
*/
|
||||
@Data
|
||||
public class Store extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 门店ID
|
||||
*/
|
||||
private Long storeId;
|
||||
|
||||
/**
|
||||
* 门店名称
|
||||
*/
|
||||
private String storeName;
|
||||
|
||||
/**
|
||||
* 门店编码
|
||||
*/
|
||||
private String storeCode;
|
||||
|
||||
/**
|
||||
* 省份
|
||||
*/
|
||||
private String province;
|
||||
|
||||
/**
|
||||
* 城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 区县
|
||||
*/
|
||||
private String district;
|
||||
|
||||
/**
|
||||
* 完整地址
|
||||
*/
|
||||
private String fullAddress;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 店长
|
||||
*/
|
||||
private String storeManager;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.ruoyi.web.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class BatchStoreDTO {
|
||||
|
||||
private List<Long> ids;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.ruoyi.web.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserStoreAssignDTO {
|
||||
private Long userId;
|
||||
private Long[] storeIds;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.ruoyi.web.mapper;
|
||||
|
||||
import com.ruoyi.web.domain.Brand;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BrandMapper {
|
||||
|
||||
/**
|
||||
* 查询所有品牌
|
||||
*/
|
||||
List<Brand> selectAll();
|
||||
|
||||
/**
|
||||
* 查询一级品牌(parentId=0)
|
||||
*/
|
||||
List<Brand> selectRootBrands();
|
||||
|
||||
/**
|
||||
* 根据父品牌ID查询子品牌
|
||||
*/
|
||||
List<Brand> selectByParentId(@Param("parentId") Long parentId);
|
||||
|
||||
/**
|
||||
* 根据ID查询品牌
|
||||
*/
|
||||
Brand selectById(@Param("id") Long id);
|
||||
|
||||
/**
|
||||
* 新增品牌
|
||||
*/
|
||||
int insert(Brand brand);
|
||||
|
||||
/**
|
||||
* 更新品牌
|
||||
*/
|
||||
int update(Brand brand);
|
||||
|
||||
/**
|
||||
* 删除品牌
|
||||
*/
|
||||
int delete(@Param("id") Long id);
|
||||
|
||||
|
||||
// /**
|
||||
// * 检查是否有子品牌
|
||||
// */
|
||||
// int countChildren(@Param("parentId") Long parentId);
|
||||
//
|
||||
// /**
|
||||
// * 根据品牌名称查询
|
||||
// */
|
||||
// Brand selectByName(@Param("brandName") String brandName);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.ruoyi.web.mapper;
|
||||
|
||||
import com.ruoyi.web.domain.Product;
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 数据层
|
||||
*/
|
||||
public interface ProductMapper {
|
||||
List<Product> selectList(Product product);
|
||||
|
||||
Product checkProductCodeUnique(Product product);
|
||||
|
||||
int insertProductStore(Product product);
|
||||
|
||||
Product selectProductBarCode(Long id);
|
||||
|
||||
int deleteProductById(Long id);
|
||||
|
||||
int updateProduct(Product product);
|
||||
|
||||
int updateProductBarCode(Product product);
|
||||
|
||||
|
||||
int batchProductById(@Param("ids") List<Long> ids);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.ruoyi.web.mapper;
|
||||
|
||||
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门店 数据层
|
||||
*
|
||||
*/
|
||||
public interface StoreMapper
|
||||
{
|
||||
List<Store> selectList(Store store);
|
||||
|
||||
int insertStore(Store store);
|
||||
|
||||
Store checkStoreNameUnique(@Param("storeCode") String storeCode,@Param("storeId") Long storeId);
|
||||
|
||||
int deleteStoreById(Long storeId);
|
||||
|
||||
int updateStore(Store store);
|
||||
|
||||
void deleteUserStore(Long userId);
|
||||
|
||||
int insertUserStore(@Param("userId") Long userId, @Param("storeIds") Long[] storeIds);
|
||||
|
||||
void deleteStoreUser(Long storeId);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.ruoyi.web.mapper;
|
||||
|
||||
|
||||
import com.ruoyi.web.vo.UserStoreVo;
|
||||
|
||||
/**
|
||||
* 用户关联门店
|
||||
*/
|
||||
public interface UserStoreMapper {
|
||||
|
||||
UserStoreVo getUserStoreWithStores(String userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi.web.service;
|
||||
|
||||
import com.ruoyi.web.domain.Brand;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BrandService {
|
||||
|
||||
// 获取品牌树(一级品牌包含子品牌)
|
||||
List<Brand> getBrandTree();
|
||||
|
||||
// 添加品牌
|
||||
int addBrand(Brand brand);
|
||||
|
||||
int updateBrand(Brand brand);
|
||||
|
||||
// 删除品牌
|
||||
void deleteBrand(Long id);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.ruoyi.web.service;
|
||||
|
||||
import com.ruoyi.web.domain.Product;
|
||||
import com.ruoyi.web.dto.BatchStoreDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 服务层
|
||||
*
|
||||
*/
|
||||
public interface ProductService {
|
||||
/**
|
||||
* 分页查询所有商品
|
||||
* @param product
|
||||
* @return
|
||||
*/
|
||||
List<Product> selectList(Product product);
|
||||
|
||||
/**
|
||||
* 查询商品编码是否存在
|
||||
* @param product
|
||||
* @return
|
||||
*/
|
||||
boolean checkProductCodeUnique(Product product);
|
||||
|
||||
int insertProductStore(Product product);
|
||||
|
||||
int importProduct(List<Product> productList,Integer storeId);
|
||||
|
||||
Product selectProductBarCode(Long id);
|
||||
|
||||
int deleteProductById(Long id);
|
||||
|
||||
int updateProduct(Product product);
|
||||
|
||||
int batchProductById(BatchStoreDTO dto);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.ruoyi.web.service;
|
||||
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import com.ruoyi.web.vo.UserStoreVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门店 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface StoreService {
|
||||
|
||||
/**
|
||||
* 分页查询门店
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
List<Store> selectList(Store store);
|
||||
|
||||
/**
|
||||
* 新增门店信息
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
int insertStore(Store store);
|
||||
|
||||
/**
|
||||
* 查看门店编码是否存在
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
boolean checkStoreNameUnique(Store store);
|
||||
|
||||
/**
|
||||
* 删除门店
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
int deleteStoreById(Long storeId);
|
||||
|
||||
/**
|
||||
* 修改部门信息
|
||||
* @param store
|
||||
* @return
|
||||
*/
|
||||
int updateStore(Store store);
|
||||
|
||||
/**
|
||||
* 用户关联门店
|
||||
* @param userId
|
||||
* @param storeIds
|
||||
* @return
|
||||
*/
|
||||
int insertUserStores(Long userId, Long[] storeIds);
|
||||
|
||||
UserStoreVo getUserStore(String userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.ruoyi.web.service.impl;
|
||||
|
||||
import com.ruoyi.web.domain.Brand;
|
||||
import com.ruoyi.web.mapper.BrandMapper;
|
||||
import com.ruoyi.web.service.BrandService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class BrandServiceImpl implements BrandService {
|
||||
|
||||
@Autowired
|
||||
private BrandMapper brandMapper;
|
||||
|
||||
@Override
|
||||
public List<Brand> getBrandTree() {
|
||||
// 1. 获取所有一级品牌
|
||||
List<Brand> rootBrands = brandMapper.selectRootBrands();
|
||||
|
||||
// 2. 为每个一级品牌设置子品牌
|
||||
for (Brand rootBrand : rootBrands) {
|
||||
List<Brand> children = brandMapper.selectByParentId(rootBrand.getId());
|
||||
rootBrand.setChildren(children);
|
||||
}
|
||||
return rootBrands;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int addBrand(Brand brand) {
|
||||
// 如果是二级品牌,检查父品牌是否存在
|
||||
if (brand.getParentId() != null && brand.getParentId() != 0) {
|
||||
Brand parent = brandMapper.selectById(brand.getParentId());
|
||||
if (parent == null || parent.getParentId() != 0) {
|
||||
throw new RuntimeException("父品牌不存在或不是一级品牌");
|
||||
}
|
||||
} else {
|
||||
brand.setParentId(0L); // 确保一级品牌parentId=0
|
||||
}
|
||||
return brandMapper.insert(brand);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int updateBrand(Brand brand) {
|
||||
return brandMapper.update(brand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBrand(Long id) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.ruoyi.web.service.impl;
|
||||
|
||||
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.web.domain.Product;
|
||||
import com.ruoyi.web.dto.BatchStoreDTO;
|
||||
import com.ruoyi.web.mapper.ProductMapper;
|
||||
import com.ruoyi.web.service.ProductService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 服务层实现
|
||||
*/
|
||||
@Service
|
||||
public class ProductServiceImpl implements ProductService {
|
||||
@Resource
|
||||
private ProductMapper productMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public List<Product> selectList(Product product) {
|
||||
return productMapper.selectList(product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkProductCodeUnique(Product product) {
|
||||
if (product == null || StringUtils.isBlank(product.getProductBarCode())) {
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
Long id = product.getId() == null ? -1L : product.getId();
|
||||
product.setId(id);
|
||||
Product product1 = productMapper.checkProductCodeUnique(product);
|
||||
return product1 != null ? UserConstants.NOT_UNIQUE : UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertProductStore(Product product) {
|
||||
return productMapper.insertProductStore(product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int importProduct(List<Product> productList, Integer storeId) {
|
||||
for (Product product : productList) {
|
||||
product.setStoreId(storeId);
|
||||
//判断同条形码是否存在,区分不同门店
|
||||
if (!checkProductCodeUnique(product)) {
|
||||
productMapper.updateProductBarCode(product);
|
||||
} else {
|
||||
productMapper.insertProductStore(product);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Product selectProductBarCode(Long id) {
|
||||
return productMapper.selectProductBarCode(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteProductById(Long id) {
|
||||
return productMapper.deleteProductById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateProduct(Product product) {
|
||||
return productMapper.updateProduct(product);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchProductById(BatchStoreDTO dto) {
|
||||
if (dto.getIds() == null || dto.getIds().isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return productMapper.batchProductById(dto.getIds());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.ruoyi.web.service.impl;
|
||||
|
||||
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.web.domain.Store;
|
||||
import com.ruoyi.web.mapper.StoreMapper;
|
||||
import com.ruoyi.web.mapper.UserStoreMapper;
|
||||
import com.ruoyi.web.service.StoreService;
|
||||
import com.ruoyi.web.vo.UserStoreVo;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 门店 服务层实现
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class StoreServiceImpl implements StoreService {
|
||||
|
||||
@Resource
|
||||
private StoreMapper storeMapper;
|
||||
|
||||
@Resource
|
||||
private UserStoreMapper userStoreMapper;
|
||||
|
||||
@Override
|
||||
public List<Store> selectList(Store store) {
|
||||
return storeMapper.selectList(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertStore(Store store) {
|
||||
return storeMapper.insertStore(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkStoreNameUnique(Store store) {
|
||||
if (store == null || StringUtils.isBlank(store.getStoreCode())) {
|
||||
return UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
// 获取当前门店ID(新增时为-1)
|
||||
Long storeId = store.getStoreId() == null ? -1L : store.getStoreId();
|
||||
|
||||
// 查询除自身外是否有相同编码的门店
|
||||
Store existStore = storeMapper.checkStoreNameUnique(
|
||||
store.getStoreCode(),
|
||||
storeId
|
||||
);
|
||||
|
||||
// 如果查询到记录,说明编码已被其他门店使用
|
||||
return existStore != null ? UserConstants.NOT_UNIQUE : UserConstants.UNIQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteStoreById(Long storeId) {
|
||||
storeMapper.deleteStoreUser(storeId);
|
||||
return storeMapper.deleteStoreById(storeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateStore(Store store) {
|
||||
return storeMapper.updateStore(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertUserStores(Long userId, Long[] storeIds) {
|
||||
//先把直接这个用户关联的门店删除掉
|
||||
storeMapper.deleteUserStore(userId);
|
||||
//再新增新的用户关联门店
|
||||
if (storeIds != null && storeIds.length > 0) {
|
||||
return storeMapper.insertUserStore(userId, storeIds);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserStoreVo getUserStore(String userId) {
|
||||
return userStoreMapper.getUserStoreWithStores(userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.ruoyi.web.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class StoreVo {
|
||||
|
||||
/**
|
||||
* 门店ID
|
||||
*/
|
||||
private Long storeId;
|
||||
|
||||
/**
|
||||
* 门店名称
|
||||
*/
|
||||
private String storeName;
|
||||
|
||||
/**
|
||||
* 门店编码
|
||||
*/
|
||||
private String storeCode;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.ruoyi.web.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class UserStoreVo {
|
||||
|
||||
private Long userId; //用户id
|
||||
private List<StoreVo> stores; // 门店对象列表
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://193.112.94.36:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: ry-vue
|
||||
password: yKSYaNzYifKFNHHj
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
minIdle: 10
|
||||
# 最大连接池数量
|
||||
maxActive: 20
|
||||
# 配置获取连接等待超时的时间
|
||||
maxWait: 60000
|
||||
# 配置连接超时时间
|
||||
connectTimeout: 30000
|
||||
# 配置网络超时时间
|
||||
socketTimeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
timeBetweenEvictionRunsMillis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
maxEvictableIdleTimeMillis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validationQuery: SELECT 1 FROM DUAL
|
||||
testWhileIdle: true
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
webStatFilter:
|
||||
enabled: true
|
||||
statViewServlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: true
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
# 项目相关配置
|
||||
ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 3.9.1
|
||||
# 版权年份
|
||||
copyrightYear: 2026
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: /home/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
captchaType: math
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8081
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
# 连接数满后的排队数,默认为100
|
||||
accept-count: 1000
|
||||
threads:
|
||||
# tomcat最大线程数,默认为200
|
||||
max: 800
|
||||
# Tomcat启动初始化的线程数,默认值10
|
||||
min-spare: 100
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.ruoyi: debug
|
||||
org.springframework: warn
|
||||
|
||||
# 用户配置
|
||||
user:
|
||||
password:
|
||||
# 密码最大错误次数
|
||||
maxRetryCount: 5
|
||||
# 密码锁定时间(默认10分钟)
|
||||
lockTime: 10
|
||||
|
||||
# Spring配置
|
||||
spring:
|
||||
# 资源信息
|
||||
messages:
|
||||
# 国际化资源文件路径
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
active: druid
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
# 热部署开关
|
||||
enabled: true
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: 193.112.94.36
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
database: 0
|
||||
# 密码
|
||||
password: 123456
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 8
|
||||
# 连接池的最大数据库连接数
|
||||
max-active: 8
|
||||
# #连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
|
||||
# token配置
|
||||
token:
|
||||
# 令牌自定义标识
|
||||
header: Authorization
|
||||
# 令牌密钥
|
||||
secret: abcdefghijklmnopqrstuvwxyz
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
# MyBatis配置
|
||||
mybatis:
|
||||
# 搜索指定包别名
|
||||
typeAliasesPackage: com.ruoyi.**.domain
|
||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 加载全局的配置文件
|
||||
configLocation: classpath:mybatis/mybatis-config.xml
|
||||
|
||||
# PageHelper分页插件
|
||||
pagehelper:
|
||||
helperDialect: mysql
|
||||
supportMethodsArguments: true
|
||||
params: count=countSql
|
||||
|
||||
# Swagger配置
|
||||
swagger:
|
||||
# 是否开启swagger
|
||||
enabled: true
|
||||
# 请求前缀
|
||||
pathMapping: /dev-api
|
||||
|
||||
# 防盗链配置
|
||||
referer:
|
||||
# 防盗链开关
|
||||
enabled: false
|
||||
# 允许的域名列表
|
||||
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
Application Version: ${ruoyi.version}
|
||||
Spring Boot Version: ${spring-boot.version}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// _ooOoo_ //
|
||||
// o8888888o //
|
||||
// 88" . "88 //
|
||||
// (| ^_^ |) //
|
||||
// O\ = /O //
|
||||
// ____/`---'\____ //
|
||||
// .' \\| |// `. //
|
||||
// / \\||| : |||// \ //
|
||||
// / _||||| -:- |||||- \ //
|
||||
// | | \\\ - /// | | //
|
||||
// | \_| ''\---/'' | | //
|
||||
// \ .-\__ `-` ___/-. / //
|
||||
// ___`. .' /--.--\ `. . ___ //
|
||||
// ."" '< `.___\_<|>_/___.' >'"". //
|
||||
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
|
||||
// \ \ `-. \_ __\ /__ _/ .-` / / //
|
||||
// ========`-.____`-.___\_____/___.-`____.-'======== //
|
||||
// `=---=' //
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
|
||||
// 佛祖保佑 永不宕机 永无BUG //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#错误消息
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
user.not.exists=用户不存在/密码错误
|
||||
user.password.not.match=用户不存在/密码错误
|
||||
user.password.retry.limit.count=密码输入错误{0}次
|
||||
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
|
||||
user.password.delete=对不起,您的账号已被删除
|
||||
user.blocked=用户已封禁,请联系管理员
|
||||
role.blocked=角色已封禁,请联系管理员
|
||||
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
||||
user.logout.success=退出成功
|
||||
|
||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||
|
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
|
||||
user.password.not.valid=* 5-50个字符
|
||||
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
|
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符
|
||||
|
||||
##权限
|
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 日志存放路径 -->
|
||||
<property name="log.path" value="./logs" />
|
||||
<!-- 日志输出格式 -->
|
||||
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||
|
||||
<!-- 控制台输出 -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统日志输出 -->
|
||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-info.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>INFO</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-error.log</file>
|
||||
<!-- 循环政策:基于时间创建日志文件 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 日志文件名格式 -->
|
||||
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<!-- 过滤的级别 -->
|
||||
<level>ERROR</level>
|
||||
<!-- 匹配时的操作:接收(记录) -->
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 用户访问日志输出 -->
|
||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/sys-user.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 按天回滚 daily -->
|
||||
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<!-- 日志最大的历史 60天 -->
|
||||
<maxHistory>60</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${log.pattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 系统模块日志级别控制 -->
|
||||
<logger name="com.ruoyi" level="info" />
|
||||
<!-- Spring日志级别控制 -->
|
||||
<logger name="org.springframework" level="warn" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
<!--系统操作日志-->
|
||||
<root level="info">
|
||||
<appender-ref ref="file_info" />
|
||||
<appender-ref ref="file_error" />
|
||||
</root>
|
||||
|
||||
<!--系统用户操作日志-->
|
||||
<logger name="sys-user" level="info">
|
||||
<appender-ref ref="sys-user"/>
|
||||
</logger>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.web.mapper.BrandMapper">
|
||||
<resultMap id="BaseResultMap" type="com.ruoyi.web.domain.Brand">
|
||||
<id property="id" column="id"/>
|
||||
<result column="parent_id" property="parentId" />
|
||||
<result column="brand_name" property="brandName" />
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="update_time" property="updateTime" />
|
||||
<result column="create_by" property="createBy" />
|
||||
<result column="update_by" property="updateBy" />
|
||||
<result column="store_id" property="storeId" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
<!-- 查询所有品牌 -->
|
||||
<select id="selectAll" resultMap="BaseResultMap">
|
||||
SELECT *
|
||||
FROM brand
|
||||
ORDER BY parent_id, sort_order
|
||||
</select>
|
||||
|
||||
<select id="selectRootBrands" resultMap="BaseResultMap">
|
||||
SELECT *
|
||||
FROM mall_brand
|
||||
WHERE parent_id = 0 and del_flag = '0'
|
||||
</select>
|
||||
|
||||
<!-- 根据父ID查询子品牌 -->
|
||||
<select id="selectByParentId" resultMap="BaseResultMap">
|
||||
SELECT *
|
||||
FROM mall_brand
|
||||
WHERE parent_id = #{parentId}
|
||||
</select>
|
||||
|
||||
<!-- 根据ID查询品牌 -->
|
||||
<select id="selectById" resultMap="BaseResultMap" parameterType="long">
|
||||
SELECT id, parent_id, brand_name
|
||||
FROM mall_brand
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insert" parameterType="Brand">
|
||||
insert into mall_brand (
|
||||
<if test="parentId != null">parent_id,</if>
|
||||
<if test="brandName != null and brandName != ''">brand_name,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="storeId != null">store_id,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="parentId != null">#{parentId},</if>
|
||||
<if test="brandName != null and brandName != ''">#{brandName},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="storeId != null">#{storeId},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="update">
|
||||
UPDATE mall_brand
|
||||
SET brand_name = #{brandName}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<!-- 删除品牌 -->
|
||||
<delete id="delete">
|
||||
DELETE
|
||||
FROM brand
|
||||
WHERE id = #{id}
|
||||
</delete>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.web.mapper.ProductMapper">
|
||||
|
||||
<resultMap type="Product" id="MallProductResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="productCode" column="product_code"/>
|
||||
<result property="productName" column="product_name"/>
|
||||
<result property="productDesc" column="product_desc"/>
|
||||
<result property="mainImage" column="main_image"/>
|
||||
<result property="storePrice" column="store_price"/>
|
||||
<result property="costPrice" column="cost_price"/>
|
||||
<result property="storeId" column="store_id"/>
|
||||
<result property="stockQuantity" column="stock_quantity"/>
|
||||
<result property="soldQuantity" column="sold_quantity"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="productBarCode" column="product_bar_code"/>
|
||||
<result property="shelfCode" column="shelf_code"/>
|
||||
<result property="shelfLife" column="shelf_life"/>
|
||||
<result property="approaching" column="approaching"/>
|
||||
<result property="productionDate" column="production_date"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectCommodityVo">
|
||||
select id,
|
||||
product_code,
|
||||
product_name,
|
||||
product_desc,
|
||||
main_image,
|
||||
store_price,
|
||||
cost_price,
|
||||
store_id,
|
||||
stock_quantity,
|
||||
sold_quantity,
|
||||
status,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
remark,
|
||||
product_bar_code,
|
||||
shelf_code,
|
||||
shelf_life,
|
||||
production_date,
|
||||
approaching
|
||||
from mall_product_store
|
||||
</sql>
|
||||
|
||||
|
||||
<select id="selectList" parameterType="Product" resultMap="MallProductResult">
|
||||
<include refid="selectCommodityVo"/>
|
||||
<where>
|
||||
del_flag = '0'
|
||||
<if test="productBarCode != null and productBarCode != ''">
|
||||
AND product_bar_code = #{productBarCode}
|
||||
</if>
|
||||
<if test="productName != null and productName != ''">
|
||||
AND product_name like concat('%', #{productName}, '%')
|
||||
</if>
|
||||
<if test="storeId != null">
|
||||
AND store_id = #{storeId}
|
||||
</if>
|
||||
|
||||
<!-- 库存大于0条件 -->
|
||||
AND stock_quantity > 0
|
||||
|
||||
<if test="status != null and status != '' ">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="checkProductCodeUnique" resultType="com.ruoyi.web.domain.Product">
|
||||
<include refid="selectCommodityVo"/>
|
||||
where product_bar_code=#{productBarCode} and del_flag = '0' and store_id = #{storeId}
|
||||
<if test="id != null">
|
||||
AND id != #{id}
|
||||
</if>
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectProductBarCode" parameterType="Product" resultMap="MallProductResult">
|
||||
<include refid="selectCommodityVo"/>
|
||||
where id=#{id} and del_flag = '0'
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertProductStore" parameterType="Product">
|
||||
insert into mall_product_store (
|
||||
<if test="productCode != null and productCode != ''">product_code,</if>
|
||||
<if test="productName != null and productName != ''">product_name,</if>
|
||||
<if test="productDesc != null and productDesc != ''">product_desc,</if>
|
||||
<if test="mainImage != null and mainImage != ''">main_image,</if>
|
||||
<if test="storePrice != null and storePrice != ''">store_price,</if>
|
||||
<if test="costPrice != null and costPrice != ''">cost_price,</if>
|
||||
<if test="originalPrice != null and originalPrice != ''">original_price,</if>
|
||||
<if test="storeId != null and storeId != ''">store_id,</if>
|
||||
<if test="stockQuantity != null and stockQuantity != ''">stock_quantity,</if>
|
||||
<if test="soldQuantity != null and soldQuantity != ''">sold_quantity,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="remark != null and remark != ''">remark,</if>
|
||||
<if test="shelfCode != null and shelfCode != ''">shelf_code,</if>
|
||||
<if test="productBarCode != null and productBarCode != ''">product_bar_code,</if>
|
||||
<if test="shelfLife != null and shelfLife != ''">shelf_life,</if>
|
||||
<if test="productionDate != null and productionDate != ''">production_date,</if>
|
||||
<if test="approaching != null">approaching,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="productCode != null and productCode != ''">#{productCode},</if>
|
||||
<if test="productName != null and productName != ''">#{productName},</if>
|
||||
<if test="productDesc != null and productDesc != ''">#{productDesc},</if>
|
||||
<if test="mainImage != null and mainImage != ''">#{mainImage},</if>
|
||||
<if test="storePrice != null and storePrice != ''">#{storePrice},</if>
|
||||
<if test="costPrice != null and costPrice != ''">#{costPrice},</if>
|
||||
<if test="originalPrice != null and originalPrice != ''">#{originalPrice},</if>
|
||||
<if test="storeId != null and storeId != ''">#{storeId},</if>
|
||||
<if test="stockQuantity != null and stockQuantity != ''">#{stockQuantity},</if>
|
||||
<if test="soldQuantity != null and soldQuantity != ''">#{soldQuantity},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="remark != null and remark != ''">#{remark},</if>
|
||||
<if test="shelfCode != null and shelfCode != ''">#{shelfCode},</if>
|
||||
<if test="productBarCode != null and productBarCode != ''">#{productBarCode},</if>
|
||||
<if test="shelfLife != null and shelfLife != ''">#{shelfLife},</if>
|
||||
<if test="productionDate != null and productionDate != ''">#{productionDate},</if>
|
||||
<if test="approaching != null">#{approaching},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="updateProduct">
|
||||
update mall_product_store
|
||||
<set>
|
||||
<if test="productCode != null and productCode != ''">product_code = #{productCode},</if>
|
||||
<if test="productName != null and productName != ''">product_name = #{productName},</if>
|
||||
<if test="productDesc != null and productDesc != ''">product_desc = #{productDesc},</if>
|
||||
<if test="mainImage != null and mainImage != ''">main_image = #{mainImage},</if>
|
||||
<if test="storePrice != null and storePrice != ''">store_price = #{storePrice},</if>
|
||||
<if test="costPrice != null and costPrice != ''">cost_price = #{costPrice},</if>
|
||||
<if test="stockQuantity != null and stockQuantity != ''">stock_quantity = #{stockQuantity},</if>
|
||||
<if test="soldQuantity != null and soldQuantity != ''">sold_quantity = #{soldQuantity},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="shelfCode != null and shelfCode != ''">shelf_code = #{shelfCode},</if>
|
||||
<if test="productBarCode != null and productBarCode != ''">product_bar_code = #{productBarCode},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="shelfLife != null">shelf_life = #{shelfLife},</if>
|
||||
<if test="productionDate != null and productionDate != ''">production_date = #{productionDate},</if>
|
||||
<if test="approaching != null">approaching = #{approaching},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateProductBarCode">
|
||||
update mall_product_store
|
||||
<set>
|
||||
<if test="productCode != null and productCode != ''">product_code = #{productCode},</if>
|
||||
<if test="productName != null and productName != ''">product_name = #{productName},</if>
|
||||
<if test="productDesc != null and productDesc != ''">product_desc = #{productDesc},</if>
|
||||
<if test="mainImage != null and mainImage != ''">main_image = #{mainImage},</if>
|
||||
<if test="storePrice != null and storePrice != ''">store_price = #{storePrice},</if>
|
||||
<if test="costPrice != null and costPrice != ''">cost_price = #{costPrice},</if>
|
||||
<if test="stockQuantity != null and stockQuantity != ''">stock_quantity = #{stockQuantity},</if>
|
||||
<if test="soldQuantity != null and soldQuantity != ''">sold_quantity = #{soldQuantity},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="shelfCode != null and shelfCode != ''">shelf_code = #{shelfCode},</if>
|
||||
<if test="productBarCode != null and productBarCode != ''">product_bar_code = #{productBarCode},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="shelfLife != null">shelf_life = #{shelfLife},</if>
|
||||
<if test="productionDate != null and productionDate != ''">production_date = #{productionDate},</if>
|
||||
<if test="approaching != null">approaching = #{approaching},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where product_bar_code = #{productBarCode}
|
||||
</update>
|
||||
|
||||
<delete id="deleteConfigById" parameterType="Long">
|
||||
delete
|
||||
from sys_config
|
||||
where config_id = #{configId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteConfigByIds" parameterType="Long">
|
||||
delete from sys_config where config_id in
|
||||
<foreach item="configId" collection="array" open="(" separator="," close=")">
|
||||
#{configId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteProductById">
|
||||
update mall_product_store
|
||||
set del_flag = '2'
|
||||
where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="batchProductById">
|
||||
UPDATE mall_product_store
|
||||
SET del_flag = 2
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.web.mapper.StoreMapper">
|
||||
|
||||
<resultMap type="Store" id="MallStoreResult">
|
||||
<id property="storeId" column="store_id"/>
|
||||
<result property="storeName" column="store_name"/>
|
||||
<result property="storeCode" column="store_code"/>
|
||||
<result property="province" column="province"/>
|
||||
<result property="city" column="city"/>
|
||||
<result property="district" column="district"/>
|
||||
<result property="fullAddress" column="full_address"/>
|
||||
<result property="contactPhone" column="contact_phone"/>
|
||||
<result property="storeManager" column="store_manager"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
|
||||
|
||||
<sql id="selectStoreVo">
|
||||
select store_id,
|
||||
store_name,
|
||||
store_code,
|
||||
province,
|
||||
city,
|
||||
district,
|
||||
full_address,
|
||||
contact_phone,
|
||||
store_manager,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
remark
|
||||
from mall_store
|
||||
</sql>
|
||||
|
||||
|
||||
<select id="selectList" parameterType="Store" resultMap="MallStoreResult">
|
||||
<include refid="selectStoreVo"/>
|
||||
<where>
|
||||
del_flag = '0'
|
||||
<if test="storeName != null and storeName != ''">
|
||||
AND store_name = #{storeName}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="checkStoreNameUnique" resultType="com.ruoyi.web.domain.Store">
|
||||
<include refid="selectStoreVo"/>
|
||||
where store_code=#{storeCode} and del_flag = '0'
|
||||
<if test="storeId != null">
|
||||
AND store_id != #{storeId}
|
||||
</if>
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertStore" parameterType="Store">
|
||||
insert into mall_store (
|
||||
<if test="storeName != null and storeName != '' ">store_name,</if>
|
||||
<if test="storeCode != null and storeCode != '' ">store_code,</if>
|
||||
<if test="province != null and province != '' ">province,</if>
|
||||
<if test="city != null and city != '' ">city,</if>
|
||||
<if test="district != null and city != '' ">district,</if>
|
||||
<if test="fullAddress != null and fullAddress != '' ">full_address,</if>
|
||||
<if test="contactPhone != null and contactPhone != '' ">contact_phone,</if>
|
||||
<if test="storeManager != null and storeManager != '' ">store_manager,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="remark != null and remark != ''">remark,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="storeName != null and storeName != ''">#{storeName},</if>
|
||||
<if test="storeCode != null and storeCode != ''">#{storeCode},</if>
|
||||
<if test="province != null and province != ''">#{province},</if>
|
||||
<if test="city != null and city != ''">#{city},</if>
|
||||
<if test="district != null and district != ''">#{district},</if>
|
||||
<if test="fullAddress != null and fullAddress != ''">#{fullAddress},</if>
|
||||
<if test="contactPhone != null and contactPhone != ''">#{contactPhone},</if>
|
||||
<if test="storeManager != null and storeManager != ''">#{storeManager},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="remark != null and remark != ''">#{remark},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="insertUserStore">
|
||||
INSERT INTO mall_user_store(user_id, store_id)
|
||||
VALUES
|
||||
<foreach collection="storeIds" item="storeId" separator=",">
|
||||
(#{userId}, #{storeId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="updateStore">
|
||||
update mall_store
|
||||
<set>
|
||||
<if test="storeName != null and storeName != ''">store_name = #{storeName},</if>
|
||||
<if test="storeCode != null and storeCode != ''">store_code = #{storeCode},</if>
|
||||
<if test="province != null and province != ''">province = #{province},</if>
|
||||
<if test="city != null and city != ''">city = #{city},</if>
|
||||
<if test="district != null and district != ''">district = #{district},</if>
|
||||
<if test="fullAddress != null and fullAddress != ''">full_address = #{fullAddress},</if>
|
||||
<if test="contactPhone != null and contactPhone != ''">contact_phone = #{contactPhone},</if>
|
||||
<if test="storeManager != null and storeManager != ''">store_manager = #{storeManager},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
where store_id = #{storeId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteStoreById">
|
||||
update mall_store
|
||||
set del_flag = '2'
|
||||
where store_id = #{storeId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteUserStore">
|
||||
delete
|
||||
from mall_user_store
|
||||
where user_id = #{userId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteStoreUser">
|
||||
delete
|
||||
from mall_user_store
|
||||
where store_id = #{storeId}
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.web.mapper.UserStoreMapper">
|
||||
|
||||
<resultMap id="userStoreWithStoresMap" type="com.ruoyi.web.vo.UserStoreVo">
|
||||
<id property="userId" column="user_id"/>
|
||||
<collection property="stores" ofType="com.ruoyi.web.vo.StoreVo">
|
||||
<result property="storeName" column="store_name"/>
|
||||
<result property="storeId" column="store_id"/>
|
||||
<result property="storeCode" column="store_code"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
<select id="getUserStoreWithStores" resultMap="userStoreWithStoresMap">
|
||||
SELECT mus.user_id,
|
||||
s.store_id,
|
||||
s.store_name,
|
||||
s.store_code
|
||||
FROM mall_user_store mus
|
||||
LEFT JOIN mall_store s ON mus.store_id = s.store_id
|
||||
WHERE mus.user_id = #{userId}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<!-- 全局参数 -->
|
||||
<settings>
|
||||
<!-- 使全局的映射器启用或禁用缓存 -->
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<!-- 允许JDBC 支持自动生成主键 -->
|
||||
<setting name="useGeneratedKeys" value="true" />
|
||||
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" />
|
||||
<!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||
<setting name="logImpl" value="SLF4J" />
|
||||
<!-- 使用驼峰命名法转换字段 -->
|
||||
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
</configuration>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
#app {
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
.chromeframe {
|
||||
margin: 0.2em 0;
|
||||
|
|
|
|||
|
|
@ -1,136 +1,136 @@
|
|||
'use strict'
|
||||
const path = require('path')
|
||||
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
const CompressionPlugin = require('compression-webpack-plugin')
|
||||
|
||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
||||
|
||||
const baseUrl = 'http://localhost:8080' // 后端接口
|
||||
|
||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||
|
||||
// vue.config.js 配置说明
|
||||
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
|
||||
// 这里只列一部分,具体配置参考文档
|
||||
module.exports = {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
||||
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
||||
outputDir: 'dist',
|
||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||
assetsDir: 'static',
|
||||
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
|
||||
productionSourceMap: false,
|
||||
transpileDependencies: ['quill'],
|
||||
// webpack-dev-server 相关配置
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: port,
|
||||
open: true,
|
||||
proxy: {
|
||||
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
||||
[process.env.VUE_APP_BASE_API]: {
|
||||
target: baseUrl,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
},
|
||||
// springdoc proxy
|
||||
'^/v3/api-docs/(.*)': {
|
||||
target: baseUrl,
|
||||
changeOrigin: true
|
||||
}
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
sassOptions: { outputStyle: "expanded" }
|
||||
}
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
name: name,
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
new CompressionPlugin({
|
||||
cache: false, // 不启用文件缓存
|
||||
test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式
|
||||
filename: '[path][base].gz[query]', // 压缩后的文件名
|
||||
algorithm: 'gzip', // 使用gzip压缩
|
||||
minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩
|
||||
deleteOriginalAssets: false // 压缩后删除原文件
|
||||
})
|
||||
],
|
||||
},
|
||||
chainWebpack(config) {
|
||||
config.plugins.delete('preload') // TODO: need test
|
||||
config.plugins.delete('prefetch') // TODO: need test
|
||||
|
||||
// set svg-sprite-loader
|
||||
config.module
|
||||
.rule('svg')
|
||||
.exclude.add(resolve('src/assets/icons'))
|
||||
.end()
|
||||
config.module
|
||||
.rule('icons')
|
||||
.test(/\.svg$/)
|
||||
.include.add(resolve('src/assets/icons'))
|
||||
.end()
|
||||
.use('svg-sprite-loader')
|
||||
.loader('svg-sprite-loader')
|
||||
.options({
|
||||
symbolId: 'icon-[name]'
|
||||
})
|
||||
.end()
|
||||
|
||||
config.when(process.env.NODE_ENV !== 'development', config => {
|
||||
config
|
||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||
.after('html')
|
||||
.use('script-ext-html-webpack-plugin', [{
|
||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/
|
||||
}])
|
||||
.end()
|
||||
|
||||
config.optimization.splitChunks({
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
libs: {
|
||||
name: 'chunk-libs',
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 10,
|
||||
chunks: 'initial' // only package third parties that are initially dependent
|
||||
},
|
||||
elementUI: {
|
||||
name: 'chunk-elementUI', // split elementUI into a single package
|
||||
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
|
||||
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||
},
|
||||
commons: {
|
||||
name: 'chunk-commons',
|
||||
test: resolve('src/components'), // can customize your rules
|
||||
minChunks: 3, // minimum common number
|
||||
priority: 5,
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
})
|
||||
config.optimization.runtimeChunk('single')
|
||||
})
|
||||
}
|
||||
}
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
const CompressionPlugin = require('compression-webpack-plugin')
|
||||
|
||||
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
|
||||
|
||||
const baseUrl = 'http://193.112.94.36:8080' // 后端接口
|
||||
|
||||
const port = process.env.port || process.env.npm_config_port || 80 // 端口
|
||||
|
||||
// vue.config.js 配置说明
|
||||
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
|
||||
// 这里只列一部分,具体配置参考文档
|
||||
module.exports = {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
|
||||
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
||||
outputDir: 'dist',
|
||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||
assetsDir: 'static',
|
||||
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
|
||||
productionSourceMap: false,
|
||||
transpileDependencies: ['quill'],
|
||||
// webpack-dev-server 相关配置
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: 8087,
|
||||
open: true,
|
||||
proxy: {
|
||||
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
||||
[process.env.VUE_APP_BASE_API]: {
|
||||
target: baseUrl,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
}
|
||||
},
|
||||
// springdoc proxy
|
||||
'^/v3/api-docs/(.*)': {
|
||||
target: baseUrl,
|
||||
changeOrigin: true
|
||||
}
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
sassOptions: { outputStyle: "expanded" }
|
||||
}
|
||||
}
|
||||
},
|
||||
configureWebpack: {
|
||||
name: name,
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
new CompressionPlugin({
|
||||
cache: false, // 不启用文件缓存
|
||||
test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式
|
||||
filename: '[path][base].gz[query]', // 压缩后的文件名
|
||||
algorithm: 'gzip', // 使用gzip压缩
|
||||
minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩
|
||||
deleteOriginalAssets: false // 压缩后删除原文件
|
||||
})
|
||||
],
|
||||
},
|
||||
chainWebpack(config) {
|
||||
config.plugins.delete('preload') // TODO: need test
|
||||
config.plugins.delete('prefetch') // TODO: need test
|
||||
|
||||
// set svg-sprite-loader
|
||||
config.module
|
||||
.rule('svg')
|
||||
.exclude.add(resolve('src/assets/icons'))
|
||||
.end()
|
||||
config.module
|
||||
.rule('icons')
|
||||
.test(/\.svg$/)
|
||||
.include.add(resolve('src/assets/icons'))
|
||||
.end()
|
||||
.use('svg-sprite-loader')
|
||||
.loader('svg-sprite-loader')
|
||||
.options({
|
||||
symbolId: 'icon-[name]'
|
||||
})
|
||||
.end()
|
||||
|
||||
config.when(process.env.NODE_ENV !== 'development', config => {
|
||||
config
|
||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||
.after('html')
|
||||
.use('script-ext-html-webpack-plugin', [{
|
||||
// `runtime` must same as runtimeChunk name. default is `runtime`
|
||||
inline: /runtime\..*\.js$/
|
||||
}])
|
||||
.end()
|
||||
|
||||
config.optimization.splitChunks({
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
libs: {
|
||||
name: 'chunk-libs',
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 10,
|
||||
chunks: 'initial' // only package third parties that are initially dependent
|
||||
},
|
||||
elementUI: {
|
||||
name: 'chunk-elementUI', // split elementUI into a single package
|
||||
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
|
||||
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||
},
|
||||
commons: {
|
||||
name: 'chunk-commons',
|
||||
test: resolve('src/components'), // can customize your rules
|
||||
minChunks: 3, // minimum common number
|
||||
priority: 5,
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
})
|
||||
config.optimization.runtimeChunk('single')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue