Compare commits
No commits in common. 'bf5bf7287fcd03159d74559174e08e1b80ef302d' and '714d9dc244951e361bf48e0efdf3a49fb41b3a8f' have entirely different histories.
bf5bf7287f
...
714d9dc244
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "java",
|
|
||||||
"name": "Launch Java Program",
|
|
||||||
"request": "launch",
|
|
||||||
"mainClass": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "java",
|
|
||||||
"name": "Current File",
|
|
||||||
"request": "launch",
|
|
||||||
"mainClass": "${file}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 2023c204150af2d4a5f41485e12868d123ad8e08
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
<?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>jeecg-boot-parent</artifactId>
|
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
|
||||||
<version>3.7.4</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>jeecg-module-computed</artifactId>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
|
||||||
<artifactId>jeecg-boot-base-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
|
||||||
<artifactId>jeecg-system-biz</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,180 +0,0 @@
|
|||||||
package org.jeecg.modules.calc.controller;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import org.jeecg.common.api.vo.Result;
|
|
||||||
import org.jeecg.common.system.query.QueryGenerator;
|
|
||||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
|
||||||
import org.jeecg.modules.calc.entity.Calc;
|
|
||||||
import org.jeecg.modules.calc.service.ICalcService;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
|
||||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
|
||||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
|
||||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
|
||||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
|
||||||
import org.jeecg.common.system.base.controller.JeecgController;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 算法计算器表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-05
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Tag(name="算法计算器表")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/calc/calc")
|
|
||||||
@Slf4j
|
|
||||||
public class CalcController extends JeecgController<Calc, ICalcService> {
|
|
||||||
@Autowired
|
|
||||||
private ICalcService calcService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分页列表查询
|
|
||||||
*
|
|
||||||
* @param calc
|
|
||||||
* @param pageNo
|
|
||||||
* @param pageSize
|
|
||||||
* @param req
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
//@AutoLog(value = "算法计算器表-分页列表查询")
|
|
||||||
@Operation(summary = "算法计算器表-分页列表查询")
|
|
||||||
@GetMapping(value = "/list")
|
|
||||||
public Result<IPage<Calc>> queryPageList(Calc calc,
|
|
||||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
|
||||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
|
||||||
HttpServletRequest req) {
|
|
||||||
QueryWrapper<Calc> queryWrapper = QueryGenerator.initQueryWrapper(calc, req.getParameterMap());
|
|
||||||
Page<Calc> page = new Page<Calc>(pageNo, pageSize);
|
|
||||||
IPage<Calc> pageList = calcService.page(page, queryWrapper);
|
|
||||||
return Result.OK(pageList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加
|
|
||||||
*
|
|
||||||
* @param calc
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@AutoLog(value = "算法计算器表-添加")
|
|
||||||
@Operation(summary = "算法计算器表-添加")
|
|
||||||
@RequiresPermissions("calc:computed:add")
|
|
||||||
@PostMapping(value = "/add")
|
|
||||||
public Result<String> add(@RequestBody Calc calc) {
|
|
||||||
calcService.save(calc);
|
|
||||||
return Result.OK("添加成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑
|
|
||||||
*
|
|
||||||
* @param calc
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@AutoLog(value = "算法计算器表-编辑")
|
|
||||||
@Operation(summary = "算法计算器表-编辑")
|
|
||||||
@RequiresPermissions("calc:computed:edit")
|
|
||||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
|
||||||
public Result<String> edit(@RequestBody Calc calc) {
|
|
||||||
calcService.updateById(calc);
|
|
||||||
return Result.OK("编辑成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过id删除
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@AutoLog(value = "算法计算器表-通过id删除")
|
|
||||||
@Operation(summary = "算法计算器表-通过id删除")
|
|
||||||
@RequiresPermissions("calc:computed:delete")
|
|
||||||
@DeleteMapping(value = "/delete")
|
|
||||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
|
||||||
calcService.removeById(id);
|
|
||||||
return Result.OK("删除成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除
|
|
||||||
*
|
|
||||||
* @param ids
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@AutoLog(value = "算法计算器表-批量删除")
|
|
||||||
@Operation(summary = "算法计算器表-批量删除")
|
|
||||||
@RequiresPermissions("calc:computed:deleteBatch")
|
|
||||||
@DeleteMapping(value = "/deleteBatch")
|
|
||||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
|
||||||
this.calcService.removeByIds(Arrays.asList(ids.split(",")));
|
|
||||||
return Result.OK("批量删除成功!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过id查询
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
//@AutoLog(value = "算法计算器表-通过id查询")
|
|
||||||
@Operation(summary = "算法计算器表-通过id查询")
|
|
||||||
@GetMapping(value = "/queryById")
|
|
||||||
public Result<Calc> queryById(@RequestParam(name="id",required=true) String id) {
|
|
||||||
Calc calc = calcService.getById(id);
|
|
||||||
if(calc==null) {
|
|
||||||
return Result.error("未找到对应数据");
|
|
||||||
}
|
|
||||||
return Result.OK(calc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出excel
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param calc
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("calc:computed:exportXls")
|
|
||||||
@RequestMapping(value = "/exportXls")
|
|
||||||
public ModelAndView exportXls(HttpServletRequest request, Calc calc) {
|
|
||||||
return super.exportXls(request, calc, Calc.class, "算法计算器表");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过excel导入数据
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@RequiresPermissions("calc:computed:importExcel")
|
|
||||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
|
||||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
|
||||||
return super.importExcel(request, response, Calc.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
package org.jeecg.modules.calc.entity;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
|
||||||
import org.jeecg.common.constant.ProvinceCityArea;
|
|
||||||
import org.jeecg.common.util.SpringContextUtils;
|
|
||||||
import lombok.Data;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
|
||||||
import org.jeecg.common.aspect.annotation.Dict;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 算法计算器表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-05
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("computed")
|
|
||||||
@Accessors(chain = true)
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
@Schema(description="算法计算器表")
|
|
||||||
public class Calc implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**主键*/
|
|
||||||
@TableId(type = IdType.ASSIGN_ID)
|
|
||||||
@Schema(description = "主键")
|
|
||||||
private String id;
|
|
||||||
/**创建人*/
|
|
||||||
@Schema(description = "创建人")
|
|
||||||
private String createBy;
|
|
||||||
/**创建日期*/
|
|
||||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Schema(description = "创建日期")
|
|
||||||
private Date createTime;
|
|
||||||
/**更新人*/
|
|
||||||
@Schema(description = "更新人")
|
|
||||||
private String updateBy;
|
|
||||||
/**更新日期*/
|
|
||||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Schema(description = "更新日期")
|
|
||||||
private Date updateTime;
|
|
||||||
/**所属部门*/
|
|
||||||
@Schema(description = "所属部门")
|
|
||||||
private String sysOrgCode;
|
|
||||||
/**算法名称*/
|
|
||||||
@Excel(name = "算法名称", width = 15)
|
|
||||||
@Schema(description = "算法名称")
|
|
||||||
private String name;
|
|
||||||
/**算法测试地址*/
|
|
||||||
@Excel(name = "算法测试地址", width = 15)
|
|
||||||
@Schema(description = "算法测试地址")
|
|
||||||
private String testlink;
|
|
||||||
/**算法编辑地址*/
|
|
||||||
@Excel(name = "算法编辑地址", width = 15)
|
|
||||||
@Schema(description = "算法编辑地址")
|
|
||||||
private String editlink;
|
|
||||||
/**算法id*/
|
|
||||||
@Excel(name = "算法id", width = 15)
|
|
||||||
@Schema(description = "算法id")
|
|
||||||
private String difyid;
|
|
||||||
/**算法编码*/
|
|
||||||
@Excel(name = "算法编码", width = 15)
|
|
||||||
@Schema(description = "算法编码")
|
|
||||||
private String computedCode;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package org.jeecg.modules.calc.mapper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import org.jeecg.modules.calc.entity.Calc;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 算法计算器表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-05
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
public interface CalcMapper extends BaseMapper<Calc> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
<?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="org.jeecg.modules.demo.calc.mapper.CalcMapper">
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package org.jeecg.modules.calc.service;
|
|
||||||
|
|
||||||
import org.jeecg.modules.calc.entity.Calc;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 算法计算器表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-05
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
public interface ICalcService extends IService<Calc> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package org.jeecg.modules.calc.service.impl;
|
|
||||||
|
|
||||||
import org.jeecg.modules.calc.entity.Calc;
|
|
||||||
import org.jeecg.modules.calc.mapper.CalcMapper;
|
|
||||||
import org.jeecg.modules.calc.service.ICalcService;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 算法计算器表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-05
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class CalcServiceImpl extends ServiceImpl<CalcMapper, Calc> implements ICalcService {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.config; // 放在配置包下
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.validation.annotation.Validated; // 可选,用于校验
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty; // 可选,用于校验
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConfigurationProperties(prefix = "spring.calculation.keys") // 对应配置文件的前缀
|
|
||||||
@Data // 使用 Lombok
|
|
||||||
@Validated // 可选:启用 JSR 303 校验
|
|
||||||
public class ExternalApiKeysConfig {
|
|
||||||
|
|
||||||
// 使用 Map 来存储不同类型的 API Key
|
|
||||||
// key: 标识符 (如 "tanyuan", "chanzhalv")
|
|
||||||
// value: 对应的 API Key
|
|
||||||
@NotEmpty // 可选:确保配置不为空 Map
|
|
||||||
private Map<String, String> calculation;
|
|
||||||
|
|
||||||
// 你也可以为特定的 key 添加单独的字段,如果它们很常用或需要特殊处理
|
|
||||||
// private String defaultKey;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Schema(description="计算器传参对象")
|
|
||||||
public class CalcData implements Serializable {
|
|
||||||
|
|
||||||
@Schema(description = "用户手机号")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@Schema(description = "具体的计算参数,类型根据业务决定")
|
|
||||||
private CalcDataBaseDto data;
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity.Dto;
|
|
||||||
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jeecg.modules.weixn.entity.CalcDataBaseDto;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Schema(description="产渣率计算参数 DTO") // 给个描述
|
|
||||||
public class ChanZhaLv implements CalcDataBaseDto { // <--- 实现接口
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L; // 最好给实现 Serializable 的类加上这个
|
|
||||||
|
|
||||||
@Schema(description = "垃圾收运量")
|
|
||||||
private String ljsyl; // 垃圾收运量
|
|
||||||
|
|
||||||
@Schema(description = "大渣产渣量")
|
|
||||||
private String dzczl; // 大渣产渣量
|
|
||||||
|
|
||||||
@Schema(description = "沼渣产渣量")
|
|
||||||
private String zzczl; // 沼渣产渣量
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCalcModelName() {
|
|
||||||
return IComputedTypes.CHAN_ZHA_LV_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity.Dto;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jeecg.modules.weixn.entity.CalcDataBaseDto;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Data
|
|
||||||
@Schema(description="污水碳源计算参数 DTO") // 给个描述
|
|
||||||
public class WuShuiTanYuan implements CalcDataBaseDto {
|
|
||||||
private static final long serialVersionUID = 1L; // 最好给实现 Serializable 的类加上这个
|
|
||||||
|
|
||||||
@Schema(description = "污水-处理量")
|
|
||||||
private String cll; // 污水-处理量
|
|
||||||
|
|
||||||
@Schema(description = "污水-COD")
|
|
||||||
private String cod; // 污水-COD
|
|
||||||
|
|
||||||
@Schema(description = "污水-总氮")
|
|
||||||
private String zd; // 污水-总氮
|
|
||||||
|
|
||||||
@Schema(description = "污水-出水总氮")
|
|
||||||
private String cszd; // 污水-出水总氮
|
|
||||||
|
|
||||||
@Schema(description = "待拖氮量")
|
|
||||||
private String dtdl; // 待拖氮量
|
|
||||||
|
|
||||||
@Schema(description = "碳源种类")
|
|
||||||
private String tyzl; // 碳源种类
|
|
||||||
|
|
||||||
@Schema(description = "碳源种有效SCOD")
|
|
||||||
private String scod; // 碳源种有效SCOD
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCalcModelName() {
|
|
||||||
return IComputedTypes.WU_SHUI_TANYUAN_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity.Dto;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jeecg.modules.weixn.entity.CalcDataBaseDto;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Data
|
|
||||||
@Schema(description="厌氧罐气率计算参数 DTO") // 给个描述
|
|
||||||
public class YanYangGuanQiLv implements CalcDataBaseDto {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L; // 最好给实现 Serializable 的类加上这个
|
|
||||||
|
|
||||||
@Schema(description = "总产气")
|
|
||||||
private String zcq;
|
|
||||||
|
|
||||||
@Schema(description = "进料TS")
|
|
||||||
private String jlts;
|
|
||||||
|
|
||||||
@Schema(description = "进料VS")
|
|
||||||
private String jlvs;
|
|
||||||
|
|
||||||
@Schema(description = "进罐浆液量")
|
|
||||||
private String jgjyl;
|
|
||||||
|
|
||||||
@Schema(description = "原生垃圾量")
|
|
||||||
private String ysljl;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCalcModelName() {
|
|
||||||
return IComputedTypes.YAN_YANG_GUAN_QI_LV_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity.Dto;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jeecg.modules.weixn.entity.CalcDataBaseDto;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Data
|
|
||||||
@Schema(description="厌氧有机负荷计算参数 DTO") // 给个描述
|
|
||||||
public class YanYangYouJiFuHe implements CalcDataBaseDto {
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L; // 最好给实现 Serializable 的类加上这个
|
|
||||||
|
|
||||||
@Schema(description = "罐容")
|
|
||||||
private String gr; // 罐容
|
|
||||||
|
|
||||||
@Schema(description = "进料TS")
|
|
||||||
private String jlts; // 进料TS
|
|
||||||
|
|
||||||
@Schema(description = "进料VS")
|
|
||||||
private String jlvs; // 进料VS
|
|
||||||
|
|
||||||
@Schema(description = "进罐浆液量")
|
|
||||||
private String jgjyl; // 进罐浆液量
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCalcModelName() {
|
|
||||||
return IComputedTypes.YAN_YANG_JI_FU_HE_NAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity; // 或者你选择的其他包名
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor; // 如果需要无参构造函数
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于映射外部 API (http://aiprice.orgcoder.com/v1/workflow/run) 返回的 JSON 结构
|
|
||||||
*/
|
|
||||||
@Data // Lombok: 自动生成 getter, setter, toString, equals, hashCode
|
|
||||||
@NoArgsConstructor // Lombok: 自动生成无参构造函数 (Jackson 反序列化需要)
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true) // Jackson: 忽略 JSON 中有但本类中没有定义的字段,增加健壮性
|
|
||||||
public class ExternalApiResponse implements Serializable {
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L; // 保持 Serializable 规范
|
|
||||||
|
|
||||||
@JsonProperty("workflow_run_id") // Jackson: 将 JSON 中的 "workflow_run_id" 映射到这个字段
|
|
||||||
private String workflowRunId;
|
|
||||||
|
|
||||||
@JsonProperty("task_id")
|
|
||||||
private String taskId;
|
|
||||||
|
|
||||||
@JsonProperty("data") // 对应 JSON 中的 "data" 对象
|
|
||||||
private ResponseData data; // 嵌套类,见下方定义
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.entity;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
|
||||||
import org.jeecg.common.constant.ProvinceCityArea;
|
|
||||||
import org.jeecg.common.util.SpringContextUtils;
|
|
||||||
import lombok.Data;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
|
||||||
import org.jeecg.common.aspect.annotation.Dict;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 小程序用户表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-04
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("weixin_user")
|
|
||||||
@Accessors(chain = true)
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
@Schema(description="小程序用户表")
|
|
||||||
public class WeixinUser implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**主键*/
|
|
||||||
@TableId(type = IdType.ASSIGN_ID)
|
|
||||||
@Schema(description = "主键")
|
|
||||||
private String id;
|
|
||||||
/**创建人*/
|
|
||||||
@Schema(description = "创建人")
|
|
||||||
private String createBy;
|
|
||||||
/**创建日期*/
|
|
||||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Schema(description = "创建日期")
|
|
||||||
private Date createTime;
|
|
||||||
/**更新人*/
|
|
||||||
@Schema(description = "更新人")
|
|
||||||
private String updateBy;
|
|
||||||
/**更新日期*/
|
|
||||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
|
||||||
@Schema(description = "更新日期")
|
|
||||||
private Date updateTime;
|
|
||||||
/**手机号*/
|
|
||||||
@Excel(name = "手机号", width = 15)
|
|
||||||
@Schema(description = "手机号")
|
|
||||||
private String phone;
|
|
||||||
/**用户昵称*/
|
|
||||||
@Excel(name = "用户昵称", width = 15)
|
|
||||||
@Schema(description = "用户昵称")
|
|
||||||
private String nickname;
|
|
||||||
/**性别*/
|
|
||||||
@Excel(name = "性别", width = 15)
|
|
||||||
@Schema(description = "性别")
|
|
||||||
private Integer sex;
|
|
||||||
/**微信id*/
|
|
||||||
@Excel(name = "微信id", width = 15)
|
|
||||||
@Schema(description = "微信id")
|
|
||||||
private String openid;
|
|
||||||
/**城市*/
|
|
||||||
@Excel(name = "城市", width = 15)
|
|
||||||
@Schema(description = "城市")
|
|
||||||
private String city;
|
|
||||||
/**经度*/
|
|
||||||
@Excel(name = "经度", width = 15)
|
|
||||||
@Schema(description = "经度")
|
|
||||||
private String log;
|
|
||||||
/**纬度*/
|
|
||||||
@Excel(name = "纬度", width = 15)
|
|
||||||
@Schema(description = "纬度")
|
|
||||||
private String lat;
|
|
||||||
/**算法配置*/
|
|
||||||
@Excel(name = "算法配置", width = 15, dictTable = "computed", dicText = "name", dicCode = "id")
|
|
||||||
@Dict(dictTable = "computed", dicText = "name", dicCode = "id")
|
|
||||||
@Schema(description = "算法配置")
|
|
||||||
private String computedids;
|
|
||||||
|
|
||||||
@Excel(name = "系统用户Id", width = 15)
|
|
||||||
@Schema(description = "系统用户Id")
|
|
||||||
private String sysUserId;
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.mapper;
|
|
||||||
|
|
||||||
import org.jeecg.modules.weixn.entity.WeixinUser;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 小程序用户表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-04
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
public interface WeixinUserMapper extends BaseMapper<WeixinUser> {
|
|
||||||
|
|
||||||
WeixinUser getByPhone(String phoneNumber);
|
|
||||||
|
|
||||||
int updateSysUserIdByPhone(String phone);
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.service;
|
|
||||||
|
|
||||||
import org.jeecg.modules.weixn.entity.CalcDataBaseDto;
|
|
||||||
import org.jeecg.modules.weixn.entity.IComputedTypes;
|
|
||||||
|
|
||||||
public interface ICalcService {
|
|
||||||
|
|
||||||
String calc(CalcDataBaseDto data, String phone, String computedTypes);
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.service;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import org.jeecg.modules.weixn.entity.WeixinUser;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Description: 小程序用户表
|
|
||||||
* @Author: jeecg-boot
|
|
||||||
* @Date: 2025-04-04
|
|
||||||
* @Version: V1.0
|
|
||||||
*/
|
|
||||||
public interface IWeixinUserService extends IService<WeixinUser> {
|
|
||||||
|
|
||||||
WeixinUser getByPhone(String phoneNumber);
|
|
||||||
|
|
||||||
|
|
||||||
JSONObject wxLogin(String phone);
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package org.jeecg.modules.weixn.vo;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class WeChatUserData implements Serializable {
|
|
||||||
private String phoneNumber;
|
|
||||||
private ArrayList<String> computedCodes;
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
# 这是一个Python示例,实际使用时根据你的后端语言进行调整
|
|
||||||
import requests
|
|
||||||
|
|
||||||
def get_phone_number(code):
|
|
||||||
url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber'
|
|
||||||
|
|
||||||
# 通过code换取手机号
|
|
||||||
data = {
|
|
||||||
'code': code,
|
|
||||||
'access_token': '你的access_token'
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.post(url, json=data)
|
|
||||||
return response.json()
|
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset=utf-8
|
||||||
|
end_of_line=lf
|
||||||
|
insert_final_newline=true
|
||||||
|
indent_style=space
|
||||||
|
indent_size=2
|
||||||
|
max_line_length = 100
|
||||||
|
|
||||||
|
[*.{yml,yaml,json}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
# port
|
||||||
|
VITE_PORT = 3100
|
||||||
|
|
||||||
|
# 网站标题
|
||||||
|
VITE_GLOB_APP_TITLE = JeecgBoot 企业级低代码平台
|
||||||
|
|
||||||
|
# 简称,此变量只能是字符/下划线
|
||||||
|
VITE_GLOB_APP_SHORT_NAME = JeecgBoot_Pro
|
||||||
|
|
||||||
|
# 单点登录服务端地址
|
||||||
|
VITE_GLOB_APP_CAS_BASE_URL=http://cas.test.com:8443/cas
|
||||||
|
|
||||||
|
# 是否开启单点登录
|
||||||
|
VITE_GLOB_APP_OPEN_SSO = false
|
||||||
|
|
||||||
|
# 开启微前端模式
|
||||||
|
VITE_GLOB_APP_OPEN_QIANKUN=true
|
||||||
|
|
||||||
|
# 文件预览地址
|
||||||
|
VITE_GLOB_ONLINE_VIEW_URL=http://fileview.jeecg.com/onlinePreview
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
*.sh
|
||||||
|
node_modules
|
||||||
|
*.md
|
||||||
|
*.woff
|
||||||
|
*.ttf
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
dist
|
||||||
|
/public
|
||||||
|
/docs
|
||||||
|
.husky
|
||||||
|
.local
|
||||||
|
/bin
|
||||||
|
Dockerfile
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
// @ts-check
|
||||||
|
const { defineConfig } = require('eslint-define-config');
|
||||||
|
module.exports = defineConfig({
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
},
|
||||||
|
parser: 'vue-eslint-parser',
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
sourceType: 'module',
|
||||||
|
jsxPragma: 'React',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/vue3-recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'prettier',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:jest/recommended',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'vue/script-setup-uses-vars': 'error',
|
||||||
|
'@typescript-eslint/ban-ts-ignore': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-var-requires': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'vue/custom-event-name-casing': 'off',
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
'@typescript-eslint/no-use-before-define': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': 'off',
|
||||||
|
'@typescript-eslint/ban-types': 'off',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'space-before-function-paren': 'off',
|
||||||
|
|
||||||
|
'vue/attributes-order': 'off',
|
||||||
|
'vue/one-component-per-file': 'off',
|
||||||
|
'vue/html-closing-bracket-newline': 'off',
|
||||||
|
'vue/max-attributes-per-line': 'off',
|
||||||
|
'vue/multiline-html-element-content-newline': 'off',
|
||||||
|
'vue/singleline-html-element-content-newline': 'off',
|
||||||
|
'vue/attribute-hyphenation': 'off',
|
||||||
|
'vue/require-default-prop': 'off',
|
||||||
|
'vue/html-self-closing': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
html: {
|
||||||
|
void: 'always',
|
||||||
|
normal: 'never',
|
||||||
|
component: 'always',
|
||||||
|
},
|
||||||
|
svg: 'always',
|
||||||
|
math: 'always',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
.github
|
||||||
|
dist
|
||||||
|
.npmrc
|
||||||
|
.cache
|
||||||
|
|
||||||
|
tests/server/static
|
||||||
|
tests/server/static/upload
|
||||||
|
|
||||||
|
.local
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.svn
|
||||||
|
# .vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
/os_del.cmd
|
||||||
|
os_del.cmd
|
||||||
|
/.vscode/
|
||||||
|
/.history/
|
||||||
|
/svn clear.bat
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
ports:
|
||||||
|
- port: 3344
|
||||||
|
onOpen: open-preview
|
||||||
|
tasks:
|
||||||
|
- init: yarn
|
||||||
|
command: yarn dev
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
/dist/*
|
||||||
|
.local
|
||||||
|
.output.js
|
||||||
|
/node_modules/**
|
||||||
|
|
||||||
|
**/*.svg
|
||||||
|
**/*.sh
|
||||||
|
|
||||||
|
/public/*
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
/dist/*
|
||||||
|
/public/*
|
||||||
|
public/*
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
# test directories
|
||||||
|
__tests__
|
||||||
|
test
|
||||||
|
tests
|
||||||
|
powered-test
|
||||||
|
|
||||||
|
# asset directories
|
||||||
|
docs
|
||||||
|
doc
|
||||||
|
website
|
||||||
|
images
|
||||||
|
assets
|
||||||
|
|
||||||
|
# examples
|
||||||
|
example
|
||||||
|
examples
|
||||||
|
|
||||||
|
# code coverage directories
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# build scripts
|
||||||
|
Makefile
|
||||||
|
Gulpfile.js
|
||||||
|
Gruntfile.js
|
||||||
|
|
||||||
|
# configs
|
||||||
|
appveyor.yml
|
||||||
|
circle.yml
|
||||||
|
codeship-services.yml
|
||||||
|
codeship-steps.yml
|
||||||
|
wercker.yml
|
||||||
|
.tern-project
|
||||||
|
.gitattributes
|
||||||
|
.editorconfig
|
||||||
|
.*ignore
|
||||||
|
.eslintrc
|
||||||
|
.jshintrc
|
||||||
|
.flowconfig
|
||||||
|
.documentup.json
|
||||||
|
.yarn-metadata.json
|
||||||
|
.travis.yml
|
||||||
|
|
||||||
|
# misc
|
||||||
|
*.md
|
||||||
|
|
||||||
|
!istanbul-reports/lib/html/assets
|
||||||
|
!istanbul-api/node_modules/istanbul-reports/lib/html/assets
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/nginx
|
||||||
|
MAINTAINER jeecgos@163.com
|
||||||
|
VOLUME /tmp
|
||||||
|
ENV LANG en_US.UTF-8
|
||||||
|
RUN echo "server { \
|
||||||
|
listen 80; \
|
||||||
|
location /jeecgboot/ { \
|
||||||
|
proxy_pass http://jeecg-boot-system:8080/jeecg-boot/; \
|
||||||
|
proxy_redirect off; \
|
||||||
|
proxy_set_header Host jeecg-boot-system; \
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr; \
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \
|
||||||
|
} \
|
||||||
|
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
|
||||||
|
location / { \
|
||||||
|
root /var/www/html/; \
|
||||||
|
index index.html index.htm; \
|
||||||
|
if (!-e \$request_filename) { \
|
||||||
|
rewrite ^(.*)\$ /index.html?s=\$1 last; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
access_log /var/log/nginx/access.log ; \
|
||||||
|
} " > /etc/nginx/conf.d/default.conf \
|
||||||
|
&& mkdir -p /var/www \
|
||||||
|
&& mkdir -p /var/www/html
|
||||||
|
|
||||||
|
ADD dist/ /var/www/html/
|
||||||
|
EXPOSE 80
|
||||||
|
EXPOSE 443
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
import { generate } from '@ant-design/colors';
|
||||||
|
|
||||||
|
export const primaryColor = '#1890FF';
|
||||||
|
|
||||||
|
export const darkMode = 'light';
|
||||||
|
|
||||||
|
type Fn = (...arg: any) => any;
|
||||||
|
|
||||||
|
type GenerateTheme = 'default' | 'dark';
|
||||||
|
|
||||||
|
export interface GenerateColorsParams {
|
||||||
|
mixLighten: Fn;
|
||||||
|
mixDarken: Fn;
|
||||||
|
tinycolor: any;
|
||||||
|
color?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateAntColors(color: string, theme: GenerateTheme = 'default') {
|
||||||
|
return generate(color, {
|
||||||
|
theme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getThemeColors(color?: string) {
|
||||||
|
const tc = color || primaryColor;
|
||||||
|
const lightColors = generateAntColors(tc);
|
||||||
|
const primary = lightColors[5];
|
||||||
|
const modeColors = generateAntColors(primary, 'dark');
|
||||||
|
|
||||||
|
return [...lightColors, ...modeColors];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateColors({
|
||||||
|
color = primaryColor,
|
||||||
|
mixLighten,
|
||||||
|
mixDarken,
|
||||||
|
tinycolor,
|
||||||
|
}: GenerateColorsParams) {
|
||||||
|
const arr = new Array(19).fill(0);
|
||||||
|
const lightens = arr.map((_t, i) => {
|
||||||
|
return mixLighten(color, i / 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
const darkens = arr.map((_t, i) => {
|
||||||
|
return mixDarken(color, i / 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
const alphaColors = arr.map((_t, i) => {
|
||||||
|
return tinycolor(color)
|
||||||
|
.setAlpha(i / 20)
|
||||||
|
.toRgbString();
|
||||||
|
});
|
||||||
|
|
||||||
|
const shortAlphaColors = alphaColors.map((item) => item.replace(/\s/g, '').replace(/0\./g, '.'));
|
||||||
|
|
||||||
|
const tinycolorLightens = arr
|
||||||
|
.map((_t, i) => {
|
||||||
|
return tinycolor(color)
|
||||||
|
.lighten(i * 5)
|
||||||
|
.toHexString();
|
||||||
|
})
|
||||||
|
.filter((item) => item !== '#ffffff');
|
||||||
|
|
||||||
|
const tinycolorDarkens = arr
|
||||||
|
.map((_t, i) => {
|
||||||
|
return tinycolor(color)
|
||||||
|
.darken(i * 5)
|
||||||
|
.toHexString();
|
||||||
|
})
|
||||||
|
.filter((item) => item !== '#000000');
|
||||||
|
return [
|
||||||
|
...lightens,
|
||||||
|
...darkens,
|
||||||
|
...alphaColors,
|
||||||
|
...shortAlphaColors,
|
||||||
|
...tinycolorDarkens,
|
||||||
|
...tinycolorLightens,
|
||||||
|
].filter((item) => !item.includes('-'));
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* The name of the configuration file entered in the production environment
|
||||||
|
*/
|
||||||
|
export const GLOB_CONFIG_FILE_NAME = '_app.config.js';
|
||||||
|
|
||||||
|
export const OUTPUT_DIR = 'dist';
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
import { primaryColor } from '../config/themeConfig';
|
||||||
|
// import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
import { generate } from '@ant-design/colors';
|
||||||
|
import { theme } from 'ant-design-vue/lib';
|
||||||
|
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
|
||||||
|
const { defaultAlgorithm, defaultSeed } = theme;
|
||||||
|
|
||||||
|
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
|
||||||
|
return generate(color, {
|
||||||
|
theme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* less global variable
|
||||||
|
*/
|
||||||
|
export function generateModifyVars() {
|
||||||
|
const palettes = generateAntColors(primaryColor);
|
||||||
|
const primary = palettes[5];
|
||||||
|
|
||||||
|
const primaryColorObj: Record<string, string> = {};
|
||||||
|
|
||||||
|
for (let index = 0; index < 10; index++) {
|
||||||
|
primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapToken = defaultAlgorithm(defaultSeed);
|
||||||
|
const v3Token = convertLegacyToken(mapToken);
|
||||||
|
return {
|
||||||
|
...v3Token,
|
||||||
|
// ...modifyVars,
|
||||||
|
// Used for global import to avoid the need to import each style file separately
|
||||||
|
// reference: Avoid repeated references
|
||||||
|
hack: `true; @import (reference) "${resolve('src/design/config.less')}";`,
|
||||||
|
'primary-color': primary,
|
||||||
|
...primaryColorObj,
|
||||||
|
'info-color': primary,
|
||||||
|
'processing-color': primary,
|
||||||
|
'success-color': '#55D187', // Success color
|
||||||
|
'error-color': '#ED6F6F', // False color
|
||||||
|
'warning-color': '#EFBD47', // Warning color
|
||||||
|
//'border-color-base': '#EEEEEE',
|
||||||
|
'font-size-base': '14px', // Main font size
|
||||||
|
'border-radius-base': '2px', // Component/float fillet
|
||||||
|
'link-color': primary, // Link color
|
||||||
|
'app-content-background': '#fafafa', // Link color
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import colors from 'picocolors';
|
||||||
|
import pkg from '../../../package.json';
|
||||||
|
|
||||||
|
async function generateIcon() {
|
||||||
|
const dir = path.resolve(process.cwd(), 'node_modules/@iconify/json');
|
||||||
|
|
||||||
|
const raw = await fs.readJSON(path.join(dir, 'collections.json'));
|
||||||
|
|
||||||
|
const collections = Object.entries(raw).map(([id, v]) => ({
|
||||||
|
...(v as any),
|
||||||
|
id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const choices = collections.map((item) => ({ key: item.id, value: item.id, name: item.name }));
|
||||||
|
|
||||||
|
inquirer
|
||||||
|
.prompt([
|
||||||
|
{
|
||||||
|
type: 'list',
|
||||||
|
name: 'useType',
|
||||||
|
choices: [
|
||||||
|
{ key: 'local', value: 'local', name: 'Local' },
|
||||||
|
{ key: 'onLine', value: 'onLine', name: 'OnLine' },
|
||||||
|
],
|
||||||
|
message: 'How to use icons?',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'list',
|
||||||
|
name: 'iconSet',
|
||||||
|
choices: choices,
|
||||||
|
message: 'Select the icon set that needs to be generated?',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
name: 'output',
|
||||||
|
message: 'Select the icon set that needs to be generated?',
|
||||||
|
default: 'src/components/Icon/data',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.then(async (answers) => {
|
||||||
|
const { iconSet, output, useType } = answers;
|
||||||
|
const outputDir = path.resolve(process.cwd(), output);
|
||||||
|
fs.ensureDir(outputDir);
|
||||||
|
const genCollections = collections.filter((item) => [iconSet].includes(item.id));
|
||||||
|
const prefixSet: string[] = [];
|
||||||
|
for (const info of genCollections) {
|
||||||
|
const data = await fs.readJSON(path.join(dir, 'json', `${info.id}.json`));
|
||||||
|
if (data) {
|
||||||
|
const { prefix } = data;
|
||||||
|
const isLocal = useType === 'local';
|
||||||
|
const icons = Object.keys(data.icons).map((item) => `${isLocal ? prefix + ':' : ''}${item}`);
|
||||||
|
|
||||||
|
await fs.writeFileSync(
|
||||||
|
path.join(output, `icons.data.ts`),
|
||||||
|
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`
|
||||||
|
);
|
||||||
|
prefixSet.push(prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite'));
|
||||||
|
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
generateIcon();
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Get the configuration file variable name
|
||||||
|
* @param env
|
||||||
|
*/
|
||||||
|
export const getConfigFileName = (env: Record<string, any>) => {
|
||||||
|
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '');
|
||||||
|
};
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
// #!/usr/bin/env node
|
||||||
|
|
||||||
|
import { runBuildConfig } from './buildConf';
|
||||||
|
import colors from 'picocolors';
|
||||||
|
|
||||||
|
import pkg from '../../package.json';
|
||||||
|
|
||||||
|
export const runBuild = async () => {
|
||||||
|
try {
|
||||||
|
const argvList = process.argv.splice(2);
|
||||||
|
|
||||||
|
// Generate configuration file
|
||||||
|
if (!argvList.includes('disabled-config')) {
|
||||||
|
runBuildConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(colors.red('vite build error:\n' + error));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
runBuild();
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
|
||||||
|
* https://github.com/anncwb/vite-plugin-compression
|
||||||
|
*/
|
||||||
|
import type { PluginOption } from 'vite';
|
||||||
|
import compressPlugin from 'vite-plugin-compression';
|
||||||
|
|
||||||
|
export function configCompressPlugin(compress: 'gzip' | 'brotli' | 'none', deleteOriginFile = false): PluginOption | PluginOption[] {
|
||||||
|
const compressList = compress.split(',');
|
||||||
|
|
||||||
|
const plugins: PluginOption[] = [];
|
||||||
|
|
||||||
|
if (compressList.includes('gzip')) {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
verbose: true,
|
||||||
|
disable: false,
|
||||||
|
threshold: 10240,
|
||||||
|
algorithm: 'gzip',
|
||||||
|
ext: '.gz',
|
||||||
|
deleteOriginFile,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compressList.includes('brotli')) {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
ext: '.br',
|
||||||
|
algorithm: 'brotliCompress',
|
||||||
|
deleteOriginFile,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* Plugin to minimize and use ejs template syntax in index.html.
|
||||||
|
* https://github.com/anncwb/vite-plugin-html
|
||||||
|
*/
|
||||||
|
import type { PluginOption } from 'vite';
|
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||||
|
import pkg from '../../../package.json';
|
||||||
|
import { GLOB_CONFIG_FILE_NAME } from '../../constant';
|
||||||
|
|
||||||
|
export function configHtmlPlugin(env: ViteEnv, isBuild: boolean, isQiankunMicro: boolean) {
|
||||||
|
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env;
|
||||||
|
|
||||||
|
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`;
|
||||||
|
|
||||||
|
const getAppConfigSrc = () => {
|
||||||
|
return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 【JEECG作为乾坤子应用】补充静态资源前缀
|
||||||
|
const {VITE_GLOB_QIANKUN_MICRO_APP_ENTRY} = env;
|
||||||
|
const basePublicPath = isQiankunMicro ? VITE_GLOB_QIANKUN_MICRO_APP_ENTRY : '';
|
||||||
|
|
||||||
|
const htmlPlugin: PluginOption[] = createHtmlPlugin({
|
||||||
|
minify: isBuild,
|
||||||
|
inject: {
|
||||||
|
// 修改模板html的标题
|
||||||
|
data: {
|
||||||
|
title: VITE_GLOB_APP_TITLE,
|
||||||
|
basePublicPath: basePublicPath,
|
||||||
|
},
|
||||||
|
// 将app.config.js文件注入到模板html中
|
||||||
|
tags: isBuild
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
tag: 'script',
|
||||||
|
attrs: {
|
||||||
|
src: getAppConfigSrc(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return htmlPlugin;
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
// 【图片压缩插件】
|
||||||
|
// Image resource files used to compress the output of the production environment
|
||||||
|
// https://github.com/anncwb/vite-plugin-imagemin
|
||||||
|
import viteImagemin from 'vite-plugin-imagemin';
|
||||||
|
|
||||||
|
export function configImageminPlugin() {
|
||||||
|
const plugin = viteImagemin({
|
||||||
|
gifsicle: {
|
||||||
|
optimizationLevel: 7,
|
||||||
|
interlaced: false,
|
||||||
|
},
|
||||||
|
optipng: {
|
||||||
|
optimizationLevel: 7,
|
||||||
|
},
|
||||||
|
mozjpeg: {
|
||||||
|
quality: 20,
|
||||||
|
},
|
||||||
|
pngquant: {
|
||||||
|
quality: [0.8, 0.9],
|
||||||
|
speed: 4,
|
||||||
|
},
|
||||||
|
svgo: {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: 'removeViewBox',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'removeEmptyAttrs',
|
||||||
|
active: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Mock plugin for development and production.
|
||||||
|
* https://github.com/anncwb/vite-plugin-mock
|
||||||
|
*/
|
||||||
|
import { viteMockServe } from 'vite-plugin-mock';
|
||||||
|
|
||||||
|
export function configMockPlugin(isBuild: boolean) {
|
||||||
|
return viteMockServe({
|
||||||
|
ignore: /^\_/,
|
||||||
|
mockPath: 'mock',
|
||||||
|
localEnabled: !isBuild,
|
||||||
|
prodEnabled: isBuild,
|
||||||
|
injectCode: `
|
||||||
|
import { setupProdMockServer } from '../mock/_createProductionServer';
|
||||||
|
|
||||||
|
setupProdMockServer();
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import qiankun from 'vite-plugin-qiankun';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【JEECG作为乾坤子应用】Vite适配乾坤以子应用模式运行
|
||||||
|
* @param env
|
||||||
|
*/
|
||||||
|
export function configQiankunMicroPlugin(env: ViteEnv) {
|
||||||
|
const {VITE_GLOB_QIANKUN_MICRO_APP_NAME} = env
|
||||||
|
|
||||||
|
return [
|
||||||
|
qiankun(VITE_GLOB_QIANKUN_MICRO_APP_NAME!, {
|
||||||
|
useDevMode: true,
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Vite Plugin for fast creating SVG sprites.
|
||||||
|
* https://github.com/anncwb/vite-plugin-svg-icons
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export function configSvgIconsPlugin(isBuild: boolean) {
|
||||||
|
const svgIconsPlugin = createSvgIconsPlugin({
|
||||||
|
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
|
||||||
|
svgoOptions: isBuild,
|
||||||
|
// default
|
||||||
|
symbolId: 'icon-[dir]-[name]',
|
||||||
|
});
|
||||||
|
return svgIconsPlugin;
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Package file volume analysis
|
||||||
|
*/
|
||||||
|
import visualizer from 'rollup-plugin-visualizer';
|
||||||
|
import { isReportMode } from '../../utils';
|
||||||
|
|
||||||
|
export function configVisualizerConfig() {
|
||||||
|
if (isReportMode()) {
|
||||||
|
return visualizer({
|
||||||
|
filename: './node_modules/.cache/visualizer/stats.html',
|
||||||
|
open: true,
|
||||||
|
gzipSize: true,
|
||||||
|
brotliSize: true,
|
||||||
|
}) as Plugin;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Used to parse the .env.development proxy configuration
|
||||||
|
*/
|
||||||
|
import type { ProxyOptions } from 'vite';
|
||||||
|
|
||||||
|
type ProxyItem = [string, string];
|
||||||
|
|
||||||
|
type ProxyList = ProxyItem[];
|
||||||
|
|
||||||
|
type ProxyTargetList = Record<string, ProxyOptions>;
|
||||||
|
|
||||||
|
const httpsRE = /^https:\/\//;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate proxy
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
|
export function createProxy(list: ProxyList = []) {
|
||||||
|
const ret: ProxyTargetList = {};
|
||||||
|
for (const [prefix, target] of list) {
|
||||||
|
const isHttps = httpsRE.test(target);
|
||||||
|
|
||||||
|
// https://github.com/http-party/node-http-proxy#options
|
||||||
|
ret[prefix] = {
|
||||||
|
target: target,
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true,
|
||||||
|
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
|
||||||
|
// https is require secure=false
|
||||||
|
...(isHttps ? { secure: false } : {}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
module.exports = {
|
||||||
|
ignores: [(commit) => commit.includes('init')],
|
||||||
|
extends: ['@commitlint/config-conventional'],
|
||||||
|
rules: {
|
||||||
|
'body-leading-blank': [2, 'always'],
|
||||||
|
'footer-leading-blank': [1, 'always'],
|
||||||
|
'header-max-length': [2, 'always', 108],
|
||||||
|
'subject-empty': [2, 'never'],
|
||||||
|
'type-empty': [2, 'never'],
|
||||||
|
'type-enum': [
|
||||||
|
2,
|
||||||
|
'always',
|
||||||
|
[
|
||||||
|
'feat',
|
||||||
|
'fix',
|
||||||
|
'perf',
|
||||||
|
'style',
|
||||||
|
'docs',
|
||||||
|
'test',
|
||||||
|
'refactor',
|
||||||
|
'build',
|
||||||
|
'ci',
|
||||||
|
'chore',
|
||||||
|
'revert',
|
||||||
|
'wip',
|
||||||
|
'workflow',
|
||||||
|
'types',
|
||||||
|
'release',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,181 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh_CN" id="htmlRoot">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
<meta name="renderer" content="webkit" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<title><%= title %></title>
|
||||||
|
<link rel="icon" href="<%= basePublicPath %>/logo.png" />
|
||||||
|
<!-- 全局配置 -->
|
||||||
|
<script>
|
||||||
|
window._CONFIG = {};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
(() => {
|
||||||
|
var htmlRoot = document.getElementById('htmlRoot');
|
||||||
|
var theme = window.localStorage.getItem('__APP__DARK__MODE__');
|
||||||
|
if (htmlRoot && theme) {
|
||||||
|
htmlRoot.setAttribute('data-theme', theme);
|
||||||
|
theme = htmlRoot = null;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="app">
|
||||||
|
<style>
|
||||||
|
html[data-theme='dark'] .app-loading {
|
||||||
|
background-color: #2c344a;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-theme='dark'] .app-loading .app-loading-title {
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
display: flex;
|
||||||
|
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||||
|
transform: translate3d(-50%, -50%, 0);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .dots {
|
||||||
|
display: flex;
|
||||||
|
padding: 98px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-title {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 30px;
|
||||||
|
font-size: 30px;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-logo {
|
||||||
|
display: block;
|
||||||
|
width: 90px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
margin-top: 30px;
|
||||||
|
font-size: 32px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: antRotate 1.2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #0065cc;
|
||||||
|
border-radius: 100%;
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: scale(0.75);
|
||||||
|
animation: antSpinMove 1s infinite linear alternate;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(1) {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(2) {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
-webkit-animation-delay: 0.4s;
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(3) {
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
-webkit-animation-delay: 0.8s;
|
||||||
|
animation-delay: 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(4) {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-animation-delay: 1.2s;
|
||||||
|
animation-delay: 1.2s;
|
||||||
|
}
|
||||||
|
@keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="app-loading">
|
||||||
|
<div class="app-loading-wrap">
|
||||||
|
<img src="<%= basePublicPath %>/resource/img/logo.png" class="app-loading-logo" alt="Logo" />
|
||||||
|
<div class="app-loading-dots">
|
||||||
|
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||||
|
</div>
|
||||||
|
<div class="app-loading-title"><%= title %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
<!-- 百度统计 -->
|
||||||
|
<script>
|
||||||
|
var _hmt = _hmt || [];
|
||||||
|
(function() {
|
||||||
|
var hm = document.createElement("script");
|
||||||
|
hm.src = "https://hm.baidu.com/hm.js?0febd9e3cacb3f627ddac64d52caac39";
|
||||||
|
var s = document.getElementsByTagName("script")[0];
|
||||||
|
s.parentNode.insertBefore(hm, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
export default {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
roots: ['<rootDir>/tests/'],
|
||||||
|
clearMocks: true,
|
||||||
|
moduleDirectories: ['node_modules', 'src'],
|
||||||
|
moduleFileExtensions: ['js', 'ts', 'vue', 'tsx', 'jsx', 'json', 'node'],
|
||||||
|
modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
|
||||||
|
testMatch: [
|
||||||
|
'**/tests/**/*.[jt]s?(x)',
|
||||||
|
'**/?(*.)+(spec|test).[tj]s?(x)',
|
||||||
|
'(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$',
|
||||||
|
],
|
||||||
|
testPathIgnorePatterns: [
|
||||||
|
'<rootDir>/tests/server/',
|
||||||
|
'<rootDir>/tests/__mocks__/',
|
||||||
|
'/node_modules/',
|
||||||
|
],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.tsx?$': 'ts-jest',
|
||||||
|
},
|
||||||
|
transformIgnorePatterns: ['<rootDir>/tests/__mocks__/', '/node_modules/'],
|
||||||
|
// A map from regular expressions to module names that allow to stub out resources with a single module
|
||||||
|
moduleNameMapper: {
|
||||||
|
'\\.(vs|fs|vert|frag|glsl|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||||
|
'<rootDir>/tests/__mocks__/fileMock.ts',
|
||||||
|
'\\.(sass|s?css|less)$': '<rootDir>/tests/__mocks__/styleMock.ts',
|
||||||
|
'\\?worker$': '<rootDir>/tests/__mocks__/workerMock.ts',
|
||||||
|
'^/@/(.*)$': '<rootDir>/src/$1',
|
||||||
|
},
|
||||||
|
testEnvironment: 'jsdom',
|
||||||
|
verbose: true,
|
||||||
|
collectCoverage: false,
|
||||||
|
coverageDirectory: 'coverage',
|
||||||
|
collectCoverageFrom: ['src/**/*.{js,ts,vue}'],
|
||||||
|
coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
|
||||||
|
};
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
|
||||||
|
|
||||||
|
const modules = import.meta.glob('./**/*.ts', { eager: true });
|
||||||
|
|
||||||
|
const mockModules: any[] = [];
|
||||||
|
Object.keys(modules).forEach((key) => {
|
||||||
|
if (key.includes('/_')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mockModules.push(...(modules as Recordable)[key].default);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in a production environment. Need to manually import all modules
|
||||||
|
*/
|
||||||
|
export function setupProdMockServer() {
|
||||||
|
createProdMockServer(mockModules);
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
import { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { resultSuccess, baseUrl } from '../_util';
|
||||||
|
|
||||||
|
const demoList = (keyword, count = 20) => {
|
||||||
|
const result = {
|
||||||
|
list: [] as any[],
|
||||||
|
};
|
||||||
|
for (let index = 0; index < count; index++) {
|
||||||
|
//根据搜索关键词做一下匹配
|
||||||
|
let name = `选项${index}`;
|
||||||
|
if(keyword && name.indexOf(keyword)!=-1){
|
||||||
|
result.list.push({
|
||||||
|
name: `选项${index}`,
|
||||||
|
id: `${index}`,
|
||||||
|
});
|
||||||
|
}else if(!keyword){
|
||||||
|
result.list.push({
|
||||||
|
name: `选项${index}`,
|
||||||
|
id: `${index}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/select/getDemoOptions`,
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { keyword,count} = query;
|
||||||
|
console.log("查询条件:", keyword);
|
||||||
|
return resultSuccess(demoList(keyword,count));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as MockMethod[];
|
||||||
@ -0,0 +1,298 @@
|
|||||||
|
import { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { resultError, resultPageSuccess, resultSuccess, baseUrl } from '../_util';
|
||||||
|
|
||||||
|
const accountList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 20; index++) {
|
||||||
|
result.push({
|
||||||
|
id: `${index}`,
|
||||||
|
account: '@first',
|
||||||
|
email: '@email',
|
||||||
|
nickname: '@cname()',
|
||||||
|
role: '@first',
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)',
|
||||||
|
'status|1': ['0', '1'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const userList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 20; index++) {
|
||||||
|
result.push({
|
||||||
|
id: `${index}`,
|
||||||
|
username: '@first',
|
||||||
|
email: '@email',
|
||||||
|
realname: '@cname()',
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)',
|
||||||
|
avatar: 'https://q1.qlogo.cn/g?b=qq&nk=190848757&s=640'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const roleList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 4; index++) {
|
||||||
|
result.push({
|
||||||
|
id: index + 1,
|
||||||
|
orderNo: `${index + 1}`,
|
||||||
|
roleName: ['超级管理员', '管理员', '文章管理员', '普通用户'][index],
|
||||||
|
roleValue: '@first',
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)',
|
||||||
|
menu: [['0', '1', '2'], ['0', '1'], ['0', '2'], ['2']][index],
|
||||||
|
'status|1': ['0', '1'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const newRoleList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 4; index++) {
|
||||||
|
result.push({
|
||||||
|
id: index + 1,
|
||||||
|
orderNo: `${index + 1}`,
|
||||||
|
roleName: ['超级管理员', '管理员', '文章管理员', '普通用户'][index],
|
||||||
|
roleCode: '@first',
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const testList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 4; index++) {
|
||||||
|
result.push({
|
||||||
|
id: index + 1,
|
||||||
|
orderNo: `${index + 1}`,
|
||||||
|
testName: ['数据1', '数据2', '数据3', '数据4'][index],
|
||||||
|
testValue: '@first',
|
||||||
|
createTime: '@datetime'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const tableDemoList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 4; index++) {
|
||||||
|
result.push({
|
||||||
|
id: index + 1,
|
||||||
|
orderCode: '2008200' + `${index + 1}`,
|
||||||
|
orderMoney: '@natural(1000,3000)',
|
||||||
|
ctype: '@natural(1,2)',
|
||||||
|
content: '@cword(10,20)',
|
||||||
|
orderDate: '@datetime'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const deptList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 3; index++) {
|
||||||
|
result.push({
|
||||||
|
id: `${index}`,
|
||||||
|
deptName: ['华东分部', '华南分部', '西北分部'][index],
|
||||||
|
orderNo: index + 1,
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)',
|
||||||
|
'status|1': ['0', '0', '1'],
|
||||||
|
children: (() => {
|
||||||
|
const children: any[] = [];
|
||||||
|
for (let j = 0; j < 4; j++) {
|
||||||
|
children.push({
|
||||||
|
id: `${index}-${j}`,
|
||||||
|
deptName: ['研发部', '市场部', '商务部', '财务部'][j],
|
||||||
|
orderNo: j + 1,
|
||||||
|
createTime: '@datetime',
|
||||||
|
remark: '@cword(10,20)',
|
||||||
|
'status|1': ['0', '1'],
|
||||||
|
parentDept: `${index}`,
|
||||||
|
children: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
})(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const menuList = (() => {
|
||||||
|
const result: any[] = [];
|
||||||
|
for (let index = 0; index < 3; index++) {
|
||||||
|
result.push({
|
||||||
|
id: `${index}`,
|
||||||
|
icon: ['ion:layers-outline', 'ion:git-compare-outline', 'ion:tv-outline'][index],
|
||||||
|
component: 'LAYOUT',
|
||||||
|
type: '0',
|
||||||
|
menuName: ['Dashboard', '权限管理', '功能'][index],
|
||||||
|
permission: '',
|
||||||
|
orderNo: index + 1,
|
||||||
|
createTime: '@datetime',
|
||||||
|
'status|1': ['0', '0', '1'],
|
||||||
|
children: (() => {
|
||||||
|
const children: any[] = [];
|
||||||
|
for (let j = 0; j < 4; j++) {
|
||||||
|
children.push({
|
||||||
|
id: `${index}-${j}`,
|
||||||
|
type: '1',
|
||||||
|
menuName: ['菜单1', '菜单2', '菜单3', '菜单4'][j],
|
||||||
|
icon: 'ion:document',
|
||||||
|
permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index],
|
||||||
|
component: [
|
||||||
|
'/dashboard/welcome/index',
|
||||||
|
'/dashboard/Analysis/index',
|
||||||
|
'/dashboard/workbench/index',
|
||||||
|
'/dashboard/test/index',
|
||||||
|
][j],
|
||||||
|
orderNo: j + 1,
|
||||||
|
createTime: '@datetime',
|
||||||
|
'status|1': ['0', '1'],
|
||||||
|
parentMenu: `${index}`,
|
||||||
|
children: (() => {
|
||||||
|
const children: any[] = [];
|
||||||
|
for (let k = 0; k < 4; k++) {
|
||||||
|
children.push({
|
||||||
|
id: `${index}-${j}-${k}`,
|
||||||
|
type: '2',
|
||||||
|
menuName: '按钮' + (j + 1) + '-' + (k + 1),
|
||||||
|
icon: '',
|
||||||
|
permission:
|
||||||
|
['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index] +
|
||||||
|
':btn' +
|
||||||
|
(k + 1),
|
||||||
|
component: [
|
||||||
|
'/dashboard/welcome/index',
|
||||||
|
'/dashboard/Analysis/index',
|
||||||
|
'/dashboard/workbench/index',
|
||||||
|
'/dashboard/test/index',
|
||||||
|
][j],
|
||||||
|
orderNo: j + 1,
|
||||||
|
createTime: '@datetime',
|
||||||
|
'status|1': ['0', '1'],
|
||||||
|
parentMenu: `${index}-${j}`,
|
||||||
|
children: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
})(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
})(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getAccountList`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, accountList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/sys/user/list`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, userList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getRoleListByPage`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, roleList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/sys/role/list`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, newRoleList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getTestListByPage`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, testList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getDemoTableListByPage`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { page = 1, pageSize = 20 } = query;
|
||||||
|
return resultPageSuccess(page, pageSize, tableDemoList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/setRoleStatus`,
|
||||||
|
timeout: 500,
|
||||||
|
method: 'post',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { id, status } = query;
|
||||||
|
return resultSuccess({ id, status });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getAllRoleList`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
return resultSuccess(roleList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getDeptList`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
return resultSuccess(deptList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/getMenuList`,
|
||||||
|
timeout: 100,
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
return resultSuccess(menuList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/system/accountExist`,
|
||||||
|
timeout: 500,
|
||||||
|
method: 'post',
|
||||||
|
response: ({ body }) => {
|
||||||
|
const { account } = body || {};
|
||||||
|
if (account && account.indexOf('admin') !== -1) {
|
||||||
|
return resultError('该字段不能包含admin');
|
||||||
|
} else {
|
||||||
|
return resultSuccess(`${account} can use`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as MockMethod[];
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { resultSuccess, baseUrl } from '../_util';
|
||||||
|
|
||||||
|
const demoTreeList = (keyword) => {
|
||||||
|
const result = {
|
||||||
|
list: [] as Recordable[],
|
||||||
|
};
|
||||||
|
for (let index = 0; index < 5; index++) {
|
||||||
|
const children: Recordable[] = [];
|
||||||
|
for (let j = 0; j < 3; j++) {
|
||||||
|
children.push({
|
||||||
|
title: `${keyword ?? ''}选项${index}-${j}`,
|
||||||
|
value: `${index}-${j}`,
|
||||||
|
key: `${index}-${j}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
result.list.push({
|
||||||
|
title: `${keyword ?? ''}选项${index}`,
|
||||||
|
value: `${index}`,
|
||||||
|
key: `${index}`,
|
||||||
|
children,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/tree/getDemoOptions`,
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'get',
|
||||||
|
response: ({ query }) => {
|
||||||
|
const { keyword } = query;
|
||||||
|
console.log("查询条件:", keyword);
|
||||||
|
return resultSuccess(demoTreeList(keyword));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as MockMethod[];
|
||||||
@ -0,0 +1,270 @@
|
|||||||
|
import { resultSuccess, resultError, getRequestToken, requestParams,baseUrl} from '../_util';
|
||||||
|
import { MockMethod } from 'vite-plugin-mock';
|
||||||
|
import { createFakeUserList } from './user';
|
||||||
|
|
||||||
|
// single
|
||||||
|
const dashboardRoute = {
|
||||||
|
path: '/dashboard',
|
||||||
|
name: 'Dashboard',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
redirect: '/dashboard/analysis',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.dashboard.dashboard',
|
||||||
|
hideChildrenInMenu: true,
|
||||||
|
icon: 'bx:bx-home',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'analysis',
|
||||||
|
name: 'Analysis',
|
||||||
|
component: '/dashboard/Analysis/index',
|
||||||
|
meta: {
|
||||||
|
hideMenu: true,
|
||||||
|
hideBreadcrumb: true,
|
||||||
|
title: 'routes.dashboard.analysis',
|
||||||
|
currentActiveMenu: '/dashboard',
|
||||||
|
icon: 'bx:bx-home',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'workbench',
|
||||||
|
name: 'Workbench',
|
||||||
|
component: '/dashboard/workbench/index',
|
||||||
|
meta: {
|
||||||
|
hideMenu: true,
|
||||||
|
hideBreadcrumb: true,
|
||||||
|
title: 'routes.dashboard.workbench',
|
||||||
|
currentActiveMenu: '/dashboard',
|
||||||
|
icon: 'bx:bx-home',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const backRoute = {
|
||||||
|
path: 'back',
|
||||||
|
name: 'PermissionBackDemo',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.permission.back',
|
||||||
|
},
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'page',
|
||||||
|
name: 'BackAuthPage',
|
||||||
|
component: '/demo/permission/back/index',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.permission.backPage',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'btn',
|
||||||
|
name: 'BackAuthBtn',
|
||||||
|
component: '/demo/permission/back/Btn',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.permission.backBtn',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const authRoute = {
|
||||||
|
path: '/permission',
|
||||||
|
name: 'Permission',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
redirect: '/permission/front/page',
|
||||||
|
meta: {
|
||||||
|
icon: 'carbon:user-role',
|
||||||
|
title: 'routes.demo.permission.permission',
|
||||||
|
},
|
||||||
|
children: [backRoute],
|
||||||
|
};
|
||||||
|
|
||||||
|
const levelRoute = {
|
||||||
|
path: '/level',
|
||||||
|
name: 'Level',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
redirect: '/level/menu1/menu1-1',
|
||||||
|
meta: {
|
||||||
|
icon: 'carbon:user-role',
|
||||||
|
title: 'routes.demo.level.level',
|
||||||
|
},
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1',
|
||||||
|
name: 'Menu1Demo',
|
||||||
|
meta: {
|
||||||
|
title: 'Menu1',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1-1',
|
||||||
|
name: 'Menu11Demo',
|
||||||
|
meta: {
|
||||||
|
title: 'Menu1-1',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'menu1-1-1',
|
||||||
|
name: 'Menu111Demo',
|
||||||
|
component: '/demo/level/Menu111',
|
||||||
|
meta: {
|
||||||
|
title: 'Menu111',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'menu1-2',
|
||||||
|
name: 'Menu12Demo',
|
||||||
|
component: '/demo/level/Menu12',
|
||||||
|
meta: {
|
||||||
|
title: 'Menu1-2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'menu2',
|
||||||
|
name: 'Menu2Demo',
|
||||||
|
component: '/demo/level/Menu2',
|
||||||
|
meta: {
|
||||||
|
title: 'Menu2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const sysRoute = {
|
||||||
|
path: '/system',
|
||||||
|
name: 'System',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
redirect: '/system/account',
|
||||||
|
meta: {
|
||||||
|
icon: 'ion:settings-outline',
|
||||||
|
title: 'routes.demo.system.moduleName',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'account',
|
||||||
|
name: 'AccountManagement',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.system.account',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
},
|
||||||
|
component: '/demo/system/account/index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'account_detail/:id',
|
||||||
|
name: 'AccountDetail',
|
||||||
|
meta: {
|
||||||
|
hideMenu: true,
|
||||||
|
title: 'routes.demo.system.account_detail',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
showMenu: false,
|
||||||
|
currentActiveMenu: '/system/account',
|
||||||
|
},
|
||||||
|
component: '/demo/system/account/AccountDetail',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'role',
|
||||||
|
name: 'RoleManagement',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.system.role',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
},
|
||||||
|
component: '/demo/system/role/index',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'menu',
|
||||||
|
name: 'MenuManagement',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.system.menu',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
},
|
||||||
|
component: '/demo/system/menu/index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'dept',
|
||||||
|
name: 'DeptManagement',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.system.dept',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
},
|
||||||
|
component: '/demo/system/dept/index',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'changePassword',
|
||||||
|
name: 'ChangePassword',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.system.password',
|
||||||
|
ignoreKeepAlive: true,
|
||||||
|
},
|
||||||
|
component: '/demo/system/password/index',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const linkRoute = {
|
||||||
|
path: '/link',
|
||||||
|
name: 'Link',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
meta: {
|
||||||
|
icon: 'ion:tv-outline',
|
||||||
|
title: 'routes.demo.iframe.frame',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'doc',
|
||||||
|
name: 'Doc',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.iframe.doc',
|
||||||
|
frameSrc: 'https://vvbin.cn/doc-next/',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'https://vvbin.cn/doc-next/',
|
||||||
|
name: 'DocExternal',
|
||||||
|
component: 'LAYOUT',
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.iframe.docExternal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: `${baseUrl}/sys/permission/getUserPermissionByToken`,
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'get',
|
||||||
|
response: (request: requestParams) => {
|
||||||
|
const token = getRequestToken(request);
|
||||||
|
if (!token) {
|
||||||
|
return resultError('Invalid token!');
|
||||||
|
}
|
||||||
|
const checkUser = createFakeUserList().find((item) => item.token === token);
|
||||||
|
if (!checkUser) {
|
||||||
|
return resultError('Invalid user token!');
|
||||||
|
}
|
||||||
|
const id = checkUser.userId;
|
||||||
|
let menu: Object[];
|
||||||
|
switch (id) {
|
||||||
|
case '1':
|
||||||
|
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[0].path;
|
||||||
|
menu = [dashboardRoute, authRoute, levelRoute, sysRoute, linkRoute];
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[1].path;
|
||||||
|
menu = [dashboardRoute, authRoute, levelRoute, linkRoute];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
menu = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultSuccess(menu);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as MockMethod[];
|
||||||
@ -0,0 +1,177 @@
|
|||||||
|
{
|
||||||
|
"name": "jeecgboot-vue3",
|
||||||
|
"version": "3.7.4",
|
||||||
|
"author": {
|
||||||
|
"name": "北京国炬信息技术有限公司",
|
||||||
|
"email": "jeecgos@163.com",
|
||||||
|
"url": "https://www.jeecg.com"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"pinstall": "pnpm install",
|
||||||
|
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
|
||||||
|
"build:report": "pnpm clean:cache && cross-env REPORT=true npm run build",
|
||||||
|
"preview": "npm run build && vite preview",
|
||||||
|
"reinstall": "rimraf pnpm-lock.yaml && rimraf yarn.lock && rimraf package.lock.json && rimraf node_modules && npm run install",
|
||||||
|
"clean:lib": "rimraf node_modules",
|
||||||
|
"gen:icon": "esno ./build/generate/icon/index.ts",
|
||||||
|
"batch:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
|
||||||
|
"upgrade:log": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||||
|
"husky:install": "husky install"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@jeecg/online": "3.7.4-beta",
|
||||||
|
"@iconify/iconify": "^3.1.1",
|
||||||
|
"@ant-design/colors": "^7.2.0",
|
||||||
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
|
"@vue/shared": "^3.5.13",
|
||||||
|
"@vueuse/core": "^10.11.1",
|
||||||
|
"@tinymce/tinymce-vue": "4.0.7",
|
||||||
|
"@zxcvbn-ts/core": "^3.0.4",
|
||||||
|
"ant-design-vue": "^4.2.6",
|
||||||
|
"axios": "^1.7.9",
|
||||||
|
"china-area-data": "^5.0.1",
|
||||||
|
"@vant/area-data": "^1.5.2",
|
||||||
|
"clipboard": "^2.0.11",
|
||||||
|
"codemirror": "^5.65.18",
|
||||||
|
"cron-parser": "^4.9.0",
|
||||||
|
"cropperjs": "^1.6.2",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
|
"dom-align": "^1.12.4",
|
||||||
|
"echarts": "^5.6.0",
|
||||||
|
"emoji-mart-vue-fast": "^15.0.3",
|
||||||
|
"enquire.js": "^2.1.6",
|
||||||
|
"intro.js": "^7.2.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"lodash.get": "^4.4.2",
|
||||||
|
"markdown-it": "^14.1.0",
|
||||||
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
|
"event-source-polyfill": "^1.0.31",
|
||||||
|
"highlight.js": "^11.11.1",
|
||||||
|
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||||
|
"md5": "^2.3.0",
|
||||||
|
"mockjs": "^1.1.0",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"path-to-regexp": "^6.3.0",
|
||||||
|
"pinia": "2.1.7",
|
||||||
|
"print-js": "^1.6.0",
|
||||||
|
"qs": "^6.13.1",
|
||||||
|
"qrcode": "^1.5.4",
|
||||||
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
|
"showdown": "^2.1.0",
|
||||||
|
"sortablejs": "^1.15.6",
|
||||||
|
"tinymce": "6.6.2",
|
||||||
|
"vditor": "^3.10.8",
|
||||||
|
"vue": "^3.5.13",
|
||||||
|
"vue-cropper": "^0.6.5",
|
||||||
|
"vue-cropperjs": "^5.0.0",
|
||||||
|
"vue-i18n": "^9.14.2",
|
||||||
|
"vue-infinite-scroll": "^2.0.2",
|
||||||
|
"vue-print-nb-jeecg": "^1.0.12",
|
||||||
|
"vue-router": "^4.5.0",
|
||||||
|
"vue-types": "^5.1.3",
|
||||||
|
"vuedraggable": "^4.1.0",
|
||||||
|
"vxe-table": "4.6.17",
|
||||||
|
"vxe-table-plugin-antd": "4.0.7",
|
||||||
|
"xe-utils": "3.5.26",
|
||||||
|
"xss": "^1.0.15"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@commitlint/cli": "^18.6.1",
|
||||||
|
"@commitlint/config-conventional": "^18.6.3",
|
||||||
|
"@iconify/json": "^2.2.292",
|
||||||
|
"@purge-icons/generated": "^0.10.0",
|
||||||
|
"@types/codemirror": "^5.60.15",
|
||||||
|
"@types/crypto-js": "^4.2.2",
|
||||||
|
"@types/fs-extra": "^11.0.4",
|
||||||
|
"@types/inquirer": "^9.0.7",
|
||||||
|
"@types/intro.js": "^5.1.5",
|
||||||
|
"@types/jest": "^29.5.14",
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
"@types/mockjs": "^1.0.10",
|
||||||
|
"@types/node": "^20.17.12",
|
||||||
|
"@types/nprogress": "^0.2.3",
|
||||||
|
"@types/qrcode": "^1.5.5",
|
||||||
|
"@types/qs": "^6.9.17",
|
||||||
|
"@types/showdown": "^2.0.6",
|
||||||
|
"@types/sortablejs": "^1.15.8",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||||
|
"@vue/compiler-sfc": "^3.5.13",
|
||||||
|
"@vue/test-utils": "^2.4.6",
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
|
"commitizen": "^4.3.1",
|
||||||
|
"conventional-changelog-cli": "^4.1.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"cz-git": "^1.11.0",
|
||||||
|
"czg": "^1.11.0",
|
||||||
|
"dotenv": "^16.4.7",
|
||||||
|
"eslint": "^8.57.1",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-define-config": "^2.1.0",
|
||||||
|
"eslint-plugin-jest": "^27.9.0",
|
||||||
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
|
"eslint-plugin-vue": "^9.32.0",
|
||||||
|
"esno": "^4.8.0",
|
||||||
|
"fs-extra": "^11.2.0",
|
||||||
|
"http-server": "^14.1.1",
|
||||||
|
"husky": "^8.0.3",
|
||||||
|
"inquirer": "^9.3.7",
|
||||||
|
"is-ci": "^3.0.1",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"less": "^4.2.1",
|
||||||
|
"lint-staged": "15.2.2",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"postcss": "^8.4.49",
|
||||||
|
"postcss-html": "^1.7.0",
|
||||||
|
"postcss-less": "^6.0.0",
|
||||||
|
"prettier": "^3.4.2",
|
||||||
|
"pretty-quick": "^4.0.0",
|
||||||
|
"rimraf": "^5.0.10",
|
||||||
|
"rollup": "^4.30.0",
|
||||||
|
"rollup-plugin-visualizer": "^5.13.1",
|
||||||
|
"stylelint": "^16.12.0",
|
||||||
|
"stylelint-config-prettier": "^9.0.5",
|
||||||
|
"stylelint-config-recommended": "^14.0.1",
|
||||||
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
|
"stylelint-config-standard": "^36.0.1",
|
||||||
|
"stylelint-order": "^6.0.4",
|
||||||
|
"ts-jest": "^29.2.5",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^4.9.5",
|
||||||
|
"vite": "^6.0.7",
|
||||||
|
"vite-plugin-compression": "^0.5.1",
|
||||||
|
"vite-plugin-html": "^3.2.2",
|
||||||
|
"vite-plugin-mkcert": "^1.17.6",
|
||||||
|
"vite-plugin-mock": "^2.9.8",
|
||||||
|
"vite-plugin-optimize-persist": "^0.1.2",
|
||||||
|
"vite-plugin-package-config": "^0.1.1",
|
||||||
|
"vite-plugin-purge-icons": "^0.10.0",
|
||||||
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
|
"vite-plugin-qiankun": "^1.0.15",
|
||||||
|
"@rys-fe/vite-plugin-theme": "^0.8.6",
|
||||||
|
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
||||||
|
"unocss": "^0.58.9",
|
||||||
|
"vue-eslint-parser": "^9.4.3",
|
||||||
|
"vue-tsc": "^1.8.27",
|
||||||
|
"dingtalk-jsapi": "^3.0.42",
|
||||||
|
"big.js": "^6.2.2"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/jeecgboot/JeecgBoot.git"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/jeecgboot/JeecgBoot/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://www.jeecg.com",
|
||||||
|
"engines": {
|
||||||
|
"node": "^18 || >=20"
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
module.exports = {
|
||||||
|
printWidth: 150,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: true, //语句末尾使用分号
|
||||||
|
vueIndentScriptAndStyle: true,
|
||||||
|
singleQuote: true, // 使用单引号
|
||||||
|
quoteProps: 'as-needed',
|
||||||
|
bracketSpacing: true,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
jsxBracketSameLine: false,
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
arrowParens: 'always',
|
||||||
|
insertPragma: false,
|
||||||
|
requirePragma: false,
|
||||||
|
proseWrap: 'never',
|
||||||
|
htmlWhitespaceSensitivity: 'strict',
|
||||||
|
endOfLine: 'auto',
|
||||||
|
rangeStart: 0,
|
||||||
|
};
|
||||||
|
After Width: | Height: | Size: 430 B |
|
After Width: | Height: | Size: 7.3 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue