Merge branch 'main' into production
52
README.md
@ -214,9 +214,7 @@ cd ../
|
||||
# ############
|
||||
# 进入 frontend 目录
|
||||
cd frontend
|
||||
# 建议使用 cnpm 安装依赖,如果没有安装 cnpm,可以通过 npm i cnpm 进行安装
|
||||
cnpm install
|
||||
# npm install --legacy-peer-deps
|
||||
npm install
|
||||
# 回到项目根目录下
|
||||
cd ../
|
||||
```
|
||||
@ -306,6 +304,17 @@ npm run package
|
||||
|
||||
|
||||
|
||||
#### 管理员前端项目打包并嵌入后端
|
||||
|
||||
```
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
然后将 `frontend/dist` 文件夹移动到 `backend/microservice-gateway/src/main/resources/static` 文件夹下,并修改文件夹名称 `dist` 为 `manage`
|
||||
|
||||
|
||||
|
||||
#### 后端配置
|
||||
|
||||
##### 配置业务域名
|
||||
@ -314,6 +323,9 @@ npm run package
|
||||
|
||||
```
|
||||
const baseUrl = "https://【⚠此处修改为你的业务域名】/" // 以 / 结尾,例如:https://epp.only4.work/
|
||||
|
||||
// 或者也可使用相对路径,例如:
|
||||
const baseUrl = "/"
|
||||
```
|
||||
|
||||
|
||||
@ -321,7 +333,7 @@ const baseUrl = "https://【⚠此处修改为你的业务域名】/" // 以 /
|
||||
修改 `backend/microservice-provider-access-8002/src/main/resources/static/access/assets/js/websocket.js` 文件
|
||||
|
||||
```
|
||||
window.wsUrl = 'ws://【⚠此处修改为你的业务域名】/access/websocket/1';
|
||||
window.wsUrl = 'ws://【⚠此处修改为你的业务域名】/access/websocket/';
|
||||
```
|
||||
|
||||
> 注意,如果使用了 SSL 证书,那么 ws:// 要换成 wss://
|
||||
@ -350,6 +362,22 @@ const envVersion = "【⚠此处修改为当前小程序环境】" // 正式版
|
||||
|
||||
|
||||
|
||||
##### 配置 Gateway 限流策略(可选)
|
||||
|
||||
> 如果你不懂这是在做什么,请直接跳过这一步
|
||||
|
||||
修改 `backend/microservice-gateway/src/main/resources/application.yml` 文件中 `routes` 中各个微服务的 `filters` 例如:
|
||||
|
||||
```yml
|
||||
filters: # 路由过滤器,使用自定义的限流过滤器工厂
|
||||
- name: RateLimitByIp # 设置每秒允许5个请求,每次请求需要1个令牌
|
||||
args:
|
||||
rate: 5.0
|
||||
permits: 1
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 打 jar 包
|
||||
|
||||
IDEA 中右侧 Maven 双击 Lifestyle 的 package,打包完成后的 jar 包可在以下位置找到
|
||||
@ -389,6 +417,7 @@ IDEA 中右侧 Maven 双击 Lifestyle 的 package,打包完成后的 jar 包
|
||||
🌟若使用的 Nacos 版本大于或等于 Nacos 2.2.0.1,则需要配置自定义密钥:
|
||||
|
||||
```properties
|
||||
# 密钥值可以自己指定,此处的自定义密钥来自 nacos 官网
|
||||
nacos.core.auth.plugin.nacos.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=
|
||||
```
|
||||
|
||||
@ -396,7 +425,9 @@ nacos.core.auth.plugin.nacos.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMT
|
||||
|
||||
|
||||
|
||||
#### nginx 代理配置(可选)
|
||||
#### nginx 代理配置
|
||||
|
||||
##### 反向代理(可选)
|
||||
|
||||
配置文件在 `nginx-conf` 目录下(不能直接拿来用,需要根据自己的实际情况来改)
|
||||
|
||||
@ -409,6 +440,13 @@ server
|
||||
listen 80;
|
||||
listen 443 ssl http2;
|
||||
|
||||
# 并发限制 限制当前站点最大并发数
|
||||
limit_conn perserver 50;
|
||||
# 单IP限制 限制单个IP访问最大并发数
|
||||
limit_conn perip 10;
|
||||
# 流量限制 限制每个请求的流量上限(单位:KB)
|
||||
limit_rate 8192k;
|
||||
|
||||
# 核心配置
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5203; # ⚠ Gateway 微服务项目本地运行的端口
|
||||
@ -425,6 +463,10 @@ server
|
||||
}
|
||||
```
|
||||
|
||||
##### SSL证书配置(可选)
|
||||
|
||||
如果域名配置为 https:// 则需要配置 SSL 证书。SSL证书可在 nginx 中进行配置,具体配置方法此处省略。
|
||||
|
||||
|
||||
|
||||
## 启动项目
|
||||
|
22
TODOs.md
@ -42,6 +42,28 @@
|
||||
Java代码中小程序AppID、密钥处理,小程序代码中小程序AppID处理
|
||||
|
||||
|
||||
# TODO 全部域名配置的地方添加 FIXME 环境配置
|
||||
|
||||
|
||||
# VSCode 全局搜索排除
|
||||
|
||||
node_modules,./postman-collection,target,out,.idea,@deprecated
|
||||
|
||||
# host 文件地址
|
||||
|
||||
C:\Windows\System32\drivers\etc
|
||||
|
||||
配置项
|
||||
|
||||
127.0.0.1 epp.only4.work
|
||||
127.0.0.1 epp-prod.only4.work
|
||||
|
||||
查看配置
|
||||
|
||||
ping epp.only4.work
|
||||
ping epp-prod.only4.work
|
||||
|
||||
|
||||
|
||||
# 后端项目启动命令
|
||||
|
||||
|
@ -4,7 +4,7 @@ import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public enum OrderStatus {
|
||||
PENDING("Pending", "等待确认"),
|
||||
PENDING("Pending", "等待支付"),
|
||||
PROCESSING("Processing", "已支付,等待发货中"),
|
||||
SHIPPED("Shipped", "已发货,等待确认收货"),
|
||||
DELIVERED("Delivered", "已送达"),
|
||||
|
@ -4,10 +4,12 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true) // 链式写法
|
||||
public class Good {
|
||||
public class Good implements Serializable {
|
||||
Long id;
|
||||
String goodsName;
|
||||
Integer categoryId;
|
||||
|
@ -4,10 +4,12 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true) // 链式写法
|
||||
public class GoodCategory {
|
||||
public class GoodCategory implements Serializable {
|
||||
Long id;
|
||||
String categoryName;
|
||||
Integer order;
|
||||
|
@ -4,13 +4,14 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true) // 链式写法
|
||||
public class Order {
|
||||
public class Order implements Serializable {
|
||||
private Long id;
|
||||
private Integer userId;
|
||||
private LocalDateTime orderDate;
|
||||
|
@ -4,10 +4,12 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true) // 链式写法
|
||||
public class OrderDetail {
|
||||
public class OrderDetail implements Serializable {
|
||||
private Long id;
|
||||
private Long orderId;
|
||||
private Long goodId;
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.cxyxiaomo.epp.common.query;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true) // 链式写法
|
||||
// 微服务必须要实现Serializable
|
||||
public class OrderQuery implements Serializable {
|
||||
private Long id;
|
||||
private Integer userId;
|
||||
private String orderStatusCode;
|
||||
private String expressId;
|
||||
}
|
@ -9,7 +9,6 @@ import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -22,10 +21,10 @@ import java.util.stream.Collectors;
|
||||
public class OrderVO implements Serializable {
|
||||
private String id;
|
||||
private Integer userId;
|
||||
private LocalDateTime orderDate;
|
||||
private String orderStatus;
|
||||
private String orderStatusCode;
|
||||
private String orderPrice;
|
||||
private String orderDate;
|
||||
private String payDate;
|
||||
private String cancelDate;
|
||||
private String shipDate;
|
||||
@ -47,6 +46,9 @@ public class OrderVO implements Serializable {
|
||||
String price = order.getOrderPrice().setScale(2, RoundingMode.FLOOR).toPlainString();
|
||||
orderVO.setOrderPrice(price);
|
||||
|
||||
if (order.getOrderDate() != null) {
|
||||
orderVO.setOrderDate(order.getOrderDate().toString().replace("T", " "));
|
||||
}
|
||||
if (order.getPayDate() != null) {
|
||||
orderVO.setPayDate(order.getPayDate().toString().replace("T", " "));
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
package com.cxyxiaomo.epp.gateway.Factory;
|
||||
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
// 一个自定义的限流过滤器工厂
|
||||
public class RateLimitByIpGatewayFilterFactory extends AbstractGatewayFilterFactory<RateLimitByIpGatewayFilterFactory.Config> {
|
||||
|
||||
// 用于存储IP地址和对应的计数器
|
||||
private static final Map<String, RateLimiter> RATE_LIMITER_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
public RateLimitByIpGatewayFilterFactory() {
|
||||
super(Config.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Config config) {
|
||||
return (exchange, chain) -> {
|
||||
// 获取请求的IP地址
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
String ip = request.getRemoteAddress().getAddress().getHostAddress();
|
||||
|
||||
// 根据IP地址获取对应的限流器
|
||||
RateLimiter rateLimiter = RATE_LIMITER_CACHE.get(ip);
|
||||
if (rateLimiter == null) {
|
||||
// 如果不存在,则创建一个新的限流器,并放入缓存中
|
||||
rateLimiter = RateLimiter.create(config.getRate());
|
||||
RATE_LIMITER_CACHE.put(ip, rateLimiter);
|
||||
}
|
||||
|
||||
// 判断请求是否被限流
|
||||
if (rateLimiter.tryAcquire(config.getPermits())) {
|
||||
// 如果没有被限流,则放行
|
||||
return chain.filter(exchange);
|
||||
} else {
|
||||
System.out.println("限流!ip: " + ip);
|
||||
// 如果被限流,则返回429状态码(Too Many Requests)
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
|
||||
return response.setComplete();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 配置类,用于接收配置参数
|
||||
public static class Config {
|
||||
|
||||
// 每秒允许的请求数
|
||||
private double rate;
|
||||
|
||||
// 每次请求需要的令牌数
|
||||
private int permits;
|
||||
|
||||
public double getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(double rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public int getPermits() {
|
||||
return permits;
|
||||
}
|
||||
|
||||
public void setPermits(int permits) {
|
||||
this.permits = permits;
|
||||
}
|
||||
}
|
||||
}
|
@ -40,20 +40,38 @@ spring:
|
||||
predicates:
|
||||
- Path=/user/**
|
||||
- Method=GET,POST
|
||||
filters: # 路由过滤器,使用自定义的限流过滤器工厂
|
||||
- name: RateLimitByIp # 设置每秒允许5个请求,每次请求需要1个令牌
|
||||
args:
|
||||
rate: 10.0
|
||||
permits: 1
|
||||
|
||||
- id: access
|
||||
uri: lb://microservice-provider-access
|
||||
predicates:
|
||||
- Path=/access/**
|
||||
- Method=GET,POST
|
||||
filters: # 路由过滤器,使用自定义的限流过滤器工厂
|
||||
- name: RateLimitByIp # 设置每秒允许5个请求,每次请求需要1个令牌
|
||||
args:
|
||||
rate: 10.0
|
||||
permits: 1
|
||||
|
||||
- id: access-websocket
|
||||
uri: lb:ws://microservice-provider-access
|
||||
predicates:
|
||||
- Path=/access/websocket/**
|
||||
|
||||
- id: shop
|
||||
uri: lb://microservice-provider-shop
|
||||
predicates:
|
||||
- Path=/shop/**
|
||||
- Method=GET,POST
|
||||
filters: # 路由过滤器,使用自定义的限流过滤器工厂
|
||||
- name: RateLimitByIp # 设置每秒允许5个请求,每次请求需要1个令牌
|
||||
args:
|
||||
rate: 10.0
|
||||
permits: 1
|
||||
|
||||
- id: test1
|
||||
uri: lb://microservice-provider-test
|
||||
|
@ -1 +1,3 @@
|
||||
编辑后右键 Compile And Reload File 修改即可生效,不用频繁重启项目
|
||||
|
||||
manage 文件夹下为 frontend 项目打包产物
|
After Width: | Height: | Size: 86 KiB |
@ -1,6 +1,7 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
html,
|
@ -0,0 +1,20 @@
|
||||
.scan-result-container {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.scan-result-image {
|
||||
width: min(55vw, 55vh);
|
||||
transition: 0.3s;
|
||||
transform: scale(0.001);
|
||||
}
|
||||
|
||||
.scan-result-image-show {
|
||||
transform: scale(1);
|
||||
}
|
@ -62,7 +62,7 @@
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* 弹窗列表样式 */
|
||||
@ -82,6 +82,7 @@
|
||||
box-sizing: border-box;
|
||||
place-items: center;
|
||||
background-color: #f6f6f6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gate-list-item > p {
|
@ -0,0 +1,39 @@
|
||||
const URLScanSuccessImage = "./assets/svg/scan-success.svg"
|
||||
const URLEnterGateImage = "./assets/svg/enter-gate.svg"
|
||||
const DOMFullScreenMask = document.getElementById("full-screen-mask")
|
||||
const DOMScanResultContainer = document.getElementById("scan-result-container")
|
||||
const DOMQRCodeScanSuccessImage = document.getElementById("qrcode-scan-success")
|
||||
|
||||
var isShowing = false
|
||||
|
||||
function showResult(imageType) {
|
||||
console.log("showResult")
|
||||
if (isShowing) {
|
||||
// console.log("showResult() skipped coz showing.")
|
||||
// 等待 0.1s 重试
|
||||
setTimeout(() => showResult(imageType), 100)
|
||||
return
|
||||
}
|
||||
isShowing = true
|
||||
DOMQRCodeScanSuccessImage.src = imageType === "onscan" ? URLScanSuccessImage : URLEnterGateImage
|
||||
DOMFullScreenMask.classList.remove("hidden")
|
||||
DOMScanResultContainer.classList.remove("hidden")
|
||||
//
|
||||
setTimeout(() => {
|
||||
DOMQRCodeScanSuccessImage.classList.add("scan-result-image-show")
|
||||
}, 100)
|
||||
|
||||
setTimeout(function hideResult() {
|
||||
console.log("hideResult")
|
||||
DOMQRCodeScanSuccessImage.classList.remove("scan-result-image-show")
|
||||
setTimeout(() => {
|
||||
DOMQRCodeScanSuccessImage.src = ""
|
||||
DOMFullScreenMask.classList.add("hidden")
|
||||
DOMScanResultContainer.classList.add("hidden")
|
||||
isShowing = false
|
||||
}, 300)
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
// setTimeout(showResult, 100)
|
||||
window.showResult = showResult
|
@ -1,6 +1,12 @@
|
||||
window.wsUrl = 'wss://epp-prod.only4.work/access/websocket/1';
|
||||
// window.wsUrl = 'ws://127.0.0.1:80/access/websocket/1';
|
||||
// window.wsUrl = 'ws://127.0.0.1:8002/access/websocket/1';
|
||||
/**
|
||||
* FIXME 环境配置
|
||||
*
|
||||
* window.wsUrl
|
||||
* - 线上环境:'wss://epp.only4.work/access/websocket/'
|
||||
* - 开发环境:'ws://127.0.0.1:80/access/websocket/'
|
||||
* 'ws://127.0.0.1:8002/access/websocket/'
|
||||
*/
|
||||
window.wsUrl = 'wss://epp.only4.work/access/websocket/';
|
||||
|
||||
window.ws = null; // WebSocket 实例对象
|
||||
|
||||
@ -10,9 +16,20 @@ window.ws = null; // WebSocket 实例对象
|
||||
return
|
||||
}
|
||||
|
||||
function getWsUrl() {
|
||||
function getUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
return `${window.wsUrl}${getUUID()}`
|
||||
}
|
||||
|
||||
function createConn() {
|
||||
// 创建webscoket 对象
|
||||
const ws = new WebSocket(window.wsUrl)
|
||||
const ws = new WebSocket(getWsUrl() /* window.wsUrl */)
|
||||
// 执行上面的语句之后,客户端就会与服务器进行连接
|
||||
|
||||
// readyState返回当前实例对象的当前状态
|
||||
@ -34,9 +51,23 @@ window.ws = null; // WebSocket 实例对象
|
||||
ws.onmessage = ({data}) => {
|
||||
console.log('onmessage readyState', ws.readyState)
|
||||
// 注意此时的data是json格式的 需要转化下
|
||||
console.log('onmessage 有新消息啦=======>', JSON.parse(data))
|
||||
let result = JSON.parse(data)
|
||||
console.log('onmessage 有新消息啦=======>', result)
|
||||
// 实例对象的send方法给服务器发送消息
|
||||
ws.send('客户端发送的消息')
|
||||
|
||||
switch (result.action) {
|
||||
case 'onscan':
|
||||
case 'onopen':
|
||||
if (window.currentGate && result.gateId === window.currentGate.id) {
|
||||
console.log(result.action)
|
||||
window.showResult(result.action)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("switch=>default", result.action)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 实例对象的onclose属性,用于连接关闭后的回调 函数
|
||||
@ -58,5 +89,6 @@ window.ws = null; // WebSocket 实例对象
|
||||
}
|
||||
return ws
|
||||
}
|
||||
|
||||
window.ws = createConn()
|
||||
})()
|
Before Width: | Height: | Size: 886 B After Width: | Height: | Size: 886 B |
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<circle cx="50" cy="50" r="45" stroke="white" stroke-width="7" fill="white"/>
|
||||
|
||||
<!-- 外围圆圈 -->
|
||||
<circle cx="50" cy="50" r="45" stroke="#006600" stroke-width="8" fill="none">
|
||||
<animate id="circle" attributeName="stroke-dasharray" from="0,282.743" to="282.743,0" dur="1s" begin="0s" fill="freeze"/>
|
||||
<animateTransform attributeName="transform" type="rotate" from="-90 50 50" to="270 50 50" dur="1s" begin="0s" fill="freeze"/>
|
||||
</circle>
|
||||
|
||||
<!-- 对勾动画 -->
|
||||
<path d="M20 50 L40 70 L80 30" stroke="#006600" stroke-width="8" fill="none" visibility="hidden">
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="circle.end+0.1s"/>
|
||||
<!-- 对勾开始动画 -->
|
||||
<!-- <animate attributeName="stroke-dasharray" from="0,120" to="120,0" dur="1s" begin="circle.end+0.1s" repeatCount="indefinite"/> -->
|
||||
<animate id="check" attributeName="stroke-dasharray" from="0,120" to="120,0" dur="1s" begin="circle.end+0.1s" repeatCount="1"/>
|
||||
<!-- 对勾隐藏动画 -->
|
||||
<set attributeName="visibility" from="visible" to="hidden" begin="check.end+0.1s"/>
|
||||
</path>
|
||||
|
||||
<!-- 扫码成功 -->
|
||||
<!-- <text x="50" y="55" font-size="20" text-anchor="middle" fill="#006600" visibility="hidden">
|
||||
扫码成功
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="check.end+0.1s"/>
|
||||
</text> -->
|
||||
<text x="50" y="50" font-weight="bold" text-anchor="middle" fill="#006600" visibility="hidden">
|
||||
<tspan x="50" dx="3" dy="-3" font-size="26">大门</tspan>
|
||||
<tspan x="50" dy="23" font-size="20">已开启</tspan>
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="check.end+0.1s"/>
|
||||
</text>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<circle cx="50" cy="50" r="45" stroke="white" stroke-width="7" fill="white"/>
|
||||
|
||||
<!-- 外围圆圈 -->
|
||||
<circle cx="50" cy="50" r="45" stroke="#006600" stroke-width="8" fill="none">
|
||||
<animate id="circle" attributeName="stroke-dasharray" from="0,282.743" to="282.743,0" dur="1s" begin="0s" fill="freeze"/>
|
||||
<animateTransform attributeName="transform" type="rotate" from="-90 50 50" to="270 50 50" dur="1s" begin="0s" fill="freeze"/>
|
||||
</circle>
|
||||
|
||||
<!-- 对勾动画 -->
|
||||
<path d="M20 50 L40 70 L80 30" stroke="#006600" stroke-width="8" fill="none" visibility="hidden">
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="circle.end+0.1s"/>
|
||||
<!-- 对勾开始动画 -->
|
||||
<!-- <animate attributeName="stroke-dasharray" from="0,120" to="120,0" dur="1s" begin="circle.end+0.1s" repeatCount="indefinite"/> -->
|
||||
<animate id="check" attributeName="stroke-dasharray" from="0,120" to="120,0" dur="1s" begin="circle.end+0.1s" repeatCount="1"/>
|
||||
<!-- 对勾隐藏动画 -->
|
||||
<set attributeName="visibility" from="visible" to="hidden" begin="check.end+0.1s"/>
|
||||
</path>
|
||||
|
||||
<!-- 扫码成功 -->
|
||||
<!-- <text x="50" y="55" font-size="20" text-anchor="middle" fill="#006600" visibility="hidden">
|
||||
扫码成功
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="check.end+0.1s"/>
|
||||
</text> -->
|
||||
<text x="50" y="50" font-size="27" font-weight="bold" text-anchor="middle" fill="#006600" visibility="hidden">
|
||||
<tspan x="50" dx="4" dy="-5">扫码</tspan>
|
||||
<tspan x="50" dy="28">成功</tspan>
|
||||
<set attributeName="visibility" from="hidden" to="visible" begin="check.end+0.1s"/>
|
||||
</text>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -10,6 +10,7 @@
|
||||
<title>社区疫情防控系统 - 门禁端</title>
|
||||
<link rel="stylesheet" href="./assets/css/index.css"/>
|
||||
<link rel="stylesheet" href="./assets/css/setting-panel.css"/>
|
||||
<link rel="stylesheet" href="./assets/css/scan-result.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -36,11 +37,12 @@
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<h1 id="no-qrcode">请选择大门</h1>
|
||||
<img id="qrcode" src="" style="display: none">
|
||||
<img id="qrcode" src="" style="display: none;"><br>
|
||||
<p id="refreshTimeCountDown"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 设置页面 -->
|
||||
<div id="full-screen-mask" class="full-screen-mask hidden"></div>
|
||||
<div id="setting-container" class="setting-container hidden">
|
||||
<div class="setting-panel">
|
||||
@ -63,8 +65,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 扫码成功 -->
|
||||
<div id="scan-result-container" class="scan-result-container hidden">
|
||||
<img id="qrcode-scan-success" class="scan-result-image" src="./assets/svg/scan-success.svg">
|
||||
</div>
|
||||
|
||||
<script src="./assets/js/setting-panel.js" type="module"></script>
|
||||
<script src="./renderer.js" type="module"></script>
|
||||
<script src="assets/js/websocket-message-panel.js"></script>
|
||||
<script src="./assets/js/websocket.js"></script>
|
||||
</body>
|
||||
|
@ -1,3 +1,13 @@
|
||||
/**
|
||||
* FIXME 环境配置
|
||||
*
|
||||
* baseUrl
|
||||
* - 线上环境:"https://epp.only4.work/"
|
||||
* - 开发环境:"/"
|
||||
* envVersion
|
||||
* - 线上环境:"release"
|
||||
* - 开发环境:"develop"
|
||||
*/
|
||||
// 定义常量
|
||||
const baseUrl = "https://epp-prod.only4.work/"
|
||||
const url = baseUrl + "access/wechat/getUnlimitedQRCode"
|
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>基于微服务的社区疫情防控系统</title>
|
||||
<style>
|
||||
body {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
border: 1px solid black;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.grid-item ul {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<h1 style="text-align: center;">基于微服务的社区疫情防控系统</h1>
|
||||
<p style="text-align: center;">epp.only4.work</p>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(2, 1fr);">
|
||||
<div class="grid-item">
|
||||
<h3>
|
||||
门禁端 跨端桌面应用
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
方式1:访问
|
||||
<a target="_blank" href="./guard/index.html">https://epp.only4.work/guard/index.html</a>
|
||||
</li>
|
||||
<li>
|
||||
方式2:运行跨端桌面应用
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<h3>
|
||||
居民端 小程序
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
方式1:扫描下方小程序码
|
||||
<p style="text-align: center">
|
||||
<img src="./assets/image/miniprogram.jpg" style="width: 180px;">
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
方式2:微信搜索小程序 <b>devprogram</b>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<h3>
|
||||
社区管理员端 管理后台
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
访问
|
||||
<a target="_blank" href="./manage/index.html">https://epp.only4.work/manage/index.html</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<h3>
|
||||
系统管理员端 管理后台
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
访问
|
||||
<a target="_blank" href="./manage/index.html">https://epp.only4.work/manage/index.html</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>开发</h2>
|
||||
<p>小程序后台:<a target="_blank">https://mp.weixin.qq.com/</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1 @@
|
||||
import{d as r,dJ as p,b0 as l,r as i,o as m,c as E,e as o,b as s,w as a,p as f,h,f as t,_ as v}from"./index.f859bf4e.js";const c=e=>(f("data-v-d4771405"),e=e(),h(),e),B={class:"error-page"},g=c(()=>o("div",{class:"error-code"},[t("4"),o("span",null,"0"),t("3")],-1)),k=c(()=>o("div",{class:"error-desc"},"\u554A\u54E6~ \u4F60\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u8BE5\u9875\u9762\u54E6",-1)),x={class:"error-handle"},y=r({name:"403"}),C=r({...y,setup(e){const u=p(),n=()=>{u.go(-2)};return(b,D)=>{const _=l,d=i("router-link");return m(),E("div",B,[g,k,o("div",x,[s(d,{to:"/"},{default:a(()=>[s(_,{type:"primary",size:"large"},{default:a(()=>[t("\u8FD4\u56DE\u9996\u9875")]),_:1})]),_:1}),s(_,{class:"error-btn",type:"primary",size:"large",onClick:n},{default:a(()=>[t("\u8FD4\u56DE\u4E0A\u4E00\u9875")]),_:1})])])}}});const I=v(C,[["__scopeId","data-v-d4771405"]]);export{I as default};
|
@ -0,0 +1 @@
|
||||
.error-page[data-v-d4771405]{display:flex;justify-content:center;align-items:center;flex-direction:column;width:100%;height:100%;background:#f3f3f3;box-sizing:border-box}.error-code[data-v-d4771405]{line-height:1;font-size:250px;font-weight:bolder;color:#f02d2d}.error-code span[data-v-d4771405]{color:#00a854}.error-desc[data-v-d4771405]{font-size:30px;color:#777}.error-handle[data-v-d4771405]{margin-top:30px;padding-bottom:200px}.error-btn[data-v-d4771405]{margin-left:100px}
|
@ -0,0 +1 @@
|
||||
import{m as s}from"./manage-list.8ab8e06b.js";import{s as t}from"./send_request.cc43fdb9.js";import{d as n,o as r,c,b as o}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";function u(e){return t({url:"/access/gate/manage/getGateList",method:"GET",params:e})}function a(e){return t({url:"/access/gate/manage/editGate",method:"POST",useQS:!0,params:e})}function i(e){return t({url:"/access/gate/manage/deleteGate",method:"POST",useQS:!0,params:e})}function m(e){return t({url:"/access/gate/manage/exportGateList",method:"GET",params:e})}const d={class:"container"},L=n({__name:"access-gate-setting",setup(e){return(p,f)=>(r(),c("div",d,[o(s,{"list-func":u,"add-func":a,"edit-func":a,"delete-func":i,"export-func":m,"edit-permiss":"access-gate-setting"},null,8,["list-func","add-func","edit-func","delete-func","export-func"])]))}});export{L as default};
|
@ -0,0 +1 @@
|
||||
import{m as o}from"./manage-list.8ab8e06b.js";import{s as m}from"./send_request.cc43fdb9.js";import{d as r,o as c,c as a,b as n}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";function p(e){var s,i;let t=JSON.parse(JSON.stringify(e));return delete t.timestamp,Array.isArray(e.timestamp)&&e.timestamp.length==2&&(t.startTime=(s=e.timestamp[0])==null?void 0:s.getTime(),t.endTime=(i=e.timestamp[1])==null?void 0:i.getTime()),m({url:"/access/access-log/manage/getAccessLogList",method:"GET",params:t})}function g(e){var s,i;let t=JSON.parse(JSON.stringify(e));return delete t.timestamp,Array.isArray(e.timestamp)&&e.timestamp.length==2&&(t.startTime=(s=e.timestamp[0])==null?void 0:s.getTime(),t.endTime=(i=e.timestamp[1])==null?void 0:i.getTime()),m({url:"/access/access-log/manage/exportAccessLogList",method:"GET",params:t})}const l={class:"container"},y=r({__name:"access-log",setup(e){return(t,s)=>(c(),a("div",l,[n(o,{"list-func":p,"export-func":g,"edit-permiss":"access-log"},null,8,["list-func","export-func"])]))}});export{y as default};
|
@ -0,0 +1 @@
|
||||
.el-row[data-v-e670d298]{margin-bottom:20px}.grid-content[data-v-e670d298]{display:flex;align-items:center;height:100px}.grid-cont-right[data-v-e670d298]{flex:1;text-align:center;font-size:14px;color:#999}.grid-num[data-v-e670d298]{font-size:30px;font-weight:700}.grid-con-icon[data-v-e670d298]{font-size:50px;width:100px;height:100px;text-align:center;line-height:100px;color:#fff}.grid-con-1 .grid-con-icon[data-v-e670d298]{background:rgb(45,140,240)}.grid-con-1 .grid-num[data-v-e670d298]{color:#2d8cf0}.grid-con-2 .grid-con-icon[data-v-e670d298]{background:rgb(100,213,114)}.grid-con-2 .grid-num[data-v-e670d298]{color:#64d572}.grid-con-3 .grid-con-icon[data-v-e670d298]{background:rgb(242,94,67)}.grid-con-3 .grid-num[data-v-e670d298]{color:#f25e43}.user-info[data-v-e670d298]{display:flex;align-items:center;padding-bottom:20px;border-bottom:2px solid #ccc;margin-bottom:20px}.user-info-cont[data-v-e670d298]{padding-left:50px;flex:1;font-size:14px;color:#999}.user-info-cont div[data-v-e670d298]:first-child{font-size:30px;color:#222}.user-info-list[data-v-e670d298]{font-size:14px;color:#999;line-height:25px}.user-info-list span[data-v-e670d298]{margin-left:70px}.mgb20[data-v-e670d298]{margin-bottom:20px}.todo-item[data-v-e670d298]{font-size:14px}.todo-item-del[data-v-e670d298]{text-decoration:line-through;color:#999}
|
@ -0,0 +1 @@
|
||||
import{d as g,E as C,r as _,a as F,o as x,c as y,b as s,w as e,e as o,u as r,t as h,f as t,g as b,p as w,h as A,_ as S}from"./index.f859bf4e.js";import{E as D,a as I,b as V}from"./el-card.0035c23b.js";import{E as N}from"./el-progress.d53d438b.js";const a=d=>(w("data-v-e670d298"),d=d(),A(),d),R={class:"container"},T={class:"user-info"},k={class:"user-info-cont"},G={class:"user-info-name"},U=a(()=>o("div",{class:"user-info-list"},[t(" \u4E0A\u6B21\u767B\u5F55\u65F6\u95F4\uFF1A "),o("span",null,"2022-10-01")],-1)),z=a(()=>o("div",{class:"user-info-list"},[t(" \u4E0A\u6B21\u767B\u5F55\u5730\u70B9\uFF1A "),o("span",null,"\u4E1C\u839E")],-1)),H=a(()=>o("div",{class:"clearfix"},[o("span",null,"\u8BED\u8A00\u8BE6\u60C5")],-1)),L={class:"grid-content grid-con-1"},M=a(()=>o("div",{class:"grid-cont-right"},[o("div",{class:"grid-num"},"1234"),o("div",null,"\u7528\u6237\u8BBF\u95EE\u91CF")],-1)),P={class:"grid-content grid-con-2"},j=a(()=>o("div",{class:"grid-cont-right"},[o("div",{class:"grid-num"},"321"),o("div",null,"\u7CFB\u7EDF\u6D88\u606F")],-1)),q={class:"grid-content grid-con-3"},J=a(()=>o("div",{class:"grid-cont-right"},[o("div",{class:"grid-num"},"500"),o("div",null,"\u5546\u54C1\u6570\u91CF")],-1)),K=g({name:"dashboard"}),O=g({...K,setup(d){const i=localStorage.getItem("ms_username"),f=i==="admin"?"\u8D85\u7EA7\u7BA1\u7406\u5458":"\u666E\u901A\u7528\u6237";return(Q,W)=>{const v=C,n=D,l=N,c=I,m=_("User"),u=F,E=_("ChatDotRound"),B=_("Goods"),p=V;return x(),y("div",R,[s(p,{gutter:20},{default:e(()=>[s(c,{span:8},{default:e(()=>[s(n,{shadow:"hover",class:"mgb20",style:{height:"252px"}},{default:e(()=>[o("div",T,[s(v,{size:120,src:r(b)},null,8,["src"]),o("div",k,[o("div",G,h(r(i)),1),o("div",null,h(r(f)),1)])]),U,z]),_:1}),s(n,{shadow:"hover",style:{height:"252px"}},{header:e(()=>[H]),default:e(()=>[t(" Vue "),s(l,{percentage:79.4,color:"#42b983"},null,8,["percentage"]),t(" TypeScript "),s(l,{percentage:14,color:"#f1e05a"}),t(" CSS "),s(l,{percentage:5.6},null,8,["percentage"]),t(" HTML "),s(l,{percentage:1,color:"#f56c6c"})]),_:1})]),_:1}),s(c,{span:16},{default:e(()=>[s(p,{gutter:20,class:"mgb20"},{default:e(()=>[s(c,{span:8},{default:e(()=>[s(n,{shadow:"hover","body-style":{padding:"0px"}},{default:e(()=>[o("div",L,[s(u,{class:"grid-con-icon"},{default:e(()=>[s(m)]),_:1}),M])]),_:1})]),_:1}),s(c,{span:8},{default:e(()=>[s(n,{shadow:"hover","body-style":{padding:"0px"}},{default:e(()=>[o("div",P,[s(u,{class:"grid-con-icon"},{default:e(()=>[s(E)]),_:1}),j])]),_:1})]),_:1}),s(c,{span:8},{default:e(()=>[s(n,{shadow:"hover","body-style":{padding:"0px"}},{default:e(()=>[o("div",q,[s(u,{class:"grid-con-icon"},{default:e(()=>[s(B)]),_:1}),J])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1})])}}});const $=S(O,[["__scopeId","data-v-e670d298"]]);export{$ as default};
|
@ -0,0 +1 @@
|
||||
import{i as g,j as r,d as u,k as h,o as f,c as N,n as d,u as o,l as m,f as R,t as x,m as B,e as K,q as w,s as _,v,x as p,y as P,z as n,A as j,B as A,C as S,w as k,D as E,F as D}from"./index.f859bf4e.js";const O=Symbol("rowContextKey"),V=g({header:{type:String,default:""},bodyStyle:{type:r([String,Object,Array]),default:""},shadow:{type:String,values:["always","hover","never"],default:"always"}}),L=u({name:"ElCard"}),T=u({...L,props:V,setup(i){const t=h("card");return(s,l)=>(f(),N("div",{class:d([o(t).b(),o(t).is(`${s.shadow}-shadow`)])},[s.$slots.header||s.header?(f(),N("div",{key:0,class:d(o(t).e("header"))},[m(s.$slots,"header",{},()=>[R(x(s.header),1)])],2)):B("v-if",!0),K("div",{class:d(o(t).e("body")),style:w(s.bodyStyle)},[m(s.$slots,"default")],6)],2))}});var q=_(T,[["__file","/home/runner/work/element-plus/element-plus/packages/components/card/src/card.vue"]]);const z=v(q),F=g({tag:{type:String,default:"div"},span:{type:Number,default:24},offset:{type:Number,default:0},pull:{type:Number,default:0},push:{type:Number,default:0},xs:{type:r([Number,Object]),default:()=>p({})},sm:{type:r([Number,Object]),default:()=>p({})},md:{type:r([Number,Object]),default:()=>p({})},lg:{type:r([Number,Object]),default:()=>p({})},xl:{type:r([Number,Object]),default:()=>p({})}}),I=u({name:"ElCol"}),J=u({...I,props:F,setup(i){const t=i,{gutter:s}=P(O,{gutter:n(()=>0)}),l=h("col"),y=n(()=>{const e={};return s.value&&(e.paddingLeft=e.paddingRight=`${s.value/2}px`),e}),b=n(()=>{const e=[];return["span","offset","pull","push"].forEach(a=>{const c=t[a];j(c)&&(a==="span"?e.push(l.b(`${t[a]}`)):c>0&&e.push(l.b(`${a}-${t[a]}`)))}),["xs","sm","md","lg","xl"].forEach(a=>{j(t[a])?e.push(l.b(`${a}-${t[a]}`)):A(t[a])&&Object.entries(t[a]).forEach(([c,C])=>{e.push(c!=="span"?l.b(`${a}-${c}-${C}`):l.b(`${a}-${C}`))})}),s.value&&e.push(l.is("guttered")),[l.b(),e]});return(e,$)=>(f(),S(E(e.tag),{class:d(o(b)),style:w(o(y))},{default:k(()=>[m(e.$slots,"default")]),_:3},8,["class","style"]))}});var G=_(J,[["__file","/home/runner/work/element-plus/element-plus/packages/components/col/src/col.vue"]]);const ee=v(G),H=["start","center","end","space-around","space-between","space-evenly"],M=["top","middle","bottom"],Q=g({tag:{type:String,default:"div"},gutter:{type:Number,default:0},justify:{type:String,values:H,default:"start"},align:{type:String,values:M,default:"top"}}),U=u({name:"ElRow"}),W=u({...U,props:Q,setup(i){const t=i,s=h("row"),l=n(()=>t.gutter);D(O,{gutter:l});const y=n(()=>{const e={};return t.gutter&&(e.marginRight=e.marginLeft=`-${t.gutter/2}px`),e}),b=n(()=>[s.b(),s.is(`justify-${t.justify}`,t.justify!=="start"),s.is(`align-${t.align}`,t.align!=="top")]);return(e,$)=>(f(),S(E(e.tag),{class:d(o(b)),style:w(o(y))},{default:k(()=>[m(e.$slots,"default")]),_:3},8,["class","style"]))}});var X=_(W,[["__file","/home/runner/work/element-plus/element-plus/packages/components/row/src/row.vue"]]);const te=v(X);export{z as E,ee as a,te as b};
|
@ -0,0 +1 @@
|
||||
:root{--el-popup-modal-bg-color:var(--el-color-black);--el-popup-modal-opacity:.5}.v-modal-enter{-webkit-animation:v-modal-in var(--el-transition-duration-fast) ease;animation:v-modal-in var(--el-transition-duration-fast) ease}.v-modal-leave{-webkit-animation:v-modal-out var(--el-transition-duration-fast) ease forwards;animation:v-modal-out var(--el-transition-duration-fast) ease forwards}@-webkit-keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{to{opacity:0}}@keyframes v-modal-out{to{opacity:0}}.v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:var(--el-popup-modal-opacity);background:var(--el-popup-modal-bg-color)}.el-popup-parent--hidden{overflow:hidden}.el-dialog{--el-dialog-width:50%;--el-dialog-margin-top:15vh;--el-dialog-bg-color:var(--el-bg-color);--el-dialog-box-shadow:var(--el-box-shadow);--el-dialog-title-font-size:var(--el-font-size-large);--el-dialog-content-font-size:14px;--el-dialog-font-line-height:var(--el-font-line-height-primary);--el-dialog-padding-primary:20px;--el-dialog-border-radius:var(--el-border-radius-small);position:relative;margin:var(--el-dialog-margin-top,15vh) auto 50px;background:var(--el-dialog-bg-color);border-radius:var(--el-dialog-border-radius);box-shadow:var(--el-dialog-box-shadow);box-sizing:border-box;width:var(--el-dialog-width,50%)}.el-dialog:focus{outline:0!important}.el-dialog.is-align-center{margin:auto}.el-dialog.is-fullscreen{--el-dialog-width:100%;--el-dialog-margin-top:0;margin-bottom:0;height:100%;overflow:auto}.el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.el-dialog.is-draggable .el-dialog__header{cursor:move;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-dialog__header{padding:var(--el-dialog-padding-primary);padding-bottom:10px;margin-right:16px}.el-dialog__headerbtn{position:absolute;top:6px;right:0;padding:0;width:54px;height:54px;background:0 0;border:none;outline:0;cursor:pointer;font-size:var(--el-message-close-size,16px)}.el-dialog__headerbtn .el-dialog__close{color:var(--el-color-info);font-size:inherit}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:var(--el-color-primary)}.el-dialog__title{line-height:var(--el-dialog-font-line-height);font-size:var(--el-dialog-title-font-size);color:var(--el-text-color-primary)}.el-dialog__body{padding:calc(var(--el-dialog-padding-primary) + 10px) var(--el-dialog-padding-primary);color:var(--el-text-color-regular);font-size:var(--el-dialog-content-font-size)}.el-dialog__footer{padding:var(--el-dialog-padding-primary);padding-top:10px;text-align:right;box-sizing:border-box}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial;padding:25px calc(var(--el-dialog-padding-primary) + 5px) 30px}.el-dialog--center .el-dialog__footer{text-align:inherit}.el-overlay-dialog{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto}.dialog-fade-enter-active{-webkit-animation:modal-fade-in var(--el-transition-duration);animation:modal-fade-in var(--el-transition-duration)}.dialog-fade-enter-active .el-overlay-dialog{-webkit-animation:dialog-fade-in var(--el-transition-duration);animation:dialog-fade-in var(--el-transition-duration)}.dialog-fade-leave-active{-webkit-animation:modal-fade-out var(--el-transition-duration);animation:modal-fade-out var(--el-transition-duration)}.dialog-fade-leave-active .el-overlay-dialog{-webkit-animation:dialog-fade-out var(--el-transition-duration);animation:dialog-fade-out var(--el-transition-duration)}@-webkit-keyframes dialog-fade-in{0%{transform:translate3d(0,-20px,0);opacity:0}to{transform:translateZ(0);opacity:1}}@keyframes dialog-fade-in{0%{transform:translate3d(0,-20px,0);opacity:0}to{transform:translateZ(0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{transform:translateZ(0);opacity:1}to{transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{transform:translateZ(0);opacity:1}to{transform:translate3d(0,-20px,0);opacity:0}}@-webkit-keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}@keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}@-webkit-keyframes modal-fade-out{0%{opacity:1}to{opacity:0}}@keyframes modal-fade-out{0%{opacity:1}to{opacity:0}}.el-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:2000;height:100%;background-color:var(--el-overlay-color-lighter);overflow:auto}.el-overlay .el-overlay-root{height:0}
|
@ -0,0 +1 @@
|
||||
.el-progress{position:relative;line-height:1;display:flex;align-items:center}.el-progress__text{font-size:14px;color:var(--el-text-color-regular);margin-left:5px;min-width:50px;line-height:1}.el-progress__text i{vertical-align:middle;display:block}.el-progress--circle,.el-progress--dashboard{display:inline-block}.el-progress--circle .el-progress__text,.el-progress--dashboard .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;transform:translateY(-50%)}.el-progress--circle .el-progress__text i,.el-progress--dashboard .el-progress__text i{vertical-align:middle;display:inline-block}.el-progress--without-text .el-progress__text{display:none}.el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.el-progress.is-success .el-progress-bar__inner{background-color:var(--el-color-success)}.el-progress.is-success .el-progress__text{color:var(--el-color-success)}.el-progress.is-warning .el-progress-bar__inner{background-color:var(--el-color-warning)}.el-progress.is-warning .el-progress__text{color:var(--el-color-warning)}.el-progress.is-exception .el-progress-bar__inner{background-color:var(--el-color-danger)}.el-progress.is-exception .el-progress__text{color:var(--el-color-danger)}.el-progress-bar{flex-grow:1;box-sizing:border-box}.el-progress-bar__outer{height:6px;border-radius:100px;background-color:var(--el-border-color-lighter);overflow:hidden;position:relative;vertical-align:middle}.el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:var(--el-color-primary);text-align:right;border-radius:100px;line-height:1;white-space:nowrap;transition:width .6s ease}.el-progress-bar__inner:after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-progress-bar__inner--indeterminate{transform:translateZ(0);-webkit-animation:indeterminate 3s infinite;animation:indeterminate 3s infinite}.el-progress-bar__innerText{display:inline-block;vertical-align:middle;color:#fff;font-size:12px;margin:0 5px}@-webkit-keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}@keyframes progress{0%{background-position:0 0}to{background-position:32px 0}}@-webkit-keyframes indeterminate{0%{left:-100%}to{left:100%}}@keyframes indeterminate{0%{left:-100%}to{left:100%}}
|
@ -0,0 +1,6 @@
|
||||
import{i as M,j as m,d as T,k as A,z as r,G as V,H as O,I as j,J as q,K as G,L as H,M as C,o as l,c,n as i,u as t,e as y,q as f,l as _,t as D,m as I,C as N,w as J,D as K,a as R,s as U,v as Q}from"./index.f859bf4e.js";const X=M({type:{type:String,default:"line",values:["line","circle","dashboard"]},percentage:{type:Number,default:0,validator:u=>u>=0&&u<=100},status:{type:String,default:"",values:["","success","exception","warning"]},indeterminate:{type:Boolean,default:!1},duration:{type:Number,default:3},strokeWidth:{type:Number,default:6},strokeLinecap:{type:m(String),default:"round"},textInside:{type:Boolean,default:!1},width:{type:Number,default:126},showText:{type:Boolean,default:!0},color:{type:m([String,Array,Function]),default:""},format:{type:m(Function),default:u=>`${u}%`}}),Y=["aria-valuenow"],Z={viewBox:"0 0 100 100"},ee=["d","stroke","stroke-width"],te=["d","stroke","opacity","stroke-linecap","stroke-width"],se={key:0},ae=T({name:"ElProgress"}),re=T({...ae,props:X,setup(u){const s=u,v={success:"#13ce66",exception:"#ff4949",warning:"#e6a23c",default:"#20a0ff"},a=A("progress"),x=r(()=>({width:`${s.percentage}%`,animationDuration:`${s.duration}s`,backgroundColor:P(s.percentage)})),g=r(()=>(s.strokeWidth/s.width*100).toFixed(1)),b=r(()=>["circle","dashboard"].includes(s.type)?Number.parseInt(`${50-Number.parseFloat(g.value)/2}`,10):0),$=r(()=>{const e=b.value,o=s.type==="dashboard";return`
|
||||
M 50 50
|
||||
m 0 ${o?"":"-"}${e}
|
||||
a ${e} ${e} 0 1 1 0 ${o?"-":""}${e*2}
|
||||
a ${e} ${e} 0 1 1 0 ${o?"":"-"}${e*2}
|
||||
`}),h=r(()=>2*Math.PI*b.value),k=r(()=>s.type==="dashboard"?.75:1),w=r(()=>`${-1*h.value*(1-k.value)/2}px`),B=r(()=>({strokeDasharray:`${h.value*k.value}px, ${h.value}px`,strokeDashoffset:w.value})),z=r(()=>({strokeDasharray:`${h.value*k.value*(s.percentage/100)}px, ${h.value}px`,strokeDashoffset:w.value,transition:"stroke-dasharray 0.6s ease 0s, stroke 0.6s ease, opacity ease 0.6s"})),E=r(()=>{let e;return s.color?e=P(s.percentage):e=v[s.status]||v.default,e}),F=r(()=>s.status==="warning"?V:s.type==="line"?s.status==="success"?O:j:s.status==="success"?q:G),W=r(()=>s.type==="line"?12+s.strokeWidth*.4:s.width*.111111+2),S=r(()=>s.format(s.percentage));function L(e){const o=100/e.length;return e.map((n,p)=>C(n)?{color:n,percentage:(p+1)*o}:n).sort((n,p)=>n.percentage-p.percentage)}const P=e=>{var o;const{color:d}=s;if(H(d))return d(e);if(C(d))return d;{const n=L(d);for(const p of n)if(p.percentage>e)return p.color;return(o=n[n.length-1])==null?void 0:o.color}};return(e,o)=>(l(),c("div",{class:i([t(a).b(),t(a).m(e.type),t(a).is(e.status),{[t(a).m("without-text")]:!e.showText,[t(a).m("text-inside")]:e.textInside}]),role:"progressbar","aria-valuenow":e.percentage,"aria-valuemin":"0","aria-valuemax":"100"},[e.type==="line"?(l(),c("div",{key:0,class:i(t(a).b("bar"))},[y("div",{class:i(t(a).be("bar","outer")),style:f({height:`${e.strokeWidth}px`})},[y("div",{class:i([t(a).be("bar","inner"),{[t(a).bem("bar","inner","indeterminate")]:e.indeterminate}]),style:f(t(x))},[(e.showText||e.$slots.default)&&e.textInside?(l(),c("div",{key:0,class:i(t(a).be("bar","innerText"))},[_(e.$slots,"default",{percentage:e.percentage},()=>[y("span",null,D(t(S)),1)])],2)):I("v-if",!0)],6)],6)],2)):(l(),c("div",{key:1,class:i(t(a).b("circle")),style:f({height:`${e.width}px`,width:`${e.width}px`})},[(l(),c("svg",Z,[y("path",{class:i(t(a).be("circle","track")),d:t($),stroke:`var(${t(a).cssVarName("fill-color-light")}, #e5e9f2)`,"stroke-width":t(g),fill:"none",style:f(t(B))},null,14,ee),y("path",{class:i(t(a).be("circle","path")),d:t($),stroke:t(E),fill:"none",opacity:e.percentage?1:0,"stroke-linecap":e.strokeLinecap,"stroke-width":t(g),style:f(t(z))},null,14,te)]))],6)),(e.showText||e.$slots.default)&&!e.textInside?(l(),c("div",{key:2,class:i(t(a).e("text")),style:f({fontSize:`${t(W)}px`})},[_(e.$slots,"default",{percentage:e.percentage},()=>[e.status?(l(),N(t(R),{key:1},{default:J(()=>[(l(),N(K(t(F))))]),_:1})):(l(),c("span",se,D(t(S)),1))])],6)):I("v-if",!0)],10,Y))}});var oe=U(re,[["__file","/home/runner/work/element-plus/element-plus/packages/components/progress/src/progress.vue"]]);const le=Q(oe);export{le as E};
|
After Width: | Height: | Size: 6.0 KiB |
@ -0,0 +1 @@
|
||||
.login-wrap[data-v-0fd4c22f]{width:100%;height:100%}.login-container[data-v-0fd4c22f]{width:100%;height:100%;display:grid;place-items:center}.ms-title[data-v-0fd4c22f]{width:100%;padding:18px 24px;box-sizing:border-box;text-align:center;font-size:20px;color:#fff;border-bottom:1px solid #ddd}.ms-login[data-v-0fd4c22f]{width:min(380px,95vw);padding:5px 10px;border-radius:5px;background:rgba(255,255,255,.3);overflow:hidden}.ms-content[data-v-0fd4c22f]{padding:30px}.login-btn[data-v-0fd4c22f]{text-align:center}.login-btn button[data-v-0fd4c22f]{width:100%;height:36px;margin-bottom:10px}.company-info[data-v-0fd4c22f]{color:#7589b6;text-align:center;position:absolute;left:0;right:0;bottom:10px;font-size:13px;letter-spacing:1px}
|
@ -0,0 +1 @@
|
||||
import{d as E,dJ as x,aR as C,ac as k,dK as N,r as R,o as b,c as h,e as d,t as F,u,b as o,w as a,aT as S,f as T,m as q,bP as B,b0 as D,a as K,bX as f,dL as L,dM as M,_ as U}from"./index.f859bf4e.js";import{E as $,s as j,t as A}from"./el-input.f35758e8.js";import{u as J}from"./user.0bac8e4f.js";import"./send_request.cc43fdb9.js";const O={class:"login-wrap"},P={class:"login-container"},X={class:"ms-login"},z={class:"ms-title"},G={class:"login-btn"},H={key:0,class:"company-info"},Q=E({__name:"login",setup(W){const _=x(),r=C({username:"root",password:"root"}),V={username:[{required:!0,message:"\u8BF7\u8F93\u5165\u7528\u6237\u540D",trigger:"blur"}],password:[{required:!0,message:"\u8BF7\u8F93\u5165\u5BC6\u7801",trigger:"blur"}]},p=k(),v=g=>{!g||g.validate(async(s,l)=>{if(!s){console.log("invalidFields",l),Object.values(l).forEach(e=>{e.forEach(t=>{B.error({message:t.message,grouping:!0})})});return}J({username:r.username,password:r.password}).then(async e=>{var i,c,m,n,y,I,w;if(!e)return;console.log("login data",e,e.userInfo),B.success("\u767B\u5F55\u6210\u529F"),localStorage.setItem("ms_username",(i=e.userInfo)==null?void 0:i.username),localStorage.setItem("ms_realname",(c=e.userInfo)==null?void 0:c.realname),localStorage.setItem("ms_user_id",(m=e.userInfo)==null?void 0:m.id),localStorage.setItem("ms_role_id",(n=e.userInfo)==null?void 0:n.roleId);let t=(w=(I=(y=_.currentRoute)==null?void 0:y.value)==null?void 0:I.query)==null?void 0:w.redirectTo;t&&!t.includes("/login")?_.push(t):_.push("/")})})};return N().clearTags(),(g,s)=>{const l=D,e=$,t=j,i=R("Right"),c=K,m=A;return b(),h("div",O,[d("div",P,[d("div",X,[d("div",z,F(u(f).siteFullTitle),1),o(m,{model:r,rules:V,ref_key:"login",ref:p,"label-width":"0px",class:"ms-content"},{default:a(()=>[o(t,{prop:"username"},{default:a(()=>[o(e,{modelValue:r.username,"onUpdate:modelValue":s[0]||(s[0]=n=>r.username=n),placeholder:"\u7528\u6237\u540D"},{prepend:a(()=>[o(l,{icon:u(L)},null,8,["icon"])]),_:1},8,["modelValue"])]),_:1}),o(t,{prop:"password"},{default:a(()=>[o(e,{type:"password",placeholder:"\u5BC6\u7801",modelValue:r.password,"onUpdate:modelValue":s[1]||(s[1]=n=>r.password=n),onKeyup:s[2]||(s[2]=S(n=>v(p.value),["enter"]))},{prepend:a(()=>[o(l,{icon:u(M)},null,8,["icon"])]),_:1},8,["modelValue"])]),_:1}),d("div",G,[o(l,{type:"primary",onClick:s[3]||(s[3]=n=>v(p.value))},{default:a(()=>[T(" \u767B \u5F55\xA0"),o(c,null,{default:a(()=>[o(i)]),_:1})]),_:1})])]),_:1},8,["model"])])]),u(f).companyName?(b(),h("div",H,F(u(f).companyName),1)):q("",!0)])}}});const te=U(Q,[["__scopeId","data-v-0fd4c22f"]]);export{te as default};
|
@ -0,0 +1 @@
|
||||
import{m as t}from"./manage-list.8ab8e06b.js";import{g as s,e,d as r,a as i}from"./user.0bac8e4f.js";import{d as n,o,c as a,b as c}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";import"./send_request.cc43fdb9.js";const p={class:"container"},L=n({__name:"privilege-user-setting",setup(d){return(m,u)=>(o(),a("div",p,[c(t,{"list-func":s,"add-func":e,"edit-func":e,"delete-func":r,"export-func":i,"edit-permiss":"privilege-user-setting"},null,8,["list-func","add-func","edit-func","delete-func","export-func"])]))}});export{L as default};
|
@ -0,0 +1 @@
|
||||
import{m}from"./manage-list.8ab8e06b.js";import{s}from"./send_request.cc43fdb9.js";import{d as o,o as n,c as p,b as a}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";function c(e){var r,i;let t=JSON.parse(JSON.stringify(e));return delete t.timestamp,Array.isArray(e.timestamp)&&e.timestamp.length==2&&(t.startTime=(r=e.timestamp[0])==null?void 0:r.getTime(),t.endTime=(i=e.timestamp[1])==null?void 0:i.getTime()),s({url:"/access/report/manage/getReportList",method:"GET",params:t})}function l(e){var r,i;let t=JSON.parse(JSON.stringify(e));return delete t.timestamp,Array.isArray(e.timestamp)&&e.timestamp.length==2&&(t.startTime=(r=e.timestamp[0])==null?void 0:r.getTime(),t.endTime=(i=e.timestamp[1])==null?void 0:i.getTime()),s({url:"/access/report/manage/exportReportList",method:"GET",params:t})}const u={class:"container"},h=o({__name:"report-log",setup(e){return(t,r)=>(n(),p("div",u,[a(m,{"list-func":c,"export-func":l,"edit-permiss":"privilege-user-setting"},null,8,["list-func","export-func"])]))}});export{h as default};
|
@ -0,0 +1 @@
|
||||
import{bU as O,bV as S,bW as P,bX as j,bY as L,bP as b}from"./index.f859bf4e.js";import{v as N}from"./el-input.f35758e8.js";var o=O,g=Object.prototype.hasOwnProperty,x=Array.isArray,s={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:o.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},E=function(i){return i.replace(/&#(\d+);/g,function(e,r){return String.fromCharCode(parseInt(r,10))})},v=function(i,e){return i&&typeof i=="string"&&e.comma&&i.indexOf(",")>-1?i.split(","):i},A="utf8=%26%2310003%3B",D="utf8=%E2%9C%93",H=function(e,r){var n={},c=r.ignoreQueryPrefix?e.replace(/^\?/,""):e,u=r.parameterLimit===1/0?void 0:r.parameterLimit,t=c.split(r.delimiter,u),l=-1,a,f=r.charset;if(r.charsetSentinel)for(a=0;a<t.length;++a)t[a].indexOf("utf8=")===0&&(t[a]===D?f="utf-8":t[a]===A&&(f="iso-8859-1"),l=a,a=t.length);for(a=0;a<t.length;++a)if(a!==l){var d=t[a],p=d.indexOf("]="),h=p===-1?d.indexOf("="):p+1,y,m;h===-1?(y=r.decoder(d,s.decoder,f,"key"),m=r.strictNullHandling?null:""):(y=r.decoder(d.slice(0,h),s.decoder,f,"key"),m=o.maybeMap(v(d.slice(h+1),r),function(w){return r.decoder(w,s.decoder,f,"value")})),m&&r.interpretNumericEntities&&f==="iso-8859-1"&&(m=E(m)),d.indexOf("[]=")>-1&&(m=x(m)?[m]:m),g.call(n,y)?n[y]=o.combine(n[y],m):n[y]=m}return n},C=function(i,e,r,n){for(var c=n?e:v(e,r),u=i.length-1;u>=0;--u){var t,l=i[u];if(l==="[]"&&r.parseArrays)t=[].concat(c);else{t=r.plainObjects?Object.create(null):{};var a=l.charAt(0)==="["&&l.charAt(l.length-1)==="]"?l.slice(1,-1):l,f=parseInt(a,10);!r.parseArrays&&a===""?t={0:c}:!isNaN(f)&&l!==a&&String(f)===a&&f>=0&&r.parseArrays&&f<=r.arrayLimit?(t=[],t[f]=c):a!=="__proto__"&&(t[a]=c)}c=t}return c},Q=function(e,r,n,c){if(!!e){var u=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,t=/(\[[^[\]]*])/,l=/(\[[^[\]]*])/g,a=n.depth>0&&t.exec(u),f=a?u.slice(0,a.index):u,d=[];if(f){if(!n.plainObjects&&g.call(Object.prototype,f)&&!n.allowPrototypes)return;d.push(f)}for(var p=0;n.depth>0&&(a=l.exec(u))!==null&&p<n.depth;){if(p+=1,!n.plainObjects&&g.call(Object.prototype,a[1].slice(1,-1))&&!n.allowPrototypes)return;d.push(a[1])}return a&&d.push("["+u.slice(a.index)+"]"),C(d,r,n,c)}},T=function(e){if(!e)return s;if(e.decoder!==null&&e.decoder!==void 0&&typeof e.decoder!="function")throw new TypeError("Decoder has to be a function.");if(typeof e.charset<"u"&&e.charset!=="utf-8"&&e.charset!=="iso-8859-1")throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var r=typeof e.charset>"u"?s.charset:e.charset;return{allowDots:typeof e.allowDots>"u"?s.allowDots:!!e.allowDots,allowPrototypes:typeof e.allowPrototypes=="boolean"?e.allowPrototypes:s.allowPrototypes,allowSparse:typeof e.allowSparse=="boolean"?e.allowSparse:s.allowSparse,arrayLimit:typeof e.arrayLimit=="number"?e.arrayLimit:s.arrayLimit,charset:r,charsetSentinel:typeof e.charsetSentinel=="boolean"?e.charsetSentinel:s.charsetSentinel,comma:typeof e.comma=="boolean"?e.comma:s.comma,decoder:typeof e.decoder=="function"?e.decoder:s.decoder,delimiter:typeof e.delimiter=="string"||o.isRegExp(e.delimiter)?e.delimiter:s.delimiter,depth:typeof e.depth=="number"||e.depth===!1?+e.depth:s.depth,ignoreQueryPrefix:e.ignoreQueryPrefix===!0,interpretNumericEntities:typeof e.interpretNumericEntities=="boolean"?e.interpretNumericEntities:s.interpretNumericEntities,parameterLimit:typeof e.parameterLimit=="number"?e.parameterLimit:s.parameterLimit,parseArrays:e.parseArrays!==!1,plainObjects:typeof e.plainObjects=="boolean"?e.plainObjects:s.plainObjects,strictNullHandling:typeof e.strictNullHandling=="boolean"?e.strictNullHandling:s.strictNullHandling}},_=function(i,e){var r=T(e);if(i===""||i===null||typeof i>"u")return r.plainObjects?Object.create(null):{};for(var n=typeof i=="string"?H(i,r):i,c=r.plainObjects?Object.create(null):{},u=Object.keys(n),t=0;t<u.length;++t){var l=u[t],a=Q(l,n[l],r,typeof i=="string");c=o.merge(c,a,r)}return r.allowSparse===!0?c:o.compact(c)},$=S,I=_,U=P,V={formats:U,parse:I,stringify:$};async function M({url:i,method:e="POST",params:r,useQS:n=!1,callback:c}){if(!i)return!1;const u=N.service({lock:!0,text:"\u8BF7\u7A0D\u5019",background:"rgba(0, 0, 0, 0.7)"});let t={baseURL:j.backendHost,url:i,method:e,withCredentials:!0};return e.toUpperCase()=="POST"?(t.headers={"content-type":"application/x-www-form-urlencoded"},t.data=n?V.stringify(r):r):e.toUpperCase()=="GET"&&(t.params=r),L(t).then(l=>{let a=l.data;if(!a.success)return b.error((a==null?void 0:a.msg)||"\u670D\u52A1\u5668\u9519\u8BEF"),null;let f=a.data;return typeof c=="function"&&c(f),f}).catch(l=>(console.error(l),b.error(l.message),!1)).finally(()=>{u.close()})}export{M as s};
|
@ -0,0 +1 @@
|
||||
import{m as r}from"./manage-list.8ab8e06b.js";import{s as t}from"./send_request.cc43fdb9.js";import{d as a,o as n,c as s,b as u}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";function i(e){return t({url:"/shop/good/manage/getCategoryList",method:"GET",params:e})}function o(e){return t({url:"/shop/good/manage/editCategory",method:"POST",useQS:!0,params:e})}function c(e){return t({url:"/shop/good/manage/deleteCategory",method:"POST",useQS:!0,params:e})}function d(e){return t({url:"/shop/good/manage/exportCategoryList",method:"GET",params:e})}const m={class:"container"},L=a({__name:"shop-cate-setting",setup(e){return(p,f)=>(n(),s("div",m,[u(r,{"list-func":i,"add-func":o,"edit-func":o,"delete-func":c,"export-func":d,"edit-permiss":"shop-cate-setting"},null,8,["list-func","add-func","edit-func","delete-func","export-func"])]))}});export{L as default};
|
@ -0,0 +1 @@
|
||||
import{m as n}from"./manage-list.8ab8e06b.js";import{s as e}from"./send_request.cc43fdb9.js";import{d as r,o as s,c as d,b as a}from"./index.f859bf4e.js";import"./el-overlay.1542ee54.js";import"./el-input.f35758e8.js";import"./el-progress.d53d438b.js";function u(o){return e({url:"/shop/good/manage/getGoodList",method:"GET",params:o})}function t(o){return e({url:"/shop/good/manage/editGood",method:"POST",useQS:!0,params:o})}function i(o){return e({url:"/shop/good/manage/deleteGood",method:"POST",useQS:!0,params:o})}function m(o){return e({url:"/shop/good/manage/exportGoodList",method:"GET",params:o})}const c={class:"container"},L=r({__name:"shop-good-setting",setup(o){return(p,f)=>(s(),d("div",c,[a(n,{"list-func":u,"add-func":t,"edit-func":t,"delete-func":i,"export-func":m,"edit-permiss":"shop-good-setting"},null,8,["list-func","add-func","edit-func","delete-func","export-func"])]))}});export{L as default};
|
@ -0,0 +1 @@
|
||||
import{s as r}from"./send_request.cc43fdb9.js";function u({username:e,password:s}){return r({url:"/user/login",method:"POST",useQS:!0,params:{username:e,password:s}})}function a(e){return r({url:"/user/manage/getUserList",method:"GET",params:e})}function n(e){return r({url:"/user/manage/editUser",method:"POST",useQS:!0,params:e})}function o(e){return r({url:"/user/manage/deleteUser",method:"POST",useQS:!0,params:e})}function m(e){return r({url:"/user/manage/exportUserList",method:"GET",params:e})}export{m as a,o as d,n as e,a as g,u};
|
@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Cropper.js v1.5.13
|
||||
* https://fengyuanchen.github.io/cropperjs
|
||||
*
|
||||
* Copyright 2015-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2022-11-20T05:30:43.444Z
|
||||
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-wrap-box,.cropper-canvas{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:#3399ffbf;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:calc(100% / 3);left:0;top:calc(100% / 3);width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:calc(100% / 3);top:0;width:calc(100% / 3)}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:before,.cropper-center:after{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width: 768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width: 992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width: 1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}.info[data-v-cdea44c0]{text-align:center;padding:35px 0}.info-image[data-v-cdea44c0]{position:relative;margin:auto;width:100px;height:100px;background:#f8f8f8;border:1px solid #eee;border-radius:50px;overflow:hidden}.info-edit[data-v-cdea44c0]{display:flex;justify-content:center;align-items:center;position:absolute;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.5);opacity:0;transition:opacity .3s ease}.info-edit i[data-v-cdea44c0]{color:#eee;font-size:25px}.info-image:hover .info-edit[data-v-cdea44c0]{opacity:1}.info-name[data-v-cdea44c0]{margin:15px 0 10px;font-size:24px;font-weight:500;color:#262626}.crop-demo-btn[data-v-cdea44c0]{position:relative}.crop-input[data-v-cdea44c0]{position:absolute;width:100px;height:40px;left:0;top:0;opacity:0;cursor:pointer}
|
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title></title>
|
||||
<link rel="stylesheet" href="https://at.alicdn.com/t/font_830376_qzecyukz0s.css">
|
||||
<script type="module" crossorigin src="./assets/index.f859bf4e.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index.87e2e9b7.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
||||
</html>
|
@ -61,6 +61,13 @@ public class AccessLogController {
|
||||
return Res.error("参数错误");
|
||||
}
|
||||
|
||||
// 推送到门禁端
|
||||
JSONObject websocketData = new JSONObject();
|
||||
websocketData.put("gateId", gateId);
|
||||
websocketData.put("action", "onopen");
|
||||
String websocketJSON = websocketData.toString();
|
||||
WebSocketServer.sendAllMessage(websocketJSON);
|
||||
|
||||
AccessLog accessLog = new AccessLog();
|
||||
accessLog.setId(null);
|
||||
accessLog.setType(type);
|
||||
|
@ -58,6 +58,14 @@ public class GateController {
|
||||
Long gateId = Long.valueOf(id);
|
||||
Gate gate = gateService.getGateById(gateId);
|
||||
GateVO gateVO = GateVO.convertFrom(gate);
|
||||
|
||||
// 推送到门禁端
|
||||
JSONObject websocketData = new JSONObject();
|
||||
websocketData.put("gateId", id);
|
||||
websocketData.put("action", "onscan");
|
||||
String websocketJSON = websocketData.toString();
|
||||
WebSocketServer.sendAllMessage(websocketJSON);
|
||||
|
||||
return Res.success(gateVO);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.cxyxiaomo.epp.access.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cxyxiaomo.epp.access.pojo.UnlimitedQRCodeParam;
|
||||
import com.cxyxiaomo.epp.access.service.WeChatTokenServiceImpl;
|
||||
import com.cxyxiaomo.epp.common.response.Res;
|
||||
@ -47,7 +48,28 @@ public class WeChatTokenController {
|
||||
unlimitedQRCodeParam.setIsHyaline(isHyaline);
|
||||
okhttp3.ResponseBody responseBody = weChatTokenService.getUnlimitedQRCodeFromApi(accessToken, unlimitedQRCodeParam);
|
||||
|
||||
try {
|
||||
// {"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 6446bac4-4a6b0410-118a16e7"}
|
||||
if (Objects.requireNonNull(responseBody.contentType()).subtype().equals("json")) {
|
||||
// 返回了 JSON 说明失败了
|
||||
String jsonString = responseBody.string();
|
||||
JSONObject jsonObject = JSONObject.parseObject(jsonString);
|
||||
String errcode = jsonObject.getString("errcode");
|
||||
if (errcode.equals("40001")) {
|
||||
// 重新获取 Access Token
|
||||
accessToken = weChatTokenService.getAccessToken(true);
|
||||
responseBody = weChatTokenService.getUnlimitedQRCodeFromApi(accessToken, unlimitedQRCodeParam);
|
||||
} else if (errcode.equals("40013")) {
|
||||
System.out.println("40013 invalid appid 不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写\n" +
|
||||
"docs: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 返回了图片,直接返回
|
||||
return responseBody.bytes();
|
||||
} catch (NullPointerException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = "/rpc/getOpenIdFromApi")
|
||||
|
@ -18,7 +18,7 @@ public class WebSocketServer {
|
||||
private Session session;
|
||||
|
||||
// session集合,存放对应的session
|
||||
private static ConcurrentHashMap<Integer, Session> sessionPool = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();
|
||||
|
||||
// concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。
|
||||
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
|
||||
@ -30,7 +30,7 @@ public class WebSocketServer {
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam(value = "userId") Integer userId) {
|
||||
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
|
||||
log.info("WebSocket建立连接中,连接用户ID:{}", userId);
|
||||
try {
|
||||
Session historySession = sessionPool.get(userId);
|
||||
@ -84,7 +84,7 @@ public class WebSocketServer {
|
||||
* @param userId 用户ID
|
||||
* @param message 发送的消息
|
||||
*/
|
||||
public static void sendMessageByUser(Integer userId, String message) {
|
||||
public static void sendMessageByUser(String userId, String message) {
|
||||
log.info("用户ID:" + userId + ",推送内容:" + message);
|
||||
Session session = sessionPool.get(userId);
|
||||
try {
|
||||
|
@ -35,12 +35,18 @@ public class WeChatTokenServiceImpl implements WeChatTokenService {
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
return getAccessToken(false);
|
||||
}
|
||||
|
||||
public String getAccessToken(Boolean forceUpdate) {
|
||||
if (!forceUpdate) {
|
||||
// 首先从数据库中查询是否存在 access_token
|
||||
// 如果存在且没有过期,那么就直接返回(距离失效时间小于 3 分钟就当作过期)
|
||||
Setting atSetting = accessDao.getValueByKey(SETTING_KEY);
|
||||
if (atSetting != null && LocalDateTime.now().plusMinutes(3L).compareTo(atSetting.getTime()) < 0) {
|
||||
return atSetting.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// 否则则去请求一个新的 access_token
|
||||
JSONObject jsonObject = getAccessTokenFromApi();
|
||||
|
@ -2,18 +2,31 @@ package com.cxyxiaomo.epp.shop.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cxyxiaomo.epp.PageTable.enums.AddType;
|
||||
import com.cxyxiaomo.epp.PageTable.enums.EditType;
|
||||
import com.cxyxiaomo.epp.PageTable.enums.FieldType;
|
||||
import com.cxyxiaomo.epp.PageTable.enums.SearchType;
|
||||
import com.cxyxiaomo.epp.PageTable.query.PageQuery;
|
||||
import com.cxyxiaomo.epp.PageTable.utils.FieldBuilder;
|
||||
import com.cxyxiaomo.epp.PageTable.utils.FieldMapperBuilder;
|
||||
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleBuilder;
|
||||
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleListBuilder;
|
||||
import com.cxyxiaomo.epp.common.enums.OrderStatus;
|
||||
import com.cxyxiaomo.epp.common.pojo.Order;
|
||||
import com.cxyxiaomo.epp.common.pojo.OrderDetail;
|
||||
import com.cxyxiaomo.epp.common.query.OrderQuery;
|
||||
import com.cxyxiaomo.epp.common.response.Res;
|
||||
import com.cxyxiaomo.epp.common.vo.GoodVO;
|
||||
import com.cxyxiaomo.epp.common.vo.OrderDetailVO;
|
||||
import com.cxyxiaomo.epp.common.vo.OrderVO;
|
||||
import com.cxyxiaomo.epp.shop.service.GoodService;
|
||||
import com.cxyxiaomo.epp.shop.service.OrderService;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -30,8 +43,8 @@ public class OrderController {
|
||||
/**
|
||||
* 小程序端创建订单
|
||||
*
|
||||
* @param userId 下单用户
|
||||
* @param orderList 下单商品 [ { goodId, count }, ... ]
|
||||
* @param params userId 下单用户
|
||||
* @param params orderList 下单商品 [ { goodId, count }, ... ]
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/miniprogram/createOrder")
|
||||
@ -184,6 +197,12 @@ public class OrderController {
|
||||
return Res.success(success ? "支付成功" : "支付失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户取消订单
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/miniprogram/cancelOrder")
|
||||
@ResponseBody
|
||||
public Res cancelOrder(@RequestBody JSONObject params) {
|
||||
@ -224,6 +243,106 @@ public class OrderController {
|
||||
return Res.success(success ? "取消成功" : "取消失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单发货
|
||||
*
|
||||
* @param orderId
|
||||
* @param expressId
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/manage/deliverOrder")
|
||||
@ResponseBody
|
||||
public Res deliverOrder(Long orderId, String expressId, String comment) {
|
||||
if (orderId == null || expressId == null || comment == null) {
|
||||
return Res.error("参数错误");
|
||||
}
|
||||
|
||||
if (expressId.equals("") && comment.equals("")) {
|
||||
return Res.error("运单号 和 发货备注 不可同时为空");
|
||||
}
|
||||
|
||||
// 查询订单详情
|
||||
Order order = orderService.getOrderById(orderId);
|
||||
if (order == null) {
|
||||
return Res.error("订单不存在");
|
||||
}
|
||||
|
||||
//判断是否可以发货
|
||||
OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
|
||||
switch (orderStatus) {
|
||||
case PENDING:
|
||||
return Res.error("订单尚未支付,不可发货");
|
||||
case PROCESSING: // 订单未发货
|
||||
// 更新订单发货信息
|
||||
orderService.updateOrderShipInfo(orderId, expressId, comment);
|
||||
// 更新支付信息
|
||||
orderService.updateOrderStatus(orderId, OrderStatus.SHIPPED);
|
||||
return Res.success("发货成功");
|
||||
case SHIPPED: // 订单已发货,修改发货信息
|
||||
// 更新订单发货信息
|
||||
orderService.updateOrderShipInfo(orderId, expressId, comment);
|
||||
return Res.success("发货信息修改成功");
|
||||
case DELIVERED:
|
||||
return Res.error("订单已完成,无法再次发货");
|
||||
case CANCELLED:
|
||||
return Res.error("订单已取消,不可发货");
|
||||
default:
|
||||
return Res.error("当前订单状态不可发货");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员取消订单
|
||||
*
|
||||
* @param orderId
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/manage/cancelOrder")
|
||||
@ResponseBody
|
||||
public Res cancelOrderByManager(Long orderId) {
|
||||
if (orderId == null) {
|
||||
return Res.error("参数错误");
|
||||
}
|
||||
|
||||
// 查询订单详情
|
||||
Order order = orderService.getOrderById(orderId);
|
||||
if (order == null) {
|
||||
return Res.error("订单不存在");
|
||||
}
|
||||
|
||||
//判断是否可以取消
|
||||
OrderStatus orderStatus = OrderStatus.get(order.getOrderStatus());
|
||||
switch (orderStatus) {
|
||||
case PENDING:
|
||||
// 更新订单发货信息
|
||||
orderService.updateOrderShipInfo(orderId, "", "管理员取消了您的订单,如有疑问请联系管理员");
|
||||
// 更新支付信息
|
||||
orderService.updateOrderStatus(orderId, OrderStatus.CANCELLED);
|
||||
return Res.success("操作成功");
|
||||
case PROCESSING:
|
||||
// 更新订单发货信息
|
||||
orderService.updateOrderShipInfo(orderId, "", "管理员取消了您的订单,费用已退回至您的帐户,如有疑问请联系管理员");
|
||||
// 更新支付信息
|
||||
orderService.updateOrderStatus(orderId, OrderStatus.CANCELLED);
|
||||
return Res.success("操作成功");
|
||||
case SHIPPED:
|
||||
return Res.error("订单已发货,不可取消");
|
||||
case DELIVERED:
|
||||
return Res.error("订单已送达,不可取消");
|
||||
case CANCELLED:
|
||||
return Res.error("订单已取消");
|
||||
default:
|
||||
return Res.error("当前订单状态无法取消");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单确认收货
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/miniprogram/confirmOrder")
|
||||
@ResponseBody
|
||||
public Res confirmOrder(@RequestBody JSONObject params) {
|
||||
@ -261,4 +380,189 @@ public class OrderController {
|
||||
|
||||
return Res.success(success ? "确认收货成功" : "确认收货失败");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/manage/getOrderList")
|
||||
@ResponseBody
|
||||
public Res getOrderList(PageQuery pageQuery, OrderQuery orderQuery) {
|
||||
// 查询分页数据
|
||||
PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize());
|
||||
List<Order> orderList = orderService.getOrderList(orderQuery);
|
||||
PageInfo<Order> orderPageInfo = new PageInfo<>(orderList);
|
||||
List<Order> list = orderPageInfo.getList();
|
||||
List<OrderVO> voList = OrderVO.convertFrom(list);
|
||||
|
||||
// id列 字段名(区分大小写;以VO中的变量名为准)
|
||||
// 新增、修改弹窗时,使用该列作为主键列进行操作
|
||||
String idFieldName = "id";
|
||||
|
||||
// 当前管理页面
|
||||
String pageName = "订单管理";
|
||||
|
||||
// 指定前端表格显示列
|
||||
JSONArray columns = FieldBuilder.create()
|
||||
.add("userId", "userId", "用户ID", "",
|
||||
FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("orderStatusCode", "orderStatusName", "订单状态", true,
|
||||
FieldType.TEXT, SearchType.SELECT, AddType.CAN_NOT_ADD, EditType.SELECT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, "订单状态",
|
||||
FieldRuleListBuilder.create()
|
||||
.add(FieldRuleBuilder.create("订单状态").required()),
|
||||
null
|
||||
)
|
||||
.add("orderPrice", "orderPrice", "订单价格", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("orderDate", "orderDate", "下单时间", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("payDate", "payDate", "支付时间", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("cancelDate", "cancelDate", "取消时间", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("shipDate", "shipDate", "发货时间", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("deliverDate", "deliverDate", "送达时间", "",
|
||||
FieldType.TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("expressId", "expressId", "运单号", "",
|
||||
FieldType.TEXT, SearchType.INPUT, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.add("comment", "comment", "发货备注", "",
|
||||
FieldType.LONG_TEXT, SearchType.CAN_NOT_SEARCH, AddType.CAN_NOT_ADD, EditType.CAN_NOT_EDIT,
|
||||
FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
|
||||
null, null, null, null
|
||||
)
|
||||
.build();
|
||||
|
||||
// 指定需要翻译的字段
|
||||
OrderStatus[] orderStatusList = OrderStatus.values();
|
||||
HashMap<String, String> orderStatusMap = new HashMap<>(orderStatusList.length);
|
||||
for (OrderStatus orderStatus : orderStatusList) {
|
||||
orderStatusMap.put(orderStatus.getValue(), orderStatus.toString());
|
||||
}
|
||||
// build
|
||||
JSONArray fieldMapper = FieldMapperBuilder.create()
|
||||
.add("orderStatusCode", "orderStatusName", orderStatusMap)
|
||||
.build();
|
||||
|
||||
// 拼装返回结果
|
||||
JSONObject map = new JSONObject(6);
|
||||
map.put("total", orderPageInfo.getTotal());
|
||||
map.put("list", voList);
|
||||
map.put("columns", columns);
|
||||
map.put("fieldMapper", fieldMapper);
|
||||
map.put("idFieldName", idFieldName);
|
||||
map.put("pageName", pageName);
|
||||
|
||||
// 返回结果
|
||||
return Res.success(map);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 编辑订单
|
||||
// *
|
||||
// * @return
|
||||
// */
|
||||
// @PostMapping("/manage/editOrder")
|
||||
// @ResponseBody
|
||||
// public Res editOrder(@ModelAttribute OrderVO OrderVO) {
|
||||
// Order Order = OrderVO.convertTo(OrderVO);
|
||||
//
|
||||
// // 先查询订单是否存在
|
||||
// Order existOrder = orderService.getOrderById(Order.getId());
|
||||
//
|
||||
// if (Order.getId() == null || Order.getId() < 1) {
|
||||
// // 新增订单
|
||||
// if (existOrder != null) {
|
||||
// return Res.error("订单已存在,操作失败");
|
||||
// }
|
||||
//
|
||||
// if (Order.getOrdersName() == null || "".equals(Order.getOrdersName())) {
|
||||
// return Res.error("订单名称不能为空");
|
||||
// }
|
||||
// Order.setId(null);
|
||||
// orderService.addOrder(Order);
|
||||
// } else {
|
||||
// // 修改订单
|
||||
// if (existOrder == null) {
|
||||
// return Res.error("订单不存在,操作失败");
|
||||
// }
|
||||
//
|
||||
// orderService.updateOrder(Order);
|
||||
// }
|
||||
// return Res.success(true);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 关闭订单
|
||||
// *
|
||||
// * @param id
|
||||
// * @return
|
||||
// */
|
||||
// @PostMapping("/manage/deleteOrder")
|
||||
// @ResponseBody
|
||||
// public Res deleteOrder(Long id) {
|
||||
// if (id == null || id <= 0) {
|
||||
// return Res.error("订单不存在,删除失败");
|
||||
// }
|
||||
// // 先查询订单是否存在
|
||||
// Order existOrder = orderService.getOrderById(id);
|
||||
// if (existOrder == null) {
|
||||
// return Res.error("订单不存在,删除失败");
|
||||
// }
|
||||
// boolean b = orderService.deleteOrder(existOrder.getId());
|
||||
// return Res.success(b);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 导出订单列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/manage/exportOrderList")
|
||||
@ResponseBody
|
||||
public Res exportOrderList(OrderQuery orderQuery) {
|
||||
List<Order> orderList = orderService.getOrderList(orderQuery);
|
||||
List<OrderVO> orderVOList = OrderVO.convertFrom(orderList);
|
||||
|
||||
// 当前时间
|
||||
Date now = Calendar.getInstance().getTime();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||
String dateTime = format.format(now);
|
||||
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("list", orderVOList);
|
||||
map.put("sheetName", "订单表-" + System.currentTimeMillis());
|
||||
map.put("fileName", "订单表_导出时间_" + dateTime);
|
||||
|
||||
return Res.success(map);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,13 +27,7 @@ public interface GoodDao {
|
||||
Integer deleteById(Integer id);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Manage
|
||||
public boolean addGood(Good good);
|
||||
|
||||
public boolean updateGood(Good good);
|
||||
|
@ -2,6 +2,7 @@ package com.cxyxiaomo.epp.shop.dao;
|
||||
|
||||
import com.cxyxiaomo.epp.common.pojo.Order;
|
||||
import com.cxyxiaomo.epp.common.pojo.OrderDetail;
|
||||
import com.cxyxiaomo.epp.common.query.OrderQuery;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -62,6 +63,19 @@ public interface OrderDao {
|
||||
*/
|
||||
int updateOrderStatus(@Param("orderId") Long orderId, @Param("orderStatus") String orderStatus);
|
||||
|
||||
/**
|
||||
* 更新订单发货信息
|
||||
*
|
||||
* @param orderId
|
||||
* @param expressId
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
int updateOrderShipInfo(@Param("orderId") Long orderId, @Param("expressId") String expressId, @Param("comment") String comment);
|
||||
|
||||
// 根据订单 ID 删除订单信息及订单详情信息
|
||||
int deleteOrderById(Long orderId);
|
||||
boolean deleteOrderById(Long orderId);
|
||||
|
||||
|
||||
public List<Order> getOrderList(OrderQuery orderQuery);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.cxyxiaomo.epp.common.enums.OrderStatus;
|
||||
import com.cxyxiaomo.epp.common.pojo.Good;
|
||||
import com.cxyxiaomo.epp.common.pojo.Order;
|
||||
import com.cxyxiaomo.epp.common.pojo.OrderDetail;
|
||||
import com.cxyxiaomo.epp.common.query.OrderQuery;
|
||||
import com.cxyxiaomo.epp.common.utils.SnowflakeManager;
|
||||
import com.cxyxiaomo.epp.common.vo.OrderDetailVO;
|
||||
import com.cxyxiaomo.epp.shop.dao.GoodDao;
|
||||
@ -132,4 +133,15 @@ public class OrderService {
|
||||
int affectRows = orderDao.updateOrderStatus(orderId, orderStatus.getValue());
|
||||
return affectRows > 0;
|
||||
}
|
||||
|
||||
public Boolean updateOrderShipInfo(Long orderId, String expressId, String comment) {
|
||||
int affectRows = orderDao.updateOrderShipInfo(orderId, expressId, comment);
|
||||
return affectRows > 0;
|
||||
}
|
||||
|
||||
|
||||
public List<Order> getOrderList(OrderQuery orderQuery) {
|
||||
return orderDao.getOrderList(orderQuery);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -95,7 +95,7 @@
|
||||
</update>
|
||||
|
||||
<!-- 根据订单 ID 删除订单信息及订单详情信息 -->
|
||||
<delete id="deleteOrderById" parameterType="java.lang.Integer">
|
||||
<delete id="deleteOrderById" parameterType="java.lang.Long">
|
||||
DELETE
|
||||
FROM `order`
|
||||
WHERE id = #{orderId};
|
||||
@ -104,4 +104,39 @@
|
||||
-- FROM goods_order_details
|
||||
-- WHERE order_id = #{orderId};
|
||||
</delete>
|
||||
|
||||
|
||||
<!-- manage 相关的 SQL -->
|
||||
<select id="getOrderList" resultType="com.cxyxiaomo.epp.common.pojo.Order"
|
||||
parameterType="com.cxyxiaomo.epp.common.query.OrderQuery">
|
||||
SELECT * FROM `order`
|
||||
<where>
|
||||
<if test="id != null">
|
||||
AND id = #{id}
|
||||
</if>
|
||||
<if test="userId != null">
|
||||
AND user_id = #{userId}
|
||||
</if>
|
||||
<if test="orderStatusCode != null and orderStatusCode != ''">
|
||||
AND order_status = #{orderStatusCode}
|
||||
</if>
|
||||
<if test="expressId != null and expressId != ''">
|
||||
AND express_id = #{expressId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 更新发货信息 -->
|
||||
<update id="updateOrderShipInfo" parameterType="com.cxyxiaomo.epp.common.pojo.Order">
|
||||
UPDATE `order`
|
||||
<set>
|
||||
<if test="expressId != null">
|
||||
express_id = #{expressId},
|
||||
</if>
|
||||
<if test="comment != null">
|
||||
`comment` = #{comment},
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{orderId}
|
||||
</update>
|
||||
</mapper>
|
||||
|
@ -11,6 +11,13 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
FIXME 环境配置
|
||||
|
||||
src
|
||||
- 线上环境:"https://epp.only4.work/access/index.html?inElectron=true"
|
||||
- 开发环境:"http://localhost/access/index.html?inElectron=true"
|
||||
-->
|
||||
<iframe src="https://epp-prod.only4.work/access/index.html?inElectron=true" frameborder="0"></iframe>
|
||||
<script src="./renderer.js" type="module"></script>
|
||||
</body>
|
||||
|
4
frontend/components.d.ts
vendored
@ -7,13 +7,10 @@ export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
Calender: typeof import('./src/components/calender.vue')['default']
|
||||
ContextMenu: typeof import('./src/components/context-menu.vue')['default']
|
||||
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
@ -38,6 +35,7 @@ declare module '@vue/runtime-core' {
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
Header: typeof import('./src/components/header.vue')['default']
|
||||
|
7
frontend/package-lock.json
generated
@ -24,6 +24,7 @@
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mockjs": "^1.0.7",
|
||||
"@vitejs/plugin-vue": "^3.0.0",
|
||||
"@vue/compiler-sfc": "^3.1.2",
|
||||
"typescript": "^4.6.4",
|
||||
@ -223,6 +224,12 @@
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mockjs": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/@types/mockjs/-/mockjs-1.0.7.tgz",
|
||||
"integrity": "sha512-OCxXz6hEaJOVpRwuJMiVY5a6LtJcih+br9gwB/Q8ooOBikvk5FpBQ31OlNimXo3EqKha1Z7PFBni+q9m+8NCWg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.14.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-18.14.0.tgz",
|
||||
|
@ -24,6 +24,7 @@
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mockjs": "^1.0.7",
|
||||
"@vitejs/plugin-vue": "^3.0.0",
|
||||
"@vue/compiler-sfc": "^3.1.2",
|
||||
"typescript": "^4.6.4",
|
||||
|
63
frontend/src/api/shop-order.js
Normal file
@ -0,0 +1,63 @@
|
||||
import send_request from '../utils/send_request';
|
||||
|
||||
/**
|
||||
* 获取订单列表
|
||||
* @returns
|
||||
*/
|
||||
export function getOrderList(params) {
|
||||
return send_request({
|
||||
url: '/shop/order/manage/getOrderList',
|
||||
method: 'GET',
|
||||
params: params,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取订单详情
|
||||
* @returns
|
||||
*/
|
||||
export function getOrderDetail(params) {
|
||||
return send_request({
|
||||
url: '/shop/order/miniprogram/orderDetail',
|
||||
method: 'GET',
|
||||
params: params,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 订单发货
|
||||
* @returns
|
||||
*/
|
||||
export function deliverOrder(params) {
|
||||
return send_request({
|
||||
url: '/shop/order/manage/deliverOrder',
|
||||
method: 'POST',
|
||||
useQS: true,
|
||||
params: params,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
* @returns
|
||||
*/
|
||||
export function withdrawOrder(params) {
|
||||
return send_request({
|
||||
url: '/shop/order/manage/cancelOrder',
|
||||
method: 'POST',
|
||||
useQS: true,
|
||||
params: params,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出订单列表
|
||||
* @returns
|
||||
*/
|
||||
export function exportOrderList(params) {
|
||||
return send_request({
|
||||
url: '/shop/order/manage/exportOrderList',
|
||||
method: 'GET',
|
||||
params: params,
|
||||
});
|
||||
};
|
@ -24,6 +24,24 @@ export function userLogout() {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @returns
|
||||
*/
|
||||
export function updatePwd({ oldpwd, newpwd }) {
|
||||
let userId = localStorage.getItem("ms_user_id")
|
||||
return send_request({
|
||||
url: '/user/updatePwd',
|
||||
method: 'POST',
|
||||
useQS: true,
|
||||
params: {
|
||||
"userId": userId,
|
||||
"oldpwd": oldpwd,
|
||||
"newpwd": newpwd,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @returns
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="header-right">
|
||||
<div class="header-user-con">
|
||||
<!-- 消息中心 -->
|
||||
<div class="btn-bell" @click="router.push('/tabs')">
|
||||
<div class="btn-bell" @click="router.push('/tabs')" v-if="false">
|
||||
<el-tooltip effect="dark" :content="message ? `有${message}条未读消息` : `消息中心`" placement="bottom">
|
||||
<i class="el-icon-lx-notice"></i>
|
||||
</el-tooltip>
|
||||
|
@ -56,17 +56,28 @@
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center" v-if="props.editFunc || props.deleteFunc">
|
||||
<el-table-column label="操作" width="220" align="center"
|
||||
v-if="props.editFunc || props.deleteFunc || props.customEditHandle">
|
||||
<template #default="scope">
|
||||
<el-button text :icon="Edit" @click="handleEdit(scope.$index, scope.row)"
|
||||
<template v-if="props.customEditHandle">
|
||||
<el-button text :icon="List"
|
||||
@click="props.customEditHandle((scope as any).$index, (scope as any).row, getData)"
|
||||
v-permiss="props.editPermiss">
|
||||
管理
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button text :icon="Edit" @click="handleEdit((scope as any).$index, (scope as any).row)"
|
||||
v-permiss="props.editPermiss" v-if="props.editFunc">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button text :icon="Delete" class="red" @click="handleDelete(scope.$index, scope.row)"
|
||||
<el-button text :icon="Delete" class="red"
|
||||
@click="handleDelete((scope as any).$index, (scope as any).row)"
|
||||
v-permiss="props.editPermiss" v-if="props.deleteFunc">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
@ -141,7 +152,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { FormInstance, FormRules, ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { Delete, Edit, Search, Plus, Filter, Download } from '@element-plus/icons-vue';
|
||||
import { Delete, Edit, Search, Plus, Filter, Download, List } from '@element-plus/icons-vue';
|
||||
import * as xlsx from 'xlsx';
|
||||
import Mock from 'mockjs';
|
||||
import ImageUpload from './image-upload.vue';
|
||||
@ -176,6 +187,12 @@ const props = defineProps({
|
||||
'editPermiss': {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
// 自定义修改按钮点击事件
|
||||
'customEditHandle': {
|
||||
type: Function,
|
||||
required: false,
|
||||
}
|
||||
})
|
||||
|
||||
@ -431,10 +448,10 @@ const saveEdit = async (formEl: FormInstance | undefined) => {
|
||||
var result;
|
||||
if (formId > 0) {
|
||||
// 修改记录
|
||||
var result = await props.editFunc(form)
|
||||
var result = await props.editFunc?.(form)
|
||||
} else {
|
||||
// 新增记录
|
||||
var result = await props.addFunc(form)
|
||||
var result = await props.addFunc?.(form)
|
||||
query.pageIndex = Math.ceil((pageTotal.value + 1) / query.pageSize);
|
||||
}
|
||||
console.log("result", result)
|
||||
@ -460,7 +477,7 @@ const handleDelete = (index: number, row: any) => {
|
||||
// 二次确认删除
|
||||
ElMessageBox.confirm('确定要删除吗?', '提示', { type: 'warning' })
|
||||
.then(async () => {
|
||||
var result = await props.deleteFunc({
|
||||
var result = await props.deleteFunc?.({
|
||||
id: row[idFieldName],
|
||||
})
|
||||
if (result) {
|
||||
@ -540,7 +557,7 @@ const handleExport = async () => {
|
||||
// 数据部分
|
||||
let excelList = dataList.map((row: any) => {
|
||||
// 通过翻译前的 key 拿数据
|
||||
return fieldNameList.map((field: any) => String(row[field]))
|
||||
return fieldNameList.map((field: any) => String(row[field] || ""))
|
||||
})
|
||||
excelList.unshift(firstRow) // 插入表头
|
||||
|
||||
|
@ -91,6 +91,11 @@ const items = [
|
||||
title: '商品管理',
|
||||
permiss: 'shop-good-setting',
|
||||
},
|
||||
{
|
||||
index: '/shop-order-setting',
|
||||
title: '订单管理',
|
||||
permiss: 'shop-order-setting',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -84,6 +84,15 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
component: () => import('../views/shop-good-setting.vue'),
|
||||
},
|
||||
{
|
||||
path: '/shop-order-setting',
|
||||
name: 'shop-order-setting',
|
||||
meta: {
|
||||
title: '订单管理',
|
||||
permiss: 'shop-order-setting',
|
||||
},
|
||||
component: () => import('../views/shop-order-setting.vue'),
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ export const usePermissStore = defineStore('permiss', {
|
||||
"shop",
|
||||
"shop-cate-setting",
|
||||
"shop-good-setting",
|
||||
"shop-order-setting",
|
||||
|
||||
"privilege",
|
||||
"privilege-user-setting",
|
||||
@ -46,6 +47,7 @@ export const usePermissStore = defineStore('permiss', {
|
||||
"shop",
|
||||
"shop-cate-setting",
|
||||
"shop-good-setting",
|
||||
"shop-order-setting",
|
||||
|
||||
"privilege",
|
||||
"privilege-user-setting",
|
||||
|
@ -22,6 +22,12 @@ export default {
|
||||
/**
|
||||
* 后端接口请求地址
|
||||
* (结尾加不加 / 都可)
|
||||
*
|
||||
* FIXME 环境配置
|
||||
*
|
||||
* backendHost
|
||||
* - 线上环境:"https://epp.only4.work/"
|
||||
* - 开发环境:"http://localhost/"
|
||||
*/
|
||||
backendHost: "https://epp-prod.only4.work/",
|
||||
};
|
||||
|
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" class="mgb20" style="height: 252px">
|
||||
<div class="user-info">
|
||||
<el-avatar :size="120" :src="imgurl" />
|
||||
@ -19,88 +17,6 @@
|
||||
<span>东莞</span>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="hover" style="height: 252px">
|
||||
<template #header>
|
||||
<div class="clearfix">
|
||||
<span>语言详情</span>
|
||||
</div>
|
||||
</template>
|
||||
Vue
|
||||
<el-progress :percentage="79.4" color="#42b983"></el-progress>
|
||||
TypeScript
|
||||
<el-progress :percentage="14" color="#f1e05a"></el-progress>
|
||||
CSS
|
||||
<el-progress :percentage="5.6"></el-progress>
|
||||
HTML
|
||||
<el-progress :percentage="1" color="#f56c6c"></el-progress>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-row :gutter="20" class="mgb20">
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }">
|
||||
<div class="grid-content grid-con-1">
|
||||
<el-icon class="grid-con-icon"><User /></el-icon>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">1234</div>
|
||||
<div>用户访问量</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }">
|
||||
<div class="grid-content grid-con-2">
|
||||
<el-icon class="grid-con-icon"><ChatDotRound /></el-icon>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">321</div>
|
||||
<div>系统消息</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="hover" :body-style="{ padding: '0px' }">
|
||||
<div class="grid-content grid-con-3">
|
||||
<el-icon class="grid-con-icon"><Goods /></el-icon>
|
||||
<div class="grid-cont-right">
|
||||
<div class="grid-num">500</div>
|
||||
<div>商品数量</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-card shadow="hover" style="height: 403px">
|
||||
<template #header>
|
||||
<div class="clearfix">
|
||||
<span>预警列表</span>
|
||||
<el-button style="float: right; padding: 3px 0" text>添加</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table :show-header="false" :data="todoList" style="width: 100%">
|
||||
<el-table-column width="40">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.status"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<div
|
||||
class="todo-item"
|
||||
:class="{
|
||||
'todo-item-del': scope.row.status
|
||||
}"
|
||||
>
|
||||
{{ scope.row.title }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -108,106 +24,11 @@
|
||||
import { ref, reactive } from 'vue';
|
||||
import imgurl from '../assets/img/img.jpg';
|
||||
|
||||
const roleMap = {
|
||||
|
||||
}
|
||||
const name = localStorage.getItem('ms_username');
|
||||
const role: string = name === 'admin' ? '超级管理员' : '普通用户';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.grid-cont-right {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.grid-num {
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.grid-con-icon {
|
||||
font-size: 50px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.grid-con-1 .grid-con-icon {
|
||||
background: rgb(45, 140, 240);
|
||||
}
|
||||
|
||||
.grid-con-1 .grid-num {
|
||||
color: rgb(45, 140, 240);
|
||||
}
|
||||
|
||||
.grid-con-2 .grid-con-icon {
|
||||
background: rgb(100, 213, 114);
|
||||
}
|
||||
|
||||
.grid-con-2 .grid-num {
|
||||
color: rgb(100, 213, 114);
|
||||
}
|
||||
|
||||
.grid-con-3 .grid-con-icon {
|
||||
background: rgb(242, 94, 67);
|
||||
}
|
||||
|
||||
.grid-con-3 .grid-num {
|
||||
color: rgb(242, 94, 67);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 2px solid #ccc;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.user-info-cont {
|
||||
padding-left: 50px;
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.user-info-cont div:first-child {
|
||||
font-size: 30px;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.user-info-list {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.user-info-list span {
|
||||
margin-left: 70px;
|
||||
}
|
||||
|
||||
.mgb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.todo-item {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.todo-item-del {
|
||||
text-decoration: line-through;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
@ -116,7 +116,10 @@ const submitForm = (formEl: FormInstance | undefined) => {
|
||||
if (!data) return;
|
||||
|
||||
console.log("login data", data, data.userInfo);
|
||||
|
||||
if (![1, 2].includes(data.userInfo?.roleId)) {
|
||||
ElMessage.error('您所在用户组无权登录当前系统');
|
||||
return;
|
||||
}
|
||||
ElMessage.success('登录成功');
|
||||
localStorage.setItem('ms_username', data.userInfo?.username);
|
||||
localStorage.setItem('ms_realname', data.userInfo?.realname);
|
||||
|
191
frontend/src/views/shop-order-setting.vue
Normal file
@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<manageList :list-func="shopOrderApi.getOrderList" :custom-edit-handle="editHandle"
|
||||
:export-func="shopOrderApi.exportOrderList" edit-permiss="shop-order-setting" />
|
||||
|
||||
<!-- 新增 / 编辑弹出框 -->
|
||||
<el-dialog title="管理订单" v-model="visible" style="width: 60%; min-width: 280px;">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单ID</span>
|
||||
{{ orderDetail.id || "" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单状态</span>
|
||||
<el-tag effect="plain" round>{{ orderDetail.orderStatus || "" }}</el-tag>
|
||||
{{ orderDetail.orderStatusCode || "" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">下单用户ID</span>
|
||||
{{ orderDetail.userId || "" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单价格</span>
|
||||
{{ orderDetail.orderPrice ? ('¥' + orderDetail.orderPrice) : "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">下单时间</span>
|
||||
{{ orderDetail.orderDate || "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单取消时间</span>
|
||||
{{ orderDetail.cancelDate || "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单支付时间</span>
|
||||
{{ orderDetail.payDate || "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单发货时间</span>
|
||||
{{ orderDetail.shipDate || "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">订单送达时间</span>
|
||||
{{ orderDetail.deliverDate || "-" }}
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">运单号</span>
|
||||
<template
|
||||
v-if="orderDetail.orderStatusCode != 'Processing' && orderDetail.orderStatusCode != 'Shipped'">
|
||||
{{ orderDetail.expressId || "-" }}
|
||||
</template>
|
||||
<el-input v-else v-model="shippingInfo.expressId" placeholder="Please input" />
|
||||
</p>
|
||||
<p class="line-height">
|
||||
<span class="row-index">发货备注</span>
|
||||
<template
|
||||
v-if="orderDetail.orderStatusCode != 'Processing' && orderDetail.orderStatusCode != 'Shipped'">
|
||||
{{ orderDetail.comment || "-" }}
|
||||
</template>
|
||||
<el-input v-else v-model="shippingInfo.comment" placeholder="Please input" />
|
||||
</p>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<p style="margin-bottom: 20px;">该订单中包含如下商品</p>
|
||||
<div style="max-height:50vh; overflow-y: scroll;">
|
||||
<el-card class="box-card" v-for="i in orderItem" :key="i.goodId"
|
||||
style="--el-card-padding: 10px; margin-bottom: 8px;">
|
||||
<div style="display: grid; grid-template-columns: 50px 1fr 60px; gap: 15px;">
|
||||
<img :src="i.good.picUrl" style="width: 60px; height: 60px;" />
|
||||
<div style="place-self: center left;">
|
||||
<p>{{ i.good.goodsName }}</p>
|
||||
<p style="color: grey; font-size: 12px;">商品ID: {{ i.goodId }}</p>
|
||||
</div>
|
||||
<div style="place-self: center; font-size: 16px;">{{ i.goodCount }} {{ i.good.unit }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 订单状态:PENDING("Pending", "等待确认"), -->
|
||||
<!-- 订单状态:PROCESSING("Processing", "已支付,等待发货中"), -->
|
||||
<!-- 订单状态:SHIPPED("Shipped", "已发货,等待确认收货"), -->
|
||||
<!-- 订单状态:DELIVERED("Delivered", "已送达"), -->
|
||||
<!-- 订单状态:CANCELLED("Cancelled", "已取消"); -->
|
||||
<!-- 该订单已被取消 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button v-if="orderDetail.orderStatusCode == 'Processing'" type="danger"
|
||||
@click="withdrawOrder">取消发货并退款</el-button>
|
||||
<el-button
|
||||
v-if="orderDetail.orderStatusCode == 'Processing' || orderDetail.orderStatusCode == 'Shipped'"
|
||||
type="primary" @click="saveEdit">保存发货信息</el-button>
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import manageList from '../components/manage-list.vue';
|
||||
import * as shopOrderApi from '../api/shop-order';
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { FormInstance, FormRules, ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { Delete, Edit, Search, Plus, Filter, Download } from '@element-plus/icons-vue';
|
||||
|
||||
const visible: any = ref(false);
|
||||
|
||||
const orderDetail = ref({} as any);
|
||||
const orderItem = ref([] as any);
|
||||
|
||||
const shippingInfo = ref({} as any); // 发货信息
|
||||
|
||||
let completeCallback: Function = () => { };
|
||||
|
||||
const editHandle = async function (tabIndex: number, row: any, refreshFunc: Function) {
|
||||
console.log("tabIndex", tabIndex)
|
||||
console.log("orderDetail", row)
|
||||
orderDetail.value = row // 订单详情
|
||||
|
||||
shippingInfo.value.expressId = row.expressId
|
||||
shippingInfo.value.comment = row.comment
|
||||
|
||||
completeCallback = refreshFunc
|
||||
visible.value = true
|
||||
|
||||
shopOrderApi.getOrderDetail({
|
||||
orderId: row.id
|
||||
}).then(function (data) {
|
||||
let orderGoods = {}
|
||||
data.goods.forEach((good: any) => {
|
||||
orderGoods[good.id] = good
|
||||
});
|
||||
|
||||
orderItem.value = data.orderItem.map((item: any) => {
|
||||
item.good = orderGoods[item.goodId]
|
||||
return item
|
||||
})
|
||||
|
||||
console.log("orderItem", orderItem.value)
|
||||
})
|
||||
}
|
||||
|
||||
const saveEdit = function () {
|
||||
// 保存发货信息
|
||||
ElMessageBox.confirm('确定要进行发货操作吗?发货后订单将不可撤销。(用户点击收货前仍可以修改发货信息)', '提示', { type: 'warning' })
|
||||
.then(async () => {
|
||||
shopOrderApi.deliverOrder({
|
||||
orderId: orderDetail.value.id,
|
||||
...shippingInfo.value
|
||||
}).then(function (data) {
|
||||
if (data) { // 如果出错则已经出提示了
|
||||
ElMessage.success({ message: data })
|
||||
visible.value = false
|
||||
completeCallback()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => { });
|
||||
}
|
||||
|
||||
const withdrawOrder = function () {
|
||||
// 取消订单
|
||||
ElMessageBox.confirm('确定要取消此订单吗?该操作不可撤销。', '提示', { type: 'warning' })
|
||||
.then(async () => {
|
||||
shopOrderApi.withdrawOrder({
|
||||
orderId: orderDetail.value.id,
|
||||
...shippingInfo.value
|
||||
}).then(function (data) {
|
||||
if (data) { // 如果出错则已经出提示了
|
||||
ElMessage.success({ message: data })
|
||||
visible.value = false
|
||||
completeCallback()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => { });
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line-height {
|
||||
line-height: 2.7em;
|
||||
}
|
||||
|
||||
.row-index {
|
||||
width: 110px;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
@ -16,7 +16,6 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-name">{{ name }}</div>
|
||||
<!-- <div class="info-desc">不可能!我的代码怎么可能会有bug!</div> -->
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@ -38,9 +37,6 @@
|
||||
<el-form-item label="确认密码:">
|
||||
<el-input type="password" v-model="form.new1"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="个人简介:">
|
||||
<el-input v-model="form.desc"></el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">保存</el-button>
|
||||
</el-form-item>
|
||||
@ -70,7 +66,7 @@ import VueCropper from 'vue-cropperjs';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
import avatar from '../assets/img/img.jpg';
|
||||
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
|
||||
import send_request from '../utils/send_request';
|
||||
import * as userApi from '../api/user';
|
||||
|
||||
const name = localStorage.getItem('ms_username');
|
||||
const user_id = localStorage.getItem('ms_user_id');
|
||||
@ -104,29 +100,16 @@ const onSubmit = async () => {
|
||||
|
||||
ElMessageBox.confirm('确认要修改密码吗?', '提示', {
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
userApi.updatePwd({
|
||||
oldpwd: form.old,
|
||||
newpwd: form.new,
|
||||
}).then((data) => {
|
||||
data && ElMessage.success(data);
|
||||
})
|
||||
.then(async () => {
|
||||
console.log("send_request v1/user/alterPSW")
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '请稍候',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
await send_request('v1/user/alterPSW', "POST", {
|
||||
"userId": form.user_id,
|
||||
"oldPSW": form.old,
|
||||
"newPSW": form.new
|
||||
}, (data: any) => {
|
||||
console.log(data);
|
||||
ElMessage.success('删除成功');
|
||||
// tableData.value.splice(index, 1);
|
||||
})
|
||||
loading.close();
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
}).catch((err) => {
|
||||
ElMessage.success('删除失败');
|
||||
console.log("err", err)
|
||||
});
|
||||
return;
|
||||
|
||||
|
@ -4,6 +4,13 @@ server
|
||||
listen 80;
|
||||
listen 443 ssl http2;
|
||||
|
||||
# 并发限制 限制当前站点最大并发数
|
||||
limit_conn perserver 50;
|
||||
# 单IP限制 限制单个IP访问最大并发数
|
||||
limit_conn perip 10;
|
||||
# 流量限制 限制每个请求的流量上限(单位:KB)
|
||||
limit_rate 8192k;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5203;
|
||||
|
||||
|
@ -22,9 +22,14 @@ App({
|
||||
},
|
||||
globalData: {
|
||||
// debugMode: true, // 是否展示调试内容
|
||||
baseUrl: true ? // Api 请求域名 不带最后的 /
|
||||
"https://epp-prod.only4.work" :
|
||||
"http://localhost",
|
||||
/**
|
||||
* FIXME 环境配置
|
||||
*
|
||||
* baseUrl
|
||||
* - 线上环境:'https://epp.only4.work'
|
||||
* - 开发环境:'http://localhost'
|
||||
*/
|
||||
baseUrl: "https://epp-prod.only4.work", // Api 请求域名 不带最后的 /
|
||||
userInfo: null
|
||||
}
|
||||
})
|
||||
|
@ -137,7 +137,7 @@ Page({
|
||||
filterList: filterList,
|
||||
filterActiveName: "全部",
|
||||
orderList: userOrder.orders.map(order => {
|
||||
order.displayDate = order.orderDate.replace("T", " ")
|
||||
order.displayDate = order.orderDate
|
||||
return order
|
||||
})
|
||||
})
|
||||
@ -153,7 +153,7 @@ Page({
|
||||
console.log("userOrder", userOrder)
|
||||
this.setData({
|
||||
orderList: userOrder.orders.map(order => {
|
||||
order.displayDate = order.orderDate.replace("T", " ")
|
||||
order.displayDate = order.orderDate
|
||||
return order
|
||||
})
|
||||
})
|
||||
|
@ -259,7 +259,7 @@ Page({
|
||||
this.setData({
|
||||
order: orderDetail.order,
|
||||
orderGoodList: orderGoodList,
|
||||
orderTime: orderDetail.order.orderDate.replace("T", " "),
|
||||
orderTime: orderDetail.order.orderDate,
|
||||
orderStatusCode: orderStatusCode,
|
||||
orderPrice: orderPrice,
|
||||
})
|
||||
|
@ -3,7 +3,7 @@
|
||||
"projectname": "weixin-miniprogram",
|
||||
"setting": {
|
||||
"compileHotReLoad": true,
|
||||
"urlCheck": true,
|
||||
"urlCheck": false,
|
||||
"bigPackageSizeSupport": true
|
||||
}
|
||||
}
|
145
论文中数据字典.md
@ -1,26 +1,21 @@
|
||||
> 使用 phpMyAdmin 导出,如果有修改,可以同步修改到论文正文
|
||||
|
||||
## apply1
|
||||
## access_log
|
||||
|
||||
表注释: *人员进出记录表*
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :---------- | :---------- | :--- | :----- | :--------------------------- |
|
||||
| id *(主键)* | int | 否 | | |
|
||||
| stu_id | int | 是 | *NULL* | 用户id |
|
||||
| issue | varchar(50) | 是 | *NULL* | 申请事由 |
|
||||
| transport | varchar(20) | 是 | *NULL* | 出行方式 |
|
||||
| place | varchar(50) | 是 | *NULL* | 目的地 |
|
||||
| start_time | datetime | 是 | *NULL* | 开始时间 |
|
||||
| end_time | datetime | 是 | *NULL* | 结束时间 |
|
||||
| state | int | 是 | 0 | 状态(0:审批中,1:通过,2:驳回) |
|
||||
| reason | varchar(20) | 是 | *NULL* | 驳回原因 |
|
||||
| :------------- | :---------------- | :--- | :---------------- | :------------------- |
|
||||
| id | bigint | 否 | | 雪花id |
|
||||
| time | datetime | 否 | CURRENT_TIMESTAMP | 进出时间 |
|
||||
| user_id | int | 否 | | 用户id |
|
||||
| user_real_name | varchar(255) | 是 | *NULL* | 用户真实姓名 |
|
||||
| gate_id | bigint | 否 | | 大门id |
|
||||
| type | enum('IN', 'OUT') | 是 | *NULL* | 类型(进门 OR 出门) |
|
||||
|
||||
### 索引
|
||||
没有已定义的索引!
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 10 | A | 否 | |
|
||||
|
||||
## community_gate
|
||||
## gate
|
||||
|
||||
表注释: *社区大门*
|
||||
|
||||
@ -32,38 +27,6 @@
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 0 | A | 否 | |
|
||||
|
||||
## count1
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :------------ | :------- | :--- | :----- | :------- |
|
||||
| date *(主键)* | date | 否 | | 日期 |
|
||||
| time | datetime | 是 | *NULL* | 时间 |
|
||||
| in_num | int | 是 | *NULL* | 入校人数 |
|
||||
| out_num | int | 是 | *NULL* | 出校人数 |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | date | 0 | A | 否 | |
|
||||
|
||||
## feedback1
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :---------- | :----------- | :--- | :----- | :--------- |
|
||||
| id *(主键)* | int | 否 | | |
|
||||
| title | varchar(255) | 是 | *NULL* | 反馈标题 |
|
||||
| content | longtext | 是 | *NULL* | 反馈内容 |
|
||||
| time | datetime | 是 | *NULL* | 反馈时间 |
|
||||
| user_id | int | 是 | *NULL* | 反馈用户id |
|
||||
| reply | varchar(255) | 是 | *NULL* | 回复 |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 5 | A | 否 | |
|
||||
@ -94,10 +57,10 @@
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :---------- | :---- | :--- | :--- | :---------- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 87 | A | 否 | |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 89 | A | 否 | |
|
||||
| category_id | BTREE | 否 | 否 | category_id | 8 | A | 是 | |
|
||||
| brand_id | BTREE | 否 | 否 | brand | 67 | A | 是 | |
|
||||
| sort_order | BTREE | 否 | 否 | sort_order | 25 | A | 是 | |
|
||||
| brand_id | BTREE | 否 | 否 | brand | 69 | A | 是 | |
|
||||
| sort_order | BTREE | 否 | 否 | sort_order | 27 | A | 是 | |
|
||||
|
||||
## goods_category
|
||||
|
||||
@ -111,22 +74,7 @@
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 7 | A | 否 | |
|
||||
|
||||
## notice1
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :---------- | :----------- | :--- | :----- | :--- |
|
||||
| id *(主键)* | int | 否 | | |
|
||||
| title | varchar(255) | 是 | *NULL* | 标题 |
|
||||
| content | longtext | 是 | *NULL* | 内容 |
|
||||
| time | date | 是 | *NULL* | 时间 |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 5 | A | 否 | |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 8 | A | 否 | |
|
||||
|
||||
## order
|
||||
|
||||
@ -138,13 +86,18 @@
|
||||
| order_status | enum('Pending', 'Processing', 'Shipped', 'Delivered', 'Cancelled') | 否 | | 订单状态 |
|
||||
| order_price | decimal(10,2) | 否 | | 订单总金额 |
|
||||
| pay_date | datetime | 是 | *NULL* | 订单支付时间 |
|
||||
| cancel_date | datetime | 是 | *NULL* | 订单取消时间 |
|
||||
| ship_date | datetime | 是 | *NULL* | 订单发货时间 |
|
||||
| deliver_date | datetime | 是 | *NULL* | 订单送达时间 |
|
||||
| express_id | varchar(500) | 是 | *NULL* | 快递单号 |
|
||||
| comment | text | 是 | *NULL* | 发货备注 |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :------ | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 4 | A | 否 | |
|
||||
| id | BTREE | 是 | 否 | id | 4 | A | 否 | |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 15 | A | 否 | |
|
||||
| id | BTREE | 是 | 否 | id | 15 | A | 否 | |
|
||||
| user_id | BTREE | 否 | 否 | user_id | 1 | A | 否 | |
|
||||
|
||||
## order_detail
|
||||
@ -161,9 +114,9 @@
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------- | :---- | :--- | :--- | :------- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 10 | A | 否 | |
|
||||
| order_id | BTREE | 否 | 否 | order_id | 4 | A | 否 | |
|
||||
| good_id | BTREE | 否 | 否 | good_id | 2 | A | 否 | |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 21 | A | 否 | |
|
||||
| order_id | BTREE | 否 | 否 | order_id | 15 | A | 否 | |
|
||||
| good_id | BTREE | 否 | 否 | good_id | 9 | A | 否 | |
|
||||
|
||||
## report
|
||||
|
||||
@ -180,7 +133,20 @@
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 1 | A | 否 | |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 12 | A | 否 | |
|
||||
|
||||
## role
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :---------- | :----------- | :--- | :--- | :------- |
|
||||
| id *(主键)* | int | 否 | | role_id |
|
||||
| role_name | varchar(255) | 否 | | roleName |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 6 | A | 否 | |
|
||||
|
||||
## setting
|
||||
|
||||
@ -199,41 +165,26 @@
|
||||
## user
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :-------------- | :----------- | :--- | :----- | :----------------------------------------------------------- |
|
||||
| :-------------- | :----------- | :--- | :----- | :--------------------------------------------- |
|
||||
| id *(主键)* | int | 否 | | |
|
||||
| username | varchar(20) | 否 | | 用户名 |
|
||||
| password | varchar(255) | 否 | | 密码 |
|
||||
| realname | varchar(20) | 是 | *NULL* | 真实姓名 |
|
||||
| id_number | varchar(18) | 是 | *NULL* | 身份证号 |
|
||||
| phone_number | varchar(11) | 是 | *NULL* | 手机号 |
|
||||
| role | int | 否 | | 角色 (0-超级管理员 1-工作人员 2-社区居民_房主 3-社区居民_家庭成员 4-社区居民_租客 5-访客) |
|
||||
| phone_number | varchar(20) | 是 | *NULL* | 手机号 |
|
||||
| role_id | int | 否 | | 角色id |
|
||||
| building_id | varchar(255) | 是 | *NULL* | 门栋号+单元号 |
|
||||
| doorplate | varchar(255) | 是 | *NULL* | 门牌号 |
|
||||
| permission | int | 否 | 0 | 进出权限 (0-无 1-继承(普通居民) 2-永久 3-限时) |
|
||||
| permission | varchar(20) | 否 | 0 | 进出权限 (0-无 1-继承(普通居民) 2-永久 3-限时) |
|
||||
| permission_time | datetime | 是 | *NULL* | 进出权限失效时间 |
|
||||
|
||||
### 索引
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 1 | A | 否 | |
|
||||
|
||||
## visitor1
|
||||
|
||||
| 字段 | 类型 | 空 | 默认 | 注释 |
|
||||
| :---------- | :----------- | :--- | :----- | :---------------------------------- |
|
||||
| id *(主键)* | int | 否 | | |
|
||||
| time | datetime | 是 | *NULL* | 预约时间 |
|
||||
| phone | varchar(20) | 是 | *NULL* | 预约用户id |
|
||||
| issue | varchar(255) | 是 | *NULL* | 预约事由 |
|
||||
| meet_name | varchar(20) | 是 | *NULL* | 会见人姓名 |
|
||||
| create_time | datetime | 是 | *NULL* | 创建时间 |
|
||||
| state | int | 是 | 0 | 状态(0:审批中,1:成功,2:驳回) |
|
||||
| wx_code | varchar(255) | 是 | *NULL* | 微信登录授权码 |
|
||||
|
||||
### 索引
|
||||
|
||||
|
||||
|
||||
| 键名 | 类型 | 唯一 | 紧凑 | 字段 | 基数 | 排序规则 | 空 | 注释 |
|
||||
| :------ | :---- | :--- | :--- | :--- | :--- | :------- | :--- | :--- |
|
||||
| :------- | :---- | :--- | :--- | :------- | :--- | :------- | :--- | :--- |
|
||||
| PRIMARY | BTREE | 是 | 否 | id | 1 | A | 否 | |
|
||||
| username | BTREE | 是 | 否 | username | 1 | A | 否 | |
|
||||
| wx_code | BTREE | 是 | 否 | wx_code | 1 | A | 是 | |
|