feat: 🚀 邮箱模板可以查看;修复部分bug
This commit is contained in:
parent
31225dfc4a
commit
c40b65cf66
197
ReadMe.md
197
ReadMe.md
|
@ -35,7 +35,7 @@ https://www.bilibili.com/video/BV1AYm8YSEKY/
|
||||||
|
|
||||||
### 安装docker内容
|
### 安装docker内容
|
||||||
|
|
||||||
如果使用是centos或者是rocky
|
#### centos或rocky
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# 更新yum 和 dnf
|
# 更新yum 和 dnf
|
||||||
|
@ -57,20 +57,75 @@ systemctl enable docker
|
||||||
systemctl start docker
|
systemctl start docker
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Ubuntu环境搭建
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get remove docker docker-engine docker.io containerd runc
|
||||||
|
sudo apt update
|
||||||
|
sudo apt upgrade
|
||||||
|
sudo apt-get install ca-certificates curl gnupg lsb-release
|
||||||
|
# 添加Docker官方GPG密钥
|
||||||
|
sudo curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
|
||||||
|
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
|
||||||
|
# 安装docker
|
||||||
|
sudo apt-get install docker-ce docker-ce-cli containerd.io
|
||||||
|
# 默认情况下,只有root用户和docker组的用户才能运行Docker命令。我们可以将当前用户添加到docker组,以避免每次使用Docker时都需要使用sudo,设置完成后退出当前用户之后再进入既可
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
# 运行docker
|
||||||
|
sudo systemctl start docker
|
||||||
|
# 安装工具
|
||||||
|
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
|
||||||
|
# 重启docker
|
||||||
|
sudo service docker restart
|
||||||
|
```
|
||||||
|
|
||||||
|
> 安装docker会可能会遇到镜像无法拉去问题试下面的几个镜像地址,根据你自己的需要进行配置不是所有人都需要;同时也不能保证地址真的有效!!!
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> # 如果遇到没有这个文件的直接输入命令进行创建既可,之后记得重启docker
|
||||||
|
> sudo touch /etc/docker/daemon.json
|
||||||
|
> sudo vim /etc/docker/daemon.json
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> 复制下面的内容到`daemon.json`
|
||||||
|
>
|
||||||
|
> ```json
|
||||||
|
> {
|
||||||
|
> "registry-mirrors": [
|
||||||
|
> "https://jockerhub.com",
|
||||||
|
> "https://dockerhub.icu",
|
||||||
|
> "https://docker.1panel.live",
|
||||||
|
> "https://gwsg6nw9.mirror.aliyuncs.com",
|
||||||
|
> "https://registry.docker-cn.com",
|
||||||
|
> "http://hub-mirror.c.163.com",
|
||||||
|
> "http://f1361db2.m.daocloud.io",
|
||||||
|
> "https://mirror.ccs.tencentyun.com",
|
||||||
|
> "https://phtv51hj.mirror.aliyuncs.com",
|
||||||
|
> "https://gwsg6nw9.mirror.aliyuncs.com"
|
||||||
|
> ]
|
||||||
|
> }
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> 重启docker
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> sudo systemctl restart docker.socket
|
||||||
|
> ```
|
||||||
|
|
||||||
### 安装Redis
|
### 安装Redis
|
||||||
|
|
||||||
#### 编写配置文件
|
#### 编写配置文件
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir /bunny/docker_data/my_redis/ -p
|
mkdir ~/docker/docker_data/redis_master/ -p
|
||||||
vim /bunny/docker_data/my_redis/redis.conf
|
vim ~/docker/docker_data/redis_master/redis.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
**添加以下内容**
|
**添加以下内容**
|
||||||
|
|
||||||
有注释大概率启动不了
|
有注释大概率启动不了
|
||||||
|
|
||||||
```
|
```properties
|
||||||
# bind 127.0.0.1 #注释掉这部分,使redis可以外部访问
|
# bind 127.0.0.1 #注释掉这部分,使redis可以外部访问
|
||||||
daemonize no #用守护线程的方式启动
|
daemonize no #用守护线程的方式启动
|
||||||
requirepass 123456
|
requirepass 123456
|
||||||
|
@ -80,7 +135,7 @@ tcp-keepalive 300 #防止出现远程主机强迫关闭了一个现有的连接
|
||||||
|
|
||||||
**删除注释**
|
**删除注释**
|
||||||
|
|
||||||
```
|
```properties
|
||||||
daemonize no
|
daemonize no
|
||||||
requirepass 123456
|
requirepass 123456
|
||||||
appendonly yes
|
appendonly yes
|
||||||
|
@ -89,40 +144,102 @@ tcp-keepalive 300
|
||||||
|
|
||||||
#### 启动Redis
|
#### 启动Redis
|
||||||
|
|
||||||
|
密码是上面的:`123456`
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker pull redis:7.0.10
|
docker pull redis:7.0.10
|
||||||
docker run -p 6379:6379 --name redis_master \
|
docker run -p 6379:6379 --name redis_master \
|
||||||
-v /bunny/docker_data/redis_master/redis.conf:/etc/redis/redis.conf \
|
-v ~/docker/docker_data/redis_master/redis.conf:/etc/redis/redis.conf \
|
||||||
-v/bunny/docker_data/redis_master/data:/data \
|
-v ~/docker/docker_data/redis_master/data:/data \
|
||||||
--restart=always -d redis:7.0.10 --appendonly yes
|
--restart=always -d redis:7.0.10 --appendonly yes
|
||||||
```
|
```
|
||||||
|
|
||||||
### 安装Minio
|
### 安装Minio
|
||||||
|
|
||||||
|
在这个项目中进入之后输入你的用户名密码之后创建一个桶,桶名称为`auth-admin`,这个桶名称在后端的配置文件中可以修改
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker run -d \
|
docker run -d \
|
||||||
-p 9000:9000 \
|
-p 9000:9000 \
|
||||||
-p 9090:9090 \
|
-p 9090:9090 \
|
||||||
--name minio_master --restart=always \
|
--name minio_master --restart=always \
|
||||||
-v /bunny/docker/minio/data:/data \
|
-v ~/docker/docker_data/minio/data:/data \
|
||||||
-e "MINIO_ROOT_USER=bunny" \
|
-e "MINIO_ROOT_USER=bunny" \
|
||||||
-e "MINIO_ROOT_PASSWORD=02120212" \
|
-e "MINIO_ROOT_PASSWORD=02120212" \
|
||||||
minio/minio server /data --console-address ":9090"
|
minio/minio server /data --console-address ":9090"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
![image-20241117201248420](http://116.196.101.14:9000/docs/image-20241117201248420.png)
|
||||||
|
|
||||||
|
#### 搭建步骤
|
||||||
|
|
||||||
|
**1、输入地址,之后登录进去**
|
||||||
|
|
||||||
|
**2、创建桶**
|
||||||
|
|
||||||
|
![image-20241117201444738](http://116.196.101.14:9000/docs/image-20241117201444738.png)
|
||||||
|
|
||||||
|
**3、进入创建的桶,设置桶的权限时公开的,否则无法访问文件内容**
|
||||||
|
|
||||||
|
![image-20241117201552805](http://116.196.101.14:9000/docs/image-20241117201552805.png)
|
||||||
|
|
||||||
|
![image-20241117201622288](http://116.196.101.14:9000/docs/image-20241117201622288.png)
|
||||||
|
|
||||||
|
![image-20241117201712911](http://116.196.101.14:9000/docs/image-20241117201712911.png)
|
||||||
|
|
||||||
### 安装MySQL
|
### 安装MySQL
|
||||||
|
|
||||||
**设置开机启动**
|
#### 创建配置文件
|
||||||
|
|
||||||
|
注意路径!!!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建3306配置文件
|
||||||
|
sudo mkdir -p /home/bunny/docker/docker_data/mysql/mysql_master/etc
|
||||||
|
sudo vim /home/bunny/docker/docker_data/mysql/mysql_master/etc/my.cnf
|
||||||
|
|
||||||
|
# 创建3304配置文件
|
||||||
|
sudo mkdir -p /home/bunny/docker/docker_data/mysql/slave_3304/etc
|
||||||
|
sudo vim /home/bunny/docker/docker_data/mysql/slave_3304/etc/my.cnf
|
||||||
|
```
|
||||||
|
|
||||||
|
**my.cnf 配置**
|
||||||
|
|
||||||
|
```mysql
|
||||||
|
[mysqld]
|
||||||
|
skip-host-cache
|
||||||
|
skip-name-resolve
|
||||||
|
secure-file-priv=/var/lib/mysql-files
|
||||||
|
user=mysql
|
||||||
|
|
||||||
|
# 设置字符集
|
||||||
|
character-set-server=utf8mb4
|
||||||
|
collation-server=utf8mb4_unicode_ci
|
||||||
|
|
||||||
|
# 设置服务器ID(如果是复制集群,确保每个节点的ID唯一)
|
||||||
|
server-id=1
|
||||||
|
|
||||||
|
# 启用二进制日志
|
||||||
|
log-bin=mysql-bin
|
||||||
|
|
||||||
|
# 设置表名不区分大小写
|
||||||
|
lower_case_table_names = 1
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 启动MySQL
|
||||||
|
|
||||||
|
启动时会一直输出,等输出差不多了直接关掉既可
|
||||||
|
|
||||||
**执行启动3306:**
|
**执行启动3306:**
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker stop master
|
docker stop mysql_master
|
||||||
docker rm master
|
docker rm mysql_master
|
||||||
|
|
||||||
docker run --name master -p 3306:3306 \
|
docker run --name mysql_master -p 3306:3306 \
|
||||||
-v /bunny/docker_data/mysql/master/etc/my.cnf:/etc/my.cnf \
|
-v /home/bunny/docker/docker_data/mysql/mysql_master/etc/my.cnf:/etc/my.cnf \
|
||||||
-v /bunny/docker_data/mysql/master/data:/var/lib/mysql \
|
-v /home/bunny/docker/docker_data/mysql/mysql_master/data:/var/lib/mysql \
|
||||||
|
-v /home/bunny/docker/docker_data/mysql/mysql_master/backup:/backup \
|
||||||
--restart=always --privileged=true \
|
--restart=always --privileged=true \
|
||||||
-e MYSQL_ROOT_PASSWORD=02120212 \
|
-e MYSQL_ROOT_PASSWORD=02120212 \
|
||||||
-e TZ=Asia/Shanghai \
|
-e TZ=Asia/Shanghai \
|
||||||
|
@ -138,47 +255,23 @@ docker stop slave_3304
|
||||||
docker rm slave_3304
|
docker rm slave_3304
|
||||||
|
|
||||||
docker run --name slave_3304 -p 3304:3306 \
|
docker run --name slave_3304 -p 3304:3306 \
|
||||||
-v /bunny/docker_data/mysql/slave_3304/etc/my.cnf:/etc/my.cnf \
|
-v /home/bunny/docker/docker_data/mysql/slave_3304/etc/my.cnf:/etc/my.cnf \
|
||||||
-v /bunny/docker_data/mysql/slave_3304/data:/var/lib/mysql \
|
-v /home/bunny/docker/docker_data/mysql/slave_3304/data:/var/lib/mysql \
|
||||||
-v /bunny/docker_data/mysql/slave_3304/backup:\
|
-v /home/bunny/docker/docker_data/mysql/slave_3304/backup:/backup \
|
||||||
--restart=always --privileged=true \
|
--restart=always --privileged=true \
|
||||||
-e MYSQL_ROOT_PASSWORD=02120212 \
|
-e MYSQL_ROOT_PASSWORD=02120212 \
|
||||||
-e TZ=Asia/Shanghai \
|
-e TZ=Asia/Shanghai \
|
||||||
mysql:8.0.33 --lower-case-table-names=1
|
mysql:8.0.33 --lower-case-table-names=1
|
||||||
```
|
```
|
||||||
|
|
||||||
**修改密码:**
|
> **修改密码:**
|
||||||
|
|
||||||
```sh
|
|
||||||
docker exec -it mysql_master /bin/bash
|
|
||||||
mysql -uroot -p02120212
|
|
||||||
use mysql
|
|
||||||
ALTER USER 'root'@'%' IDENTIFIED BY "02120212";
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
```
|
|
||||||
|
|
||||||
> my.cnf 配置
|
|
||||||
>
|
|
||||||
> ```sql
|
|
||||||
> [mysqld]
|
|
||||||
> skip-host-cache
|
|
||||||
> skip-name-resolve
|
|
||||||
> secure-file-priv=/var/lib/mysql-files
|
|
||||||
> user=mysql
|
|
||||||
>
|
|
||||||
> # 设置字符集
|
|
||||||
> character-set-server=utf8mb4
|
|
||||||
> collation-server=utf8mb4_unicode_ci
|
|
||||||
>
|
|
||||||
> # 设置服务器ID(如果是复制集群,确保每个节点的ID唯一)
|
|
||||||
> server-id=1
|
|
||||||
>
|
|
||||||
> # 启用二进制日志
|
|
||||||
> log-bin=mysql-bin
|
|
||||||
>
|
|
||||||
> # 设置表名不区分大小写
|
|
||||||
> lower_case_table_names = 1
|
|
||||||
>
|
>
|
||||||
|
> ```sh
|
||||||
|
> docker exec -it mysql_master /bin/bash
|
||||||
|
> mysql -uroot -p02120212
|
||||||
|
> use mysql
|
||||||
|
> ALTER USER 'root'@'%' IDENTIFIED BY "02120212";
|
||||||
|
> FLUSH PRIVILEGES;
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
### 数据库文件
|
### 数据库文件
|
||||||
|
@ -1067,6 +1160,14 @@ server {
|
||||||
|
|
||||||
## 后端部署
|
## 后端部署
|
||||||
|
|
||||||
|
### 注意事项
|
||||||
|
|
||||||
|
如果需要打包需要手动创建生产环境文件:`application-prod.yml`
|
||||||
|
|
||||||
|
![image-20241117202134939](http://116.196.101.14:9000/docs/image-20241117202134939.png)
|
||||||
|
|
||||||
|
### 环境设置
|
||||||
|
|
||||||
开发环境环境:对外暴露的端口是`7070`
|
开发环境环境:对外暴露的端口是`7070`
|
||||||
|
|
||||||
生产环境:对外暴露的端口是`8000`
|
生产环境:对外暴露的端口是`8000`
|
||||||
|
|
|
@ -43,6 +43,7 @@ export const buildEnvironment = () => {
|
||||||
// 如果是包含在包中则打包成 vendor
|
// 如果是包含在包中则打包成 vendor
|
||||||
if (id.includes('node_modules')) {
|
if (id.includes('node_modules')) {
|
||||||
return `vendor`;
|
return `vendor`;
|
||||||
|
// return id.toString().split('node_modules/')[1].split('/')[1].toString();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -76,7 +76,7 @@ async function add(data) {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
token:
|
token:
|
||||||
'eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_yWLywqFIBQA_-WsE9Sjt2xXuz7jmAYGWfiAIu6_X-HuhmHmhVwtjDDXGB_owN8XjKJH3iMayTuo2afFNffHSIdv-eSOEEMuicqZ2raX0Kx22g4ciRkUyBRpw6yxgq1S0SBXubnPBt8fEjhnWnMAAAA.YwSm-NO_6Kg1k1GRwucIt50Y70FbPHoldsdTPVHK_Y4',
|
'eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_yWLywqFIBQA_-WsE_RknWxXuz5DU8EgCx9QXO6_X-HuhmHmA7kamGGtMb7QgXtumAX1KEekQXVQs0ubbe6PUZ-u5Ys9Qwy5JF2u1LajhGaNFoZGLxlKS0xavjPjkbPBKS8Uql3TBN8fHTtSk3MAAAA.u-rDR1a46DoV0X-iQEz0Y9lfUGPm0Nsr2MuD4fvtVMg',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,10 +6,10 @@ RUN rm /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# 将自定义的 Nginx 配置文件复制到容器中
|
# 将自定义的 Nginx 配置文件复制到容器中
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
COPY bunny-web.site.csr /etc/nginx/bunny-web.site.csr
|
#COPY bunny-web.site.csr /etc/nginx/bunny-web.site.csr
|
||||||
COPY bunny-web.site.key /etc/nginx/bunny-web.site.key
|
#COPY bunny-web.site.key /etc/nginx/bunny-web.site.key
|
||||||
COPY bunny-web.site_bundle.crt /etc/nginx/bunny-web.site_bundle.crt
|
#COPY bunny-web.site_bundle.crt /etc/nginx/bunny-web.site_bundle.crt
|
||||||
COPY bunny-web.site_bundle.pem /etc/nginx/bunny-web.site_bundle.pem
|
#COPY bunny-web.site_bundle.pem /etc/nginx/bunny-web.site_bundle.pem
|
||||||
|
|
||||||
# 设置时区,构建镜像时执行的命令
|
# 设置时区,构建镜像时执行的命令
|
||||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||||
|
@ -25,7 +25,7 @@ COPY dist/ /etc/nginx/html
|
||||||
|
|
||||||
# 暴露 Nginx 的默认端口
|
# 暴露 Nginx 的默认端口
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
EXPOSE 443
|
#EXPOSE 443
|
||||||
|
|
||||||
# 自动启动 Nginx
|
# 自动启动 Nginx
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|
|
@ -3,59 +3,10 @@ map $http_upgrade $connection_upgrade {
|
||||||
'' close;
|
'' close;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
|
||||||
#SSL 默认访问端口号为 443
|
|
||||||
listen 443 ssl;
|
|
||||||
#请填写绑定证书的域名
|
|
||||||
server_name localhost;
|
|
||||||
#请填写证书文件的相对路径或绝对路径
|
|
||||||
ssl_certificate bunny-web.site_bundle.crt;
|
|
||||||
#请填写私钥文件的相对路径或绝对路径
|
|
||||||
ssl_certificate_key bunny-web.site.key;
|
|
||||||
ssl_session_timeout 5m;
|
|
||||||
#请按照以下协议配置
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
|
|
||||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
root /etc/nginx/html;
|
|
||||||
index index.html index.htm;
|
|
||||||
try_files $uri /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端跨域请求
|
|
||||||
location ~/admin/ {
|
|
||||||
proxy_pass http://172.17.0.1:8000;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端跨域请求
|
|
||||||
location ~/api/v1/ {
|
|
||||||
proxy_pass http://129.211.31.58:3000;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect http:// https://;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_page 404 404.html;
|
|
||||||
|
|
||||||
location = /50x.html {
|
|
||||||
root html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80 ;
|
listen 80 ;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /etc/nginx/html;
|
root /etc/nginx/html;
|
||||||
|
|
14
package.json
14
package.json
|
@ -1,11 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "bunny-admin-element",
|
"name": "bunny-admin-web",
|
||||||
"version": "1.0.0",
|
"version": "2.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bunny-admin-element",
|
|
||||||
"bunny-cli",
|
|
||||||
"element-plus",
|
"element-plus",
|
||||||
"tailwindcss",
|
"tailwindcss",
|
||||||
"typescript",
|
"typescript",
|
||||||
|
@ -14,19 +12,19 @@
|
||||||
"vite",
|
"vite",
|
||||||
"esm"
|
"esm"
|
||||||
],
|
],
|
||||||
"homepage": "https://gitee.com/BunnyBoss/bunny-admin-element.git",
|
"homepage": "https://github.com/BunnyMaster/bunny-admin-web",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitee.com/BunnyBoss/bunny-admin-element.git"
|
"url": "https://github.com/BunnyMaster/bunny-admin-web"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitee.com/BunnyBoss/bunny-admin-element.git/issues"
|
"url": "https://github.com/BunnyMaster/bunny-admin-web/issues"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Bunny0212",
|
"name": "Bunny0212",
|
||||||
"email": "1319900154@qq.com",
|
"email": "1319900154@qq.com",
|
||||||
"url": "https://github.com/xiaoxian521"
|
"url": "https://github.com/BunnyMaster"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
||||||
|
|
|
@ -8,7 +8,7 @@ const Copyright = getConfig('Copyright');
|
||||||
<template>
|
<template>
|
||||||
<footer class="layout-footer text-[rgba(0,0,0,0.6)] dark:text-[rgba(220,220,242,0.8)]">
|
<footer class="layout-footer text-[rgba(0,0,0,0.6)] dark:text-[rgba(220,220,242,0.8)]">
|
||||||
{{ Copyright }}
|
{{ Copyright }}
|
||||||
<a class="hover:text-primary" href="https://github.com/pure-admin" target="_blank"> {{ TITLE }} </a>
|
<a class="hover:text-primary" href="/" target="_blank"> {{ TITLE }} </a>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ export const useEmailUsersStore = defineStore('emailUsersStore', {
|
||||||
port: undefined,
|
port: undefined,
|
||||||
// 邮箱协议
|
// 邮箱协议
|
||||||
smtpAgreement: undefined,
|
smtpAgreement: undefined,
|
||||||
|
// 是否启用SSL
|
||||||
|
openSSL: undefined,
|
||||||
},
|
},
|
||||||
// 分页查询结果
|
// 分页查询结果
|
||||||
pagination: {
|
pagination: {
|
||||||
|
|
|
@ -83,7 +83,7 @@ export const storeMessage = (result: BaseResult<any>) => {
|
||||||
if (result.code !== 200) {
|
if (result.code !== 200) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
message(result.message, { type: 'success' });
|
message(result.message, { type: 'success', duration: 3666 });
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@ import { rules } from '@/views/configuration/emailTemplate/utils/columns';
|
||||||
import { FormProps } from '@/views/configuration/emailTemplate/utils/types';
|
import { FormProps } from '@/views/configuration/emailTemplate/utils/types';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { useEmailTemplateStore } from '@/store/configuration/emailTemplate';
|
import { useEmailTemplateStore } from '@/store/configuration/emailTemplate';
|
||||||
|
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
||||||
|
import View from '@iconify-icons/ep/view';
|
||||||
|
import { viewTemplate } from '@/views/configuration/emailTemplate/utils/hooks';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<FormProps>(), {
|
const props = withDefaults(defineProps<FormProps>(), {
|
||||||
formInline: () => ({
|
formInline: () => ({
|
||||||
|
@ -54,6 +57,9 @@ defineExpose({ formRef });
|
||||||
<!-- 配置邮件发送体 -->
|
<!-- 配置邮件发送体 -->
|
||||||
<el-form-item :label="$t('emailTemplate_body')" prop="body">
|
<el-form-item :label="$t('emailTemplate_body')" prop="body">
|
||||||
<el-input v-model="form.body" :autosize="{ minRows: 2, maxRows: 26 }" autocomplete="off" type="textarea" />
|
<el-input v-model="form.body" :autosize="{ minRows: 2, maxRows: 26 }" autocomplete="off" type="textarea" />
|
||||||
|
<el-button :icon="useRenderIcon(View)" class="reset-margin" link type="primary" @click="viewTemplate(form.body)">
|
||||||
|
{{ $t('viewTemplate') }}
|
||||||
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!--配置邮件类型-->
|
<!--配置邮件类型-->
|
||||||
|
|
|
@ -4,9 +4,10 @@ import { columns } from '@/views/configuration/emailTemplate/utils/columns';
|
||||||
import PureTableBar from '@/components/TableBar/src/bar';
|
import PureTableBar from '@/components/TableBar/src/bar';
|
||||||
import AddFill from '@iconify-icons/ri/add-circle-line';
|
import AddFill from '@iconify-icons/ri/add-circle-line';
|
||||||
import PureTable from '@pureadmin/table';
|
import PureTable from '@pureadmin/table';
|
||||||
import { onAdd, onDelete, onDeleteBatch, onSearch, onUpdate, selectRows } from '@/views/configuration/emailTemplate/utils/hooks';
|
import { onAdd, onDelete, onDeleteBatch, onSearch, onUpdate, selectRows, viewTemplate } from '@/views/configuration/emailTemplate/utils/hooks';
|
||||||
import Delete from '@iconify-icons/ep/delete';
|
import Delete from '@iconify-icons/ep/delete';
|
||||||
import EditPen from '@iconify-icons/ep/edit-pen';
|
import EditPen from '@iconify-icons/ep/edit-pen';
|
||||||
|
import View from '@iconify-icons/ep/view';
|
||||||
import Refresh from '@iconify-icons/ep/refresh';
|
import Refresh from '@iconify-icons/ep/refresh';
|
||||||
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
|
@ -122,6 +123,7 @@ onMounted(() => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #operation="{ row }">
|
<template #operation="{ row }">
|
||||||
|
<el-button :icon="useRenderIcon(View)" :size="size" class="reset-margin" link type="primary" @click="viewTemplate(row.body)"> {{ $t('viewTemplate') }} </el-button>
|
||||||
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
|
<el-button v-if="hasAuth(auth.update)" :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify') }} </el-button>
|
||||||
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
|
<el-popconfirm v-if="hasAuth(auth.deleted)" :title="`${$t('delete')} ${row.templateName}?`" @confirm="onDelete(row)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const columns: TableColumnList = [
|
||||||
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
||||||
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
||||||
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 130 },
|
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 130 },
|
||||||
{ label: $t('table.operation'), fixed: 'right', width: 210, slot: 'operation' },
|
{ label: $t('table.operation'), fixed: 'right', width: 230, slot: 'operation' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 添加规则
|
// 添加规则
|
||||||
|
|
|
@ -133,3 +133,14 @@ export const onDeleteBatch = async () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 查看模板 */
|
||||||
|
export const viewTemplate = (template: string) => {
|
||||||
|
addDialog({
|
||||||
|
title: $t('viewTemplate'),
|
||||||
|
draggable: true,
|
||||||
|
fullscreenIcon: true,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
contentRenderer: () => <div v-html={template} />,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -59,6 +59,11 @@ defineExpose({ formRef });
|
||||||
<el-input v-model="form.smtpAgreement" autocomplete="off" maxlength="10" show-word-limit type="text" />
|
<el-input v-model="form.smtpAgreement" autocomplete="off" maxlength="10" show-word-limit type="text" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 是否启用SSL -->
|
||||||
|
<el-form-item label="ssl" prop="openSSL">
|
||||||
|
<el-switch v-model="form.openSSL" :active-text="$t('enable')" :active-value="true" :inactive-text="$t('disable')" :inactive-value="false" :style="switchStyle" inline-prompt />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 是否为默认 -->
|
<!-- 是否为默认 -->
|
||||||
<el-form-item :label="$t('emailUsers_isDefault')" prop="isDefault">
|
<el-form-item :label="$t('emailUsers_isDefault')" prop="isDefault">
|
||||||
<el-switch v-model="form.isDefault" :active-text="$t('default')" :active-value="true" :inactive-text="$t('no_default')" :inactive-value="false" :style="switchStyle" inline-prompt />
|
<el-switch v-model="form.isDefault" :active-text="$t('default')" :active-value="true" :inactive-text="$t('no_default')" :inactive-value="false" :style="switchStyle" inline-prompt />
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { usePublicHooks } from '@/views/hooks';
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { auth } from '@/views/configuration/emailUsers/utils/auth';
|
import { auth } from '@/views/configuration/emailUsers/utils/auth';
|
||||||
import { hasAuth } from '@/router/utils';
|
import { hasAuth } from '@/router/utils';
|
||||||
|
import { enabledOrNotStatus } from '@/enums/baseConstant';
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
@ -76,6 +77,13 @@ onMounted(() => {
|
||||||
<el-input v-model="emailUsersStore.form.smtpAgreement" :placeholder="`${$t('input')}${$t('emailUsers_smtpAgreement')}`" class="!w-[180px]" clearable />
|
<el-input v-model="emailUsersStore.form.smtpAgreement" :placeholder="`${$t('input')}${$t('emailUsers_smtpAgreement')}`" class="!w-[180px]" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 是否启用SSL -->
|
||||||
|
<el-form-item label="SSL" prop="openSSL">
|
||||||
|
<el-select v-model="emailUsersStore.form.openSSL" class="!w-[180px]" clearable filterable placeholder="SSL">
|
||||||
|
<el-option v-for="(item, index) in enabledOrNotStatus" :key="index" :label="item.label" :navigationBar="false" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button :icon="useRenderIcon('ri:search-line')" :loading="emailUsersStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
<el-button :icon="useRenderIcon('ri:search-line')" :loading="emailUsersStore.loading" type="primary" @click="onSearch"> {{ $t('search') }} </el-button>
|
||||||
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||||
|
@ -116,6 +124,11 @@ onMounted(() => {
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
@page-current-change="onCurrentPageChange"
|
@page-current-change="onCurrentPageChange"
|
||||||
>
|
>
|
||||||
|
<template #openSSL="{ row }">
|
||||||
|
<el-tag v-show="row.openSSL" effect="plain" type="success">{{ $t('enable') }}</el-tag>
|
||||||
|
<el-tag v-show="!row.openSSL" effect="plain" type="danger">{{ $t('disable') }}</el-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #isDefault="{ row, index }">
|
<template #isDefault="{ row, index }">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="row.isDefault"
|
v-model="row.isDefault"
|
||||||
|
|
|
@ -15,8 +15,10 @@ export const columns: TableColumnList = [
|
||||||
{ label: $t('emailUsers_port'), prop: 'port', width: 90 },
|
{ label: $t('emailUsers_port'), prop: 'port', width: 90 },
|
||||||
// 邮箱协议
|
// 邮箱协议
|
||||||
{ label: $t('emailUsers_smtpAgreement'), prop: 'smtpAgreement', width: 100 },
|
{ label: $t('emailUsers_smtpAgreement'), prop: 'smtpAgreement', width: 100 },
|
||||||
// 是否为默认邮件
|
// 是否启用SSL
|
||||||
{ label: $t('emailUsers_isDefault'), prop: 'isDefault', slot: 'isDefault', width: 100 },
|
{ label: $t('emailUsers_isDefault'), prop: 'isDefault', slot: 'isDefault', width: 100 },
|
||||||
|
// 是否为默认邮件
|
||||||
|
{ label: 'SSL', prop: 'openSSL', slot: 'openSSL', width: 100 },
|
||||||
{ label: $t('table.updateTime'), prop: 'updateTime', sortable: true, width: 160 },
|
{ label: $t('table.updateTime'), prop: 'updateTime', sortable: true, width: 160 },
|
||||||
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
||||||
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
||||||
|
@ -37,6 +39,8 @@ export const rules: any = reactive({
|
||||||
host: [{ required: true, message: `${$t('input')}${$t('emailUsers_host')}`, trigger: 'blur' }],
|
host: [{ required: true, message: `${$t('input')}${$t('emailUsers_host')}`, trigger: 'blur' }],
|
||||||
// 端口号
|
// 端口号
|
||||||
port: [{ required: true, message: `${$t('input')}${$t('emailUsers_port')}`, trigger: 'blur' }],
|
port: [{ required: true, message: `${$t('input')}${$t('emailUsers_port')}`, trigger: 'blur' }],
|
||||||
|
// 是否启用SSL
|
||||||
|
openSSL: [{ required: true, message: `SSL`, trigger: 'blur' }],
|
||||||
// 是否为默认邮件
|
// 是否为默认邮件
|
||||||
isDefault: [{ required: true, message: `${$t('input')}${$t('emailUsers_isDefault')}`, trigger: 'blur' }],
|
isDefault: [{ required: true, message: `${$t('input')}${$t('emailUsers_isDefault')}`, trigger: 'blur' }],
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,7 @@ export function onAdd() {
|
||||||
host: undefined,
|
host: undefined,
|
||||||
port: undefined,
|
port: undefined,
|
||||||
smtpAgreement: undefined,
|
smtpAgreement: undefined,
|
||||||
|
openSSL: true,
|
||||||
isDefault: false,
|
isDefault: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -69,6 +70,7 @@ export function onUpdate(row: any) {
|
||||||
host: row.host,
|
host: row.host,
|
||||||
port: row.port,
|
port: row.port,
|
||||||
smtpAgreement: row.smtpAgreement,
|
smtpAgreement: row.smtpAgreement,
|
||||||
|
openSSL: row.openSSL,
|
||||||
isDefault: row.isDefault,
|
isDefault: row.isDefault,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,6 +10,8 @@ export interface FormItemProps {
|
||||||
port: number;
|
port: number;
|
||||||
// 邮箱协议
|
// 邮箱协议
|
||||||
smtpAgreement: string;
|
smtpAgreement: string;
|
||||||
|
// 是否启用SSL
|
||||||
|
openSSL: boolean;
|
||||||
// 是否为默认邮件
|
// 是否为默认邮件
|
||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ export const columns: TableColumnList = [
|
||||||
{ label: $t('table.createTime'), prop: 'createTime', sortable: true },
|
{ label: $t('table.createTime'), prop: 'createTime', sortable: true },
|
||||||
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
||||||
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 130 },
|
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 130 },
|
||||||
{ label: $t('table.operation'), fixed: 'right', width: 210, slot: 'operation' },
|
{ label: $t('table.operation'), fixed: 'right', width: 160, slot: 'operation' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 添加多语言表单规则
|
// 添加多语言表单规则
|
||||||
|
|
|
@ -124,7 +124,7 @@ onMounted(() => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #rank="{ row }">
|
<template #rank="{ row }">
|
||||||
<el-input v-model="row.rank" :max="9999" :min="1" type="number" @change="onChangeMenuRank(row)" />
|
<el-input v-model="row.rank" :max="9999" :min="1" type="number" @blur="onChangeMenuRank(row)" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #createUser="{ row }">
|
<template #createUser="{ row }">
|
||||||
|
|
|
@ -201,6 +201,7 @@ export const onChangeMenuRank = async (row: any) => {
|
||||||
if (!confirm) return;
|
if (!confirm) return;
|
||||||
|
|
||||||
await routerStore.updateMenuByIdWithRank(data);
|
await routerStore.updateMenuByIdWithRank(data);
|
||||||
|
await onSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue