mirror of https://gitee.com/xiaonuobase/snowy
parent
3805aead41
commit
f06cd305f4
36
README.md
36
README.md
|
@ -11,7 +11,7 @@ Snowy(SnowyAdmin)是国内首个国密前后端分离快速开发平台,
|
|||
技术框架与密码结合,让更多的人认识密码,使用密码;更是让前后分离“密”不可分。
|
||||
|
||||
|
||||
采用SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多优秀组件及前沿技术开发,注释丰富,代码简洁,开箱即用!
|
||||
采用SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多组件及前沿技术开发,注释丰富,代码简洁,开箱即用!
|
||||
|
||||
Snowy谐音“小诺”,恰应小诺团队名称;意思为”下雪的、纯洁的“,寓意框架追求简洁至上,大道至简。
|
||||
|
||||
|
@ -24,19 +24,19 @@ Snowy谐音“小诺”,恰应小诺团队名称;意思为”下雪的、纯
|
|||
<img src="https://gitee.com/xiaonuobase/snowy/badge/fork.svg?theme=dark" alt="Gitee fork">
|
||||
</a>
|
||||
<a href="https://www.antdv.com/docs/vue/introduce-cn/">
|
||||
<img src="https://img.shields.io/badge/vue-3.2-blue.svg" alt="bootstrap">
|
||||
<img src="https://img.shields.io/badge/vue-3-blue.svg" alt="bootstrap">
|
||||
</a>
|
||||
<a href="http://spring.io/projects/spring-boot">
|
||||
<img src="https://img.shields.io/badge/vite-2.8-green.svg" alt="spring-boot">
|
||||
<img src="https://img.shields.io/badge/vite-5-green.svg" alt="spring-boot">
|
||||
</a>
|
||||
<a href="https://www.antdv.com/docs/vue/introduce-cn/">
|
||||
<img src="https://img.shields.io/badge/vue--ant--design-3.2-blue.svg" alt="bootstrap">
|
||||
<img src="https://img.shields.io/badge/vue--ant--design-4-blue.svg" alt="bootstrap">
|
||||
</a>
|
||||
<a href="http://spring.io/projects/spring-boot">
|
||||
<img src="https://img.shields.io/badge/spring--boot-2.5-green.svg" alt="spring-boot">
|
||||
<img src="https://img.shields.io/badge/spring--boot-3-green.svg" alt="spring-boot">
|
||||
</a>
|
||||
<a href="http://mp.baomidou.com">
|
||||
<img src="https://img.shields.io/badge/mybatis--plus-3.5-blue.svg" alt="mybatis-plus">
|
||||
<img src="https://img.shields.io/badge/mybatis--plus-3-blue.svg" alt="mybatis-plus">
|
||||
</a>
|
||||
<a href="./LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-Apache%202-red" alt="license Apache 2.0">
|
||||
|
@ -62,9 +62,9 @@ github下载地址(镜像):[https://github.com/xiaonuobase/Snowy](https://
|
|||
全栈工程师推荐idea
|
||||
|
||||
### 前端支撑
|
||||
| 插件 | 版本 | 用途 |
|
||||
|--- | ----- | ----- |
|
||||
| node.js | ≥16 | JavaScript运行环境 |
|
||||
| 插件 | 版本 | 用途 |
|
||||
|--- |-----| ----- |
|
||||
| node.js | ≥18 | JavaScript运行环境 |
|
||||
|
||||
### 启动前端
|
||||
|
||||
|
@ -75,12 +75,12 @@ npm install
|
|||
npm run dev
|
||||
```
|
||||
### 后端支撑
|
||||
| 插件 | 版本 | 用途 |
|
||||
| --- | ----- | ----- |
|
||||
| jdk | 11 / 1.8 |java环境 |
|
||||
| lombok | idea内 |代码简化插件 |
|
||||
| maven | 最新版 |包管理工具 |
|
||||
| redis | 最新版 | 缓存库 |
|
||||
| 插件 | 版本 | 用途 |
|
||||
| --- |-----------| ----- |
|
||||
| jdk | 17 |java环境 |
|
||||
| lombok | idea内 |代码简化插件 |
|
||||
| maven | 最新版 |包管理工具 |
|
||||
| redis | 最新版 | 缓存库 |
|
||||
| mysql | 8.0 / 5.7 | 数据库 |
|
||||
|
||||
### 启动后端
|
||||
|
@ -88,7 +88,7 @@ npm run dev
|
|||
|
||||
## 代码结构
|
||||
|
||||
Snowy2.0框架对代码以插件化的模式进行分包,使得包层级结构更加清晰合理,同时降低了耦合度,关于插件模块化开发的规范请查阅文档【SNOWY开源文档——前端手册or后端手册——开发规范】板块。
|
||||
Snowy3.0框架对代码以插件化的模式进行分包,使得包层级结构更加清晰合理,同时降低了耦合度,关于插件模块化开发的规范请查阅文档【SNOWY开源文档——前端手册or后端手册——开发规范】板块。
|
||||
|
||||
```
|
||||
snowy
|
||||
|
@ -141,6 +141,10 @@ snowy
|
|||
|
||||
1.x分支,目前已停止新增功能,只限于bug的维护,推荐使用2x版本
|
||||
|
||||
- snowy2.5
|
||||
|
||||
2.x分支,目前已停止新增功能,只限于bug的维护,可以平滑过渡至3x版本
|
||||
|
||||
## 视频教程
|
||||
|
||||
教程地址(免费开放):[https://space.bilibili.com/50101698/channel/collectiondetail?sid=739071](https://space.bilibili.com/50101698/channel/collectiondetail?sid=739071)
|
||||
|
|
421
pom.xml
421
pom.xml
|
@ -6,83 +6,23 @@
|
|||
<groupId>vip.xiaonuo</groupId>
|
||||
<artifactId>snowy</artifactId>
|
||||
<name>snowy</name>
|
||||
<version>2.0.0</version>
|
||||
<version>3.0.0</version>
|
||||
<description>snowy快速开发平台</description>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.5.12</version>
|
||||
<version>3.2.1</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<snowy.version>2.0.0</snowy.version>
|
||||
<spring-framework.version>5.3.26</spring-framework.version>
|
||||
<java.version>17</java.version>
|
||||
<snowy.version>3.0.0</snowy.version>
|
||||
<spring-boot.version>3.2.1</spring-boot.version>
|
||||
<spring-framework.version>6.1.2</spring-framework.version>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- 锁定依赖版本号 -->
|
||||
<ali.oss.version>3.14.0</ali.oss.version>
|
||||
<aliyun.sdk.dm.version>3.3.1</aliyun.sdk.dm.version>
|
||||
<aliyun.sdk.dysmsapi.version>2.0.9</aliyun.sdk.dysmsapi.version>
|
||||
<aliyun.sdk.ecs.version>3.1.0</aliyun.sdk.ecs.version>
|
||||
<bcprov.jdk15on.version>1.70</bcprov.jdk15on.version>
|
||||
<beetl.version>1.2.40.Beetl.RELEASE</beetl.version>
|
||||
<checker.qual.version>3.31.0</checker.qual.version>
|
||||
<commons.beanutils.version>1.9.4</commons.beanutils.version>
|
||||
<commons.compress.version>1.22</commons.compress.version>
|
||||
<commons.pool2.version>2.11.1</commons.pool2.version>
|
||||
<druid.version>1.2.9</druid.version>
|
||||
<dynamic.datasource.version>3.5.1</dynamic.datasource.version>
|
||||
<easy.trans.version>2.1.7</easy.trans.version>
|
||||
<easyexcel.version>3.2.1</easyexcel.version>
|
||||
<easypoi.version>4.3.0</easypoi.version>
|
||||
<fastjson.version>2.0.24</fastjson.version>
|
||||
<gson.version>2.8.9</gson.version>
|
||||
<guava.version>31.1-jre</guava.version>
|
||||
<hutool.version>5.8.12</hutool.version>
|
||||
<ip2region.version>2.6.3</ip2region.version>
|
||||
<jackson.annotations.version>2.14.2</jackson.annotations.version>
|
||||
<jackson.core.version>2.14.2</jackson.core.version>
|
||||
<jackson.databind.version>2.14.2</jackson.databind.version>
|
||||
<jackson.datatype.jdk8.version>2.14.2</jackson.datatype.jdk8.version>
|
||||
<jackson.datatype.jsr310.version>2.14.2</jackson.datatype.jsr310.version>
|
||||
<jackson.module.parameter.names.version>2.14.2</jackson.module.parameter.names.version>
|
||||
<javax.mail.version>1.6.2</javax.mail.version>
|
||||
<jettison.version>1.5.4</jettison.version>
|
||||
<junit.version>4.13.2</junit.version>
|
||||
<just.auth.version>1.16.5</just.auth.version>
|
||||
<knife4j.version>2.0.9</knife4j.version>
|
||||
<logback.classic.version>1.2.0</logback.classic.version>
|
||||
<lombok.versin>1.18.22</lombok.versin>
|
||||
<minio.version>8.5.2</minio.version>
|
||||
<mssql.connector.java.version>9.2.1.jre8</mssql.connector.java.version>
|
||||
<mybatis.plus.version>3.5.3.1</mybatis.plus.version>
|
||||
<mybatis.version>3.5.10</mybatis.version>
|
||||
<mysql.connector.java.version>8.0.28</mysql.connector.java.version>
|
||||
<netty.common.version>4.1.89.Final</netty.common.version>
|
||||
<netty.handler.version>4.1.89.Final</netty.handler.version>
|
||||
<okhttp3.version>4.10.0</okhttp3.version>
|
||||
<okio.version>3.3.0</okio.version>
|
||||
<dm.connector.java.version>8.1.2.192</dm.connector.java.version>
|
||||
<kingbase.connector.java.version>8.6.0</kingbase.connector.java.version>
|
||||
<oracle.connector.java.version>21.5.0.0</oracle.connector.java.version>
|
||||
<oracle.nls.orai18n.version>19.7.0.0</oracle.nls.orai18n.version>
|
||||
<oshi.core.version>6.2.2</oshi.core.version>
|
||||
<pinyin.version>2.5.1</pinyin.version>
|
||||
<postgres.connector.java.version>42.2.25</postgres.connector.java.version>
|
||||
<protobuf.java.version>3.21.12</protobuf.java.version>
|
||||
<sa.token.version>1.31.0</sa.token.version>
|
||||
<smcrypto.version>0.3.2</smcrypto.version>
|
||||
<snakeyaml.version>2.0</snakeyaml.version>
|
||||
<spring.context.version>5.3.19</spring.context.version>
|
||||
<spring.security.crypto.version>5.8.9</spring.security.crypto.version>
|
||||
<springfox.swagger2.version>2.10.5</springfox.swagger2.version>
|
||||
<ten.cos.version>5.6.68</ten.cos.version>
|
||||
<ten.sdk.ses.version>3.1.455</ten.sdk.ses.version>
|
||||
<ten.sdk.sms.version>3.1.455</ten.sdk.sms.version>
|
||||
<tomcat.embed.core.version>9.0.72</tomcat.embed.core.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
@ -207,458 +147,282 @@
|
|||
<version>${snowy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- nashorn-core -->
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>15.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.versin}</version>
|
||||
<version>1.18.30</version>
|
||||
</dependency>
|
||||
|
||||
<!-- druid -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis -->
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>${mybatis.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus-core -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-core</artifactId>
|
||||
<version>${mybatis.plus.version}</version>
|
||||
<version>1.2.21</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatis.plus.version}</version>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>3.5.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- easy-trans -->
|
||||
<dependency>
|
||||
<groupId>com.fhs-opensource</groupId>
|
||||
<artifactId>easy-trans-spring-boot-starter</artifactId>
|
||||
<version>${easy.trans.version}</version>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- easy-trans-mybatis-plus-extend -->
|
||||
<dependency>
|
||||
<groupId>com.fhs-opensource</groupId>
|
||||
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
||||
<version>${easy.trans.version}</version>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- redis -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
<version>${commons.pool2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- okhttp -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- okio -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
<version>${okio.version}</version>
|
||||
<version>2.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
<version>5.8.25</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pinyin4j -->
|
||||
<dependency>
|
||||
<groupId>com.belerweb</groupId>
|
||||
<artifactId>pinyin4j</artifactId>
|
||||
<version>${pinyin.version}</version>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ip2region -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>${ip2region.version}</version>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- knife4j -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||
<version>4.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- easy-poi -->
|
||||
<dependency>
|
||||
<groupId>cn.afterturn</groupId>
|
||||
<artifactId>easypoi-spring-boot-starter</artifactId>
|
||||
<version>${easypoi.version}</version>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sm-crypto -->
|
||||
<dependency>
|
||||
<groupId>com.antherd</groupId>
|
||||
<artifactId>sm-crypto</artifactId>
|
||||
<version>${smcrypto.version}</version>
|
||||
<version>0.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- easyexcel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<version>${easyexcel.version}</version>
|
||||
<version>3.3.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-core -->
|
||||
<!-- Sa-token-core -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>${sa.token.version}</version>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token -->
|
||||
<!-- Sa-token -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa.token.version}</version>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token 整合 redis (使用jackson序列化方式) -->
|
||||
<!-- Sa-token 整合 redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>${sa.token.version}</version>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token插件:权限缓存与业务缓存分离 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-alone-redis</artifactId>
|
||||
<version>${sa.token.version}</version>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 插件:整合SSO -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-sso</artifactId>
|
||||
<version>${sa.token.version}</version>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JustAuth 第三方登录 -->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>${just.auth.version}</version>
|
||||
<version>1.16.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- beetl模板引擎 -->
|
||||
<dependency>
|
||||
<groupId>com.ibeetl</groupId>
|
||||
<artifactId>beetl-framework-starter</artifactId>
|
||||
<version>${beetl.version}</version>
|
||||
<version>1.2.40.Beetl.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!--腾讯云上传文件客户端-->
|
||||
<!--x-file-storage文件sdk-->
|
||||
<dependency>
|
||||
<groupId>org.dromara.x-file-storage</groupId>
|
||||
<artifactId>x-file-storage-spring</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--腾讯云文件sdk-->
|
||||
<dependency>
|
||||
<groupId>com.qcloud</groupId>
|
||||
<artifactId>cos_api</artifactId>
|
||||
<version>${ten.cos.version}</version>
|
||||
<version>5.6.199</version>
|
||||
</dependency>
|
||||
|
||||
<!--阿里云上传文件客户端-->
|
||||
<!--阿里云文件sdk-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${ali.oss.version}</version>
|
||||
<version>3.15.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--minio上传文件客户端-->
|
||||
<!--minio文件sdk-->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
<version>8.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--java邮件发送-->
|
||||
<!--java邮件sdk-->
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>javax.mail</artifactId>
|
||||
<version>${javax.mail.version}</version>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--阿里云邮件发送-->
|
||||
<!--阿里云邮件sdk-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dm</artifactId>
|
||||
<version>${aliyun.sdk.dm.version}</version>
|
||||
<artifactId>dm20151123</artifactId>
|
||||
<version>1.0.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 腾讯云邮件发送 -->
|
||||
<!-- 腾讯云邮件sdk -->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-ses</artifactId>
|
||||
<version>${ten.sdk.ses.version}</version>
|
||||
<version>3.1.944</version>
|
||||
</dependency>
|
||||
|
||||
<!--阿里云短信发送-->
|
||||
<!--阿里云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>${aliyun.sdk.dysmsapi.version}</version>
|
||||
<version>2.0.24</version>
|
||||
</dependency>
|
||||
|
||||
<!--腾讯云短信发送-->
|
||||
<!--腾讯云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId>
|
||||
<version>${ten.sdk.sms.version}</version>
|
||||
<version>3.1.893</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sms4j短信sdk -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-javase-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--系统硬件信息-->
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>${oshi.core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- logback-classic -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.classic.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- gson -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- netty-common -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-common</artifactId>
|
||||
<version>${netty.common.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- netty-common -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-handler</artifactId>
|
||||
<version>${netty.handler.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jettison -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jettison</groupId>
|
||||
<artifactId>jettison</artifactId>
|
||||
<version>${jettison.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- snakeyaml -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>${snakeyaml.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-context -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.context.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-security-crypto -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
<version>${spring.security.crypto.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- springfox-swagger2 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${springfox.swagger2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- tomcat-embed-core -->
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-core</artifactId>
|
||||
<version>${tomcat.embed.core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- fastjson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-annotations -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.annotations.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-core -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-databind -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.databind.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-datatype -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||
<version>${jackson.datatype.jdk8.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-jsr310 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson.datatype.jsr310.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jackson-module-parameter-names -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-parameter-names</artifactId>
|
||||
<version>${jackson.module.parameter.names.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- commons-beanutils -->
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>${commons.beanutils.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- commons-compress -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>${commons.compress.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- protobuf-java -->
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>${protobuf.java.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- checker-qual -->
|
||||
<dependency>
|
||||
<groupId>org.checkerframework</groupId>
|
||||
<artifactId>checker-qual</artifactId>
|
||||
<version>${checker.qual.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- bcprov-jdk15on -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bcprov.jdk15on.version}</version>
|
||||
<version>6.4.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- dynamic-datasource -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>${dynamic.datasource.version}</version>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.connector.java.version}</version>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- postgresql -->
|
||||
<!--<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgres.connector.java.version}</version>
|
||||
<version>42.7.1</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- 达梦数据库 -->
|
||||
<!--<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>DmJdbcDriver18</artifactId>
|
||||
<version>${dm.connector.java.version}</version>
|
||||
<version>8.1.3.62</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- 人大金仓数据库 -->
|
||||
<!--<dependency>
|
||||
<groupId>cn.com.kingbase</groupId>
|
||||
<artifactId>kingbase8</artifactId>
|
||||
<version>${kingbase.connector.java.version}</version>
|
||||
<version>8.6.0</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- oracle -->
|
||||
<!--<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
<version>${oracle.connector.java.version}</version>
|
||||
<artifactId>ojdbc10</artifactId>
|
||||
<version>19.21.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.nls</groupId>
|
||||
<artifactId>orai18n</artifactId>
|
||||
<version>${oracle.nls.orai18n.version}</version>
|
||||
<version>23.3.0.23.09</version>
|
||||
</dependency>-->
|
||||
|
||||
<!-- mssql -->
|
||||
<!--<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>${mssql.connector.java.version}</version>
|
||||
<version>12.4.2.jre11</version>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
@ -668,16 +432,19 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.12.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
</configuration>
|
||||
|
@ -694,10 +461,6 @@
|
|||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>_sql/*</exclude>
|
||||
<exclude>*.md</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<link rel="icon" href="/favicon.ico">
|
||||
<title>Snowy</title>
|
||||
<style>
|
||||
.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}
|
||||
.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1677FF;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}
|
||||
.app-loading {position: absolute;top:0px;left:0px;right:0px;bottom:0px;display: flex;justify-content: center;align-items: center;flex-direction: column;background: #fff;}
|
||||
.app-loading__logo {margin-bottom: 30px;}
|
||||
.app-loading__logo img {width: 90px;vertical-align: bottom;}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "snowy-admin-web",
|
||||
"version": "1.0.0",
|
||||
"version": "3.0.0",
|
||||
"private": true,
|
||||
"description": "小诺团队旗下Snowy前端,基于Antdv3.2+Vue3.2+Vite2.8",
|
||||
"repository": {
|
||||
|
@ -24,10 +24,10 @@
|
|||
"@chenfengyuan/vue-qrcode": "2.0.0",
|
||||
"@highlightjs/vue-plugin": "2.1.0",
|
||||
"@tinymce/tinymce-vue": "5.1.1",
|
||||
"@vue-office/docx": "1.3.2",
|
||||
"@vue-office/excel": "1.4.7",
|
||||
"@vue-office/pdf": "1.5.5",
|
||||
"ant-design-vue": "3.2.14",
|
||||
"@vue-office/docx": "1.6.0",
|
||||
"@vue-office/excel": "1.7.1",
|
||||
"@vue-office/pdf": "1.6.4",
|
||||
"ant-design-vue": "4.1.2",
|
||||
"axios": "1.6.2",
|
||||
"cropperjs": "1.6.1",
|
||||
"dayjs": "1.11.10",
|
||||
|
@ -48,12 +48,12 @@
|
|||
"snowflake-id": "1.1.0",
|
||||
"sortablejs": "1.15.1",
|
||||
"tinymce": "6.8.1",
|
||||
"vue": "3.3.10",
|
||||
"vue": "3.4.21",
|
||||
"vue-cropper": "1.1.1",
|
||||
"vue-demi": "0.13.11",
|
||||
"vue-demi": "0.14.7",
|
||||
"vue-i18n": "9.8.0",
|
||||
"vue-router": "4.2.5",
|
||||
"vue3-colorpicker": "2.2.3",
|
||||
"vue-router": "4.3.0",
|
||||
"vue3-colorpicker": "2.3.0",
|
||||
"vue3-tree-org": "4.2.2",
|
||||
"vuedraggable-es": "4.1.1"
|
||||
},
|
||||
|
@ -79,7 +79,7 @@
|
|||
"typescript": "5.3.3",
|
||||
"unplugin-auto-import": "0.17.2",
|
||||
"unplugin-vue-components": "0.26.0",
|
||||
"vite": "5.1.4",
|
||||
"vite": "5.1.6",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-vue-setup-extend": "0.4.0",
|
||||
"vue-eslint-parser": "9.3.2"
|
||||
|
|
|
@ -1,14 +1,40 @@
|
|||
<template>
|
||||
<a-config-provider :locale="locale">
|
||||
<router-view />
|
||||
<a-config-provider
|
||||
:locale="locale"
|
||||
:theme="{
|
||||
algorithm: store.theme === 'realDark' ? theme.darkAlgorithm : theme.defaultAlgorithm,
|
||||
token: {
|
||||
colorPrimary: `${store.themeColor}`,
|
||||
borderRadius: roundedCornerStyleOpen ? 6 : 2
|
||||
}
|
||||
}"
|
||||
>
|
||||
<a-watermark
|
||||
:content="loginUserWatermarkOpen && userInfo ? [userInfo.name, userInfo.account] : undefined"
|
||||
class="admin-ui-main"
|
||||
>
|
||||
<router-view />
|
||||
</a-watermark>
|
||||
</a-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup name="App">
|
||||
import i18n from '@/locales'
|
||||
import { globalStore } from '@/store'
|
||||
|
||||
import { theme } from 'ant-design-vue'
|
||||
const store = globalStore()
|
||||
store.initTheme()
|
||||
const locale = i18n.global.messages.value[i18n.global.locale.value].lang
|
||||
// 获取用户信息
|
||||
const userInfo = computed(() => {
|
||||
return store.userInfo
|
||||
})
|
||||
// 水印开关
|
||||
const loginUserWatermarkOpen = computed(() => {
|
||||
return store.loginUserWatermarkOpen
|
||||
})
|
||||
// 圆角风格
|
||||
const roundedCornerStyleOpen = computed(() => {
|
||||
return store.roundedCornerStyleOpen
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -30,6 +30,10 @@ export default {
|
|||
smsSendTencent(data) {
|
||||
return request('sendTencent', data)
|
||||
},
|
||||
// 发送短信——小诺短信
|
||||
smsSendXiaonuo(data) {
|
||||
return request('sendXiaonuo', data)
|
||||
},
|
||||
// 删除短信
|
||||
smsDelete(data) {
|
||||
return request('delete', data)
|
||||
|
|
|
@ -97,5 +97,9 @@ export default {
|
|||
// 根据id集合获取角色集合
|
||||
userCenterGetRoleListByIdList(data) {
|
||||
return request('getRoleListByIdList', data)
|
||||
},
|
||||
// 根据id获取头像
|
||||
userCenterGtAvatarById(data) {
|
||||
return request('getAvatarById', data)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
angleField: 'sold',
|
||||
colorField: 'sex',
|
||||
radius: 0.66,
|
||||
color: ['#1890ff', '#f04864'],
|
||||
color: ['#1677FF', '#f04864'],
|
||||
label: {
|
||||
content: (obj) => {
|
||||
const group = new G.Group({})
|
||||
|
@ -46,7 +46,7 @@
|
|||
text: obj.sex,
|
||||
textAlign: 'center',
|
||||
textBaseline: 'top',
|
||||
fill: obj.sex === '男' ? '#1890ff' : '#f04864'
|
||||
fill: obj.sex === '男' ? '#1677FF' : '#f04864'
|
||||
}
|
||||
})
|
||||
return group
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
},
|
||||
areaStyle: () => {
|
||||
return {
|
||||
fill: 'l(270) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
|
||||
fill: 'l(270) 0:#ffffff 0.5:#7ec2f3 1:#1677FF'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
default: '#1890ff'
|
||||
default: '#1677FF'
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -22,11 +22,17 @@
|
|||
}
|
||||
|
||||
const update = (val) => {
|
||||
showTxt(val)
|
||||
emit('update:value', val)
|
||||
}
|
||||
onMounted(() => {
|
||||
showTxt(props.value)
|
||||
})
|
||||
const showTxt = (val) => {
|
||||
const currentColor = document.querySelector('.current-color')
|
||||
if (currentColor) {
|
||||
currentColor.textContent = val
|
||||
}
|
||||
emit('update:value', val)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -71,31 +71,31 @@ export const data = {
|
|||
month: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
|
||||
week: [
|
||||
{
|
||||
value: '1',
|
||||
value: '0',
|
||||
label: '周日'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
value: '1',
|
||||
label: '周一'
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
value: '2',
|
||||
label: '周二'
|
||||
},
|
||||
{
|
||||
value: '4',
|
||||
value: '3',
|
||||
label: '周三'
|
||||
},
|
||||
{
|
||||
value: '5',
|
||||
value: '4',
|
||||
label: '周四'
|
||||
},
|
||||
{
|
||||
value: '6',
|
||||
value: '5',
|
||||
label: '周五'
|
||||
},
|
||||
{
|
||||
value: '7',
|
||||
value: '6',
|
||||
label: '周六'
|
||||
}
|
||||
],
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</a-input>
|
||||
<a-modal
|
||||
title="CRON规则生成器"
|
||||
v-model:visible="modalVisible"
|
||||
v-model:open="modalVisible"
|
||||
:width="580"
|
||||
@cancel="modalVisible = false"
|
||||
@ok="submit"
|
||||
|
@ -35,9 +35,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>秒</h2>
|
||||
<a-tag :color="activeKey === '1' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_second
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '1' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_second }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -56,7 +54,7 @@
|
|||
:max="59"
|
||||
controls-position="right"
|
||||
></a-input-number>
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number
|
||||
v-model:value="dateValue.second.range.end"
|
||||
:min="0"
|
||||
|
@ -79,7 +77,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.second.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -92,9 +90,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>分钟</h2>
|
||||
<a-tag :color="activeKey === '2' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_minute
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '2' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_minute }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -113,7 +109,7 @@
|
|||
:max="59"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number v-model:value="dateValue.minute.range.end" :min="0" :max="59" controls-position="right" />
|
||||
</a-form-item>
|
||||
<a-form-item label="间隔" v-if="dateValue.minute.type === '2'">
|
||||
|
@ -131,7 +127,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.minute.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -144,9 +140,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>小时</h2>
|
||||
<a-tag :color="activeKey === '3' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_hour
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '3' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_hour }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -160,7 +154,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item label="范围" v-if="dateValue.hour.type === '1'">
|
||||
<a-input-number v-model:value="dateValue.hour.range.start" :min="0" :max="23" controls-position="right" />
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number v-model:value="dateValue.hour.range.end" :min="0" :max="23" controls-position="right" />
|
||||
</a-form-item>
|
||||
<a-form-item label="间隔" v-if="dateValue.hour.type === '2'">
|
||||
|
@ -173,7 +167,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.hour.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -186,9 +180,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>日</h2>
|
||||
<a-tag :color="activeKey === '4' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_day
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '4' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_day }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -204,7 +196,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item label="范围" v-if="dateValue.day.type === '1'">
|
||||
<a-input-number v-model:value="dateValue.day.range.start" :min="1" :max="31" controls-position="right" />
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number v-model:value="dateValue.day.range.end" :min="1" :max="31" controls-position="right" />
|
||||
</a-form-item>
|
||||
<a-form-item label="间隔" v-if="dateValue.day.type === '2'">
|
||||
|
@ -217,7 +209,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.day.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -230,9 +222,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>月</h2>
|
||||
<a-tag :color="activeKey === '5' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_month
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '5' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_month }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -251,7 +241,7 @@
|
|||
:max="12"
|
||||
controls-position="right"
|
||||
/>
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number v-model:value="dateValue.month.range.end" :min="1" :max="12" controls-position="right" />
|
||||
</a-form-item>
|
||||
<a-form-item label="间隔" v-if="dateValue.month.type === '2'">
|
||||
|
@ -264,7 +254,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.month.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -277,9 +267,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>周</h2>
|
||||
<a-tag :color="activeKey === '6' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_week
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '6' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_week }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -303,7 +291,7 @@
|
|||
:value="item.value"
|
||||
/>
|
||||
</a-select>
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-select v-model:value="dateValue.week.range.end" placeholder="请选择">
|
||||
<a-select-option
|
||||
v-for="(item, index) in data.week"
|
||||
|
@ -331,7 +319,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.week.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -360,9 +348,7 @@
|
|||
<template #tab>
|
||||
<div class="cron-num">
|
||||
<h2>年</h2>
|
||||
<a-tag :color="activeKey === '7' ? `var(--primary-color)` : ''" style="margin-right: 0px">{{
|
||||
value_year
|
||||
}}</a-tag>
|
||||
<a-tag :color="activeKey === '7' ? `var(--primary-color)` : ''" class="xn-mr">{{ value_year }}</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
<a-form>
|
||||
|
@ -377,7 +363,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item label="范围" v-if="dateValue.year.type === '1'">
|
||||
<a-input-number v-model:value="dateValue.year.range.start" controls-position="right" />
|
||||
<span style="padding: 0 15px">-</span>
|
||||
<span class="xn-pd">-</span>
|
||||
<a-input-number v-model:value="dateValue.year.range.end" controls-position="right" />
|
||||
</a-form-item>
|
||||
<a-form-item label="间隔" v-if="dateValue.year.type === '2'">
|
||||
|
@ -390,7 +376,7 @@
|
|||
<a-select
|
||||
v-model:value="dateValue.year.appoint"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
mode="multiple"
|
||||
placeholder="请选择"
|
||||
>
|
||||
|
@ -580,6 +566,9 @@
|
|||
}
|
||||
})
|
||||
watch(props, (newValue) => {
|
||||
if (newValue.modelValue === '') {
|
||||
defaultValue.value = ''
|
||||
}
|
||||
if (newValue.modelValue) {
|
||||
defaultValue.value = newValue.modelValue
|
||||
}
|
||||
|
@ -758,4 +747,10 @@
|
|||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.xn-mr {
|
||||
margin-right: 0px;
|
||||
}
|
||||
.xn-pd {
|
||||
padding: 0 15px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-modal ref="cropmodal" v-model:visible="visible" :width="700" title="头像裁剪" @cancel="handleClear" @ok="cropOk">
|
||||
<a-modal v-model:open="visible" :width="700" title="头像裁剪" @cancel="handleClear" @ok="cropOk">
|
||||
<a-row :gutter="10">
|
||||
<!-- 裁剪区 -->
|
||||
<a-col :span="17">
|
||||
|
@ -26,27 +26,27 @@
|
|||
/>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<div style="width: 165px; height: 165px; border: 1px solid #e9e9e9; border-radius: 2px">
|
||||
<div class="xn-cj">
|
||||
<a-image :src="previewUrl" />
|
||||
</div>
|
||||
<div style="padding-top: 10px; display: flex">
|
||||
<div style="height: 100px; width: 100px; border: 1px solid #e9e9e9; border-radius: 2px">
|
||||
<div class="xn-cj-two">
|
||||
<div>
|
||||
<a-image :src="previewUrl" />
|
||||
</div>
|
||||
<div style="height: 60px; width: 60px; border: 1px solid #e9e9e9; margin-left: 5px; border-radius: 2px">
|
||||
<div>
|
||||
<a-image :src="previewUrl" />
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div style="text-align: center; padding-top: 10px">
|
||||
<div class="xn-tl">
|
||||
<a-space>
|
||||
<a-button @click="cropper.changeScale(1)">放大</a-button>
|
||||
<a-button @click="cropper.changeScale(-1)">缩小</a-button>
|
||||
<a-button @click="cropper.rotateLeft()">向左旋转</a-button>
|
||||
<a-button @click="cropper.rotateRight()">向右旋转</a-button>
|
||||
</a-space>
|
||||
<div style="padding-top: 10px">
|
||||
<div class="xn-pt">
|
||||
<a-upload
|
||||
name="file"
|
||||
:show-upload-list="false"
|
||||
|
@ -60,7 +60,7 @@
|
|||
</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div style="padding-top: 10px">请上传图片文件,建议不超过2M</div>
|
||||
<div class="xn-pt">请上传图片文件,建议不超过2M</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
@ -152,4 +152,35 @@
|
|||
.cropper {
|
||||
height: 280px;
|
||||
}
|
||||
.xn-cj {
|
||||
width: 165px;
|
||||
height: 165px;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 2px
|
||||
}
|
||||
.xn-pt {
|
||||
padding-top: 10px;
|
||||
}
|
||||
.xn-tl {
|
||||
text-align: center;
|
||||
padding-top: 10px
|
||||
}
|
||||
.xn-cj-two {
|
||||
padding-top: 10px;
|
||||
display: flex
|
||||
|
||||
}
|
||||
.xn-cj-two > div:first-child {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 2px
|
||||
}
|
||||
.xn-cj-two > div:nth-child(2) {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
border: 1px solid #e9e9e9;
|
||||
margin-left: 5px;
|
||||
border-radius: 2px
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<a-modal
|
||||
:class="['my-modal', modalClass, simpleClass]"
|
||||
:visible="visible"
|
||||
:open="visible"
|
||||
v-bind="props"
|
||||
:width="modalWidth"
|
||||
:wrap-class-name="wrapClassName + fullscreenClass"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="baiduMap" :style="{ height: `${height}px` }">
|
||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||
<div :id="`container-${mid}`" class="xn-wh">地图资源加载中...</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--BMapGL官网:https://lbsyun.baidu.com/index.php?title=jspopularGL-->
|
||||
|
@ -332,6 +332,10 @@
|
|||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.xn-wh {
|
||||
width: 100%;
|
||||
height: 100%
|
||||
}
|
||||
.baiduMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="gaodeMap" :style="{ height: `${height}px` }">
|
||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||
<div :id="`container-${mid}`" class="xn-wh">地图资源加载中...</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--AMap官网:https://lbs.amap.com/api/javascript-api-v2/summary-->
|
||||
|
@ -353,6 +353,10 @@
|
|||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.xn-wh {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.gaodeMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
|
|
@ -44,5 +44,43 @@
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import './index.less';
|
||||
.ant-pro-number-info-subtitle {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.number-info-value {
|
||||
margin-top: 4px;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
|
||||
& > span {
|
||||
color: @heading-color;
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
font-size: 24px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.sub-total {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-lg;
|
||||
vertical-align: top;
|
||||
margin-right: 0;
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.82);
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="移动端图标选择"
|
||||
:mask-closable="false"
|
||||
:width="800"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="图标选择"
|
||||
:mask-closable="false"
|
||||
:width="800"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="机构选择"
|
||||
:width="1000"
|
||||
:mask-closable="false"
|
||||
|
@ -22,7 +22,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<div class="table-operator" style="margin-bottom: 10px">
|
||||
<div class="table-operator xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
|
@ -32,7 +32,7 @@
|
|||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button type="primary" class="primarySele" @click="loadData()"> 查询 </a-button>
|
||||
<a-button class="snowy-buttom-left" @click="() => reset()"> 重置 </a-button>
|
||||
<a-button class="snowy-button-left" @click="() => reset()"> 重置 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
@ -50,7 +50,7 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>待选择列表 {{ tableRecordNum }} 条</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fd">
|
||||
<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -59,7 +59,7 @@
|
|||
{{ $TOOL.dictTypeData('ORG_CATEGORY', record.category) }}
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)">添加</a-button>
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
@ -89,13 +89,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>已选择: {{ selectedData.length }}</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fd">
|
||||
<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)">移除</a-button>
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
@ -116,7 +116,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '机构名',
|
||||
|
@ -134,7 +134,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '机构名',
|
||||
|
@ -250,10 +250,7 @@
|
|||
loadData()
|
||||
}
|
||||
const judge = () => {
|
||||
if (radioModel && selectedData.value.length > 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return !(radioModel && selectedData.value.length > 0)
|
||||
}
|
||||
// 添加记录
|
||||
const addRecord = (record) => {
|
||||
|
@ -377,6 +374,12 @@
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.xn-mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.xn-fd {
|
||||
float: right;
|
||||
}
|
||||
.selectorTreeDiv {
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="职位选择"
|
||||
:width="1000"
|
||||
:mask-closable="false"
|
||||
|
@ -22,7 +22,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<div class="table-operator" style="margin-bottom: 10px">
|
||||
<div class="table-operator xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
|
@ -32,7 +32,7 @@
|
|||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button type="primary" class="primarySele" @click="loadData()"> 查询 </a-button>
|
||||
<a-button class="snowy-buttom-left" @click="() => reset()"> 重置 </a-button>
|
||||
<a-button class="snowy-button-left" @click="() => reset()"> 重置 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
@ -50,13 +50,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>待选择列表 {{ tableRecordNum }} 条</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)">添加</a-button>
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'category'">
|
||||
{{ $TOOL.dictTypeData('POSITION_CATEGORY', record.category) }}
|
||||
|
@ -89,13 +89,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>已选择: {{ selectedData.length }}</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)">移除</a-button>
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
@ -116,7 +116,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '职位名',
|
||||
|
@ -134,7 +134,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '职位名',
|
||||
|
@ -251,10 +251,7 @@
|
|||
loadData()
|
||||
}
|
||||
const judge = () => {
|
||||
if (radioModel && selectedData.value.length > 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return !(radioModel && selectedData.value.length > 0)
|
||||
}
|
||||
// 添加记录
|
||||
const addRecord = (record) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="角色选择"
|
||||
:width="1000"
|
||||
:mask-closable="false"
|
||||
|
@ -22,7 +22,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<div class="table-operator" style="margin-bottom: 10px">
|
||||
<div class="table-operator xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
|
@ -32,7 +32,7 @@
|
|||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button type="primary" class="primarySele" @click="loadData()"> 查询 </a-button>
|
||||
<a-button class="snowy-buttom-left" @click="() => reset()"> 重置 </a-button>
|
||||
<a-button class="snowy-button-left" @click="() => reset()"> 重置 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
@ -50,13 +50,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>待选择列表 {{ tableRecordNum }} 条</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)">添加</a-button>
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'category'">
|
||||
{{ $TOOL.dictTypeData('ROLE_CATEGORY', record.category) }}
|
||||
|
@ -89,13 +89,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>已选择: {{ selectedData.length }}</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)">移除</a-button>
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
@ -116,7 +116,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '角色名',
|
||||
|
@ -134,7 +134,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '角色名',
|
||||
|
@ -298,10 +298,7 @@
|
|||
loadData()
|
||||
}
|
||||
const judge = () => {
|
||||
if (radioModel && selectedData.value.length > 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return !(radioModel && selectedData.value.length > 0)
|
||||
}
|
||||
// 添加记录
|
||||
const addRecord = (record) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
title="用户选择"
|
||||
:width="1000"
|
||||
:mask-closable="false"
|
||||
|
@ -22,7 +22,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<div class="table-operator" style="margin-bottom: 10px">
|
||||
<div class="table-operator xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
|
@ -32,7 +32,7 @@
|
|||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button type="primary" class="primarySele" @click="loadData()"> 查询 </a-button>
|
||||
<a-button class="snowy-buttom-left" @click="reset()"> 重置 </a-button>
|
||||
<a-button class="snowy-button-left" @click="reset()"> 重置 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
@ -50,13 +50,16 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>待选择列表 {{ tableRecordNum }} 条</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'avatar'">
|
||||
<a-avatar :src="record.avatar" style="margin-bottom: -5px; margin-top: -5px" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)">添加</a-button>
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'category'">
|
||||
{{ $TOOL.dictTypeData('ROLE_CATEGORY', record.category) }}
|
||||
|
@ -89,13 +92,13 @@
|
|||
>
|
||||
<template #title>
|
||||
<span>已选择: {{ selectedData.length }}</span>
|
||||
<div v-if="!radioModel" style="float: right">
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)">移除</a-button>
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
@ -116,7 +119,12 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
dataIndex: 'avatar',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
|
@ -134,7 +142,7 @@
|
|||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 80
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
|
@ -252,10 +260,7 @@
|
|||
loadData()
|
||||
}
|
||||
const judge = () => {
|
||||
if (radioModel && selectedData.value.length > 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return !(radioModel && selectedData.value.length > 0)
|
||||
}
|
||||
// 添加记录
|
||||
const addRecord = (record) => {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
})
|
||||
// 颜色列表
|
||||
const colorList = ['#7265E6', '#FFBF00', '#00A2AE', '#F56A00', '#1890FF', '#606D80']
|
||||
const colorList = ['#7265E6', '#FFBF00', '#00A2AE', '#F56A00', '#1677FF', '#606D80']
|
||||
// 获取随机颜色
|
||||
const randomColor = () => {
|
||||
if (props.color) {
|
||||
|
|
|
@ -112,7 +112,7 @@ export default {
|
|||
<!-- #bodyCell 放入column表格列需要显示的数据,可以通过判断进行一个自定义显示 -->
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template >
|
||||
<a-avatar style="width: 25px; height: 25px" />
|
||||
<a-avatar class="xn-wh25" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'status'">
|
||||
<!-- 进行自定义显示内容 -->
|
||||
|
@ -199,7 +199,8 @@ const edit = (row) => {
|
|||
| -------------- | ----------------------------------------------- | ----------------- | ------ |
|
||||
| alert | 设置是否显示表格信息栏 | [object, boolean] | null |
|
||||
| showPagination | 显示分页选择器,可传 'auto' \| boolean | [string, boolean] | 'auto' |
|
||||
| data | 加载数据方法 必须为 `Promise` 对象 **必须绑定** | Promise | - |
|
||||
| data | 加载数据方法 必须为 `Promise` 对象 **必须绑定** | Promise | - |
|
||||
| lineSelection | 是否开启点击行高亮显示并选中 | Boolean | 'false' |
|
||||
|
||||
|
||||
`alert` 属性对象:
|
||||
|
@ -245,6 +246,7 @@ result.then((r) => {
|
|||
data.localLoading = false
|
||||
return
|
||||
}
|
||||
// 获取分页数据及分页的显示内容
|
||||
data.localPagination =
|
||||
(props.showPagination &&
|
||||
Object.assign({}, data.localPagination, {
|
||||
|
@ -270,31 +272,35 @@ result.then((r) => {
|
|||
loadData()
|
||||
return
|
||||
}
|
||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||
|
||||
try {
|
||||
/*
|
||||
if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.size))) {
|
||||
data.localPagination.hideOnSinglePage = true
|
||||
}
|
||||
*/
|
||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||
// 没有数据或只有一页数据时隐藏分页栏
|
||||
// if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.pageSize))) {
|
||||
// data.localPagination.hideOnSinglePage = true
|
||||
// }
|
||||
if (!props.showPagination) {
|
||||
data.localPagination.hideOnSinglePage = true
|
||||
}
|
||||
} catch (e) {
|
||||
data.localPagination = false
|
||||
}
|
||||
|
||||
// if (props.showPagination === false) {
|
||||
// // 既然配置了不分页,那么我们这里接收到肯定是数组
|
||||
// console.log(r);
|
||||
// data.localDataSource = []
|
||||
// if (r instanceof Array) {
|
||||
// data.localDataSource = r
|
||||
// }
|
||||
// } else {
|
||||
// data.localDataSource = r.records
|
||||
// }
|
||||
|
||||
// 返回结果中的数组数据
|
||||
if (props.showPagination === false) {
|
||||
// 既然配置了不分页,那么我们这里接收到肯定是数组
|
||||
data.localDataSource = []
|
||||
if (r instanceof Array) {
|
||||
data.localDataSource = r
|
||||
}
|
||||
} else {
|
||||
data.localDataSource = r.records
|
||||
}
|
||||
data.localDataSource = r.records
|
||||
data.localLoading = false
|
||||
getTableProps() // 获取到后端返回的数据后,需要调用一下获取table的props的方法去刷新table
|
||||
getTableProps()
|
||||
})
|
||||
```
|
||||
返回 JSON 例子:
|
||||
|
|
|
@ -89,3 +89,36 @@
|
|||
emit('columnChange', columnsSetting.value)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.s-tool-column-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 16px 4px 4px;
|
||||
.ant-checkbox-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
.s-tool-column-handle {
|
||||
opacity: 0.8;
|
||||
cursor: move;
|
||||
.anticon-more {
|
||||
font-size: 12px;
|
||||
& + .anticon-more {
|
||||
margin: 0px 4px 0 -8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.s-tool-column-header {
|
||||
padding: 5px 16px 10px 24px;
|
||||
min-width: 180px;
|
||||
}
|
||||
.s-tool-column {
|
||||
.ant-divider {
|
||||
margin: 0;
|
||||
}
|
||||
.ant-checkbox-group {
|
||||
padding: 4px 0;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
.table-wrapper{
|
||||
}
|
||||
|
||||
.table-striped td {
|
||||
background-color: var(--table-row-hover-bg);
|
||||
}
|
||||
.s-table-tool{
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
.s-table-tool-left{
|
||||
flex: 1;
|
||||
}
|
||||
.s-table-tool-right{
|
||||
.s-tool-item{
|
||||
font-size: 16px;
|
||||
@apply ml-4;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-tool-column-item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 16px 4px 4px;
|
||||
.ant-checkbox-wrapper{
|
||||
flex: 1;
|
||||
}
|
||||
.s-tool-column-handle{
|
||||
opacity: .8;
|
||||
cursor: move;
|
||||
.anticon-more{
|
||||
font-size: 12px;
|
||||
& + .anticon-more{
|
||||
margin: 0px 4px 0 -8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.s-tool-column-header{
|
||||
padding: 5px 16px 10px 24px;
|
||||
min-width: 180px;
|
||||
}
|
||||
.s-tool-column{
|
||||
.ant-divider{
|
||||
margin: 0;
|
||||
}
|
||||
.ant-checkbox-group{
|
||||
padding: 4px 0;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.s-table-column-settings .ant-popover-inner-content{
|
||||
padding: 0;
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
<div className="layout-items-center ml-4" v-show="props.toolConfig.striped">
|
||||
<a-checkbox :checked="data.localSettings.rowClassNameSwitch" @change="changeRowClass"> 斑马纹 </a-checkbox>
|
||||
</div>
|
||||
<span v-for="item in tool">
|
||||
<span v-for="item in tool" :key="item.name">
|
||||
<!-- 刷新 -->
|
||||
<a-tooltip
|
||||
v-if="item.name === 'refresh' && props.toolConfig.refresh"
|
||||
|
@ -37,7 +37,7 @@
|
|||
</a-tooltip>
|
||||
</a-popover>
|
||||
<!-- 密度 -->
|
||||
<a-dropdown trigger="click" v-if="item.isDropdown && item.name == 'height' && props.toolConfig.height">
|
||||
<a-dropdown trigger="click" v-if="item.isDropdown && item.name === 'height' && props.toolConfig.height">
|
||||
<template #overlay>
|
||||
<a-menu selectable :selectedKeys="[data.customSize]" @click="changeHeight">
|
||||
<a-menu-item key="default">默认</a-menu-item>
|
||||
|
@ -93,29 +93,35 @@
|
|||
|
||||
<!-- 表格 -->
|
||||
<a-table
|
||||
v-bind="{ ...renderTableProps, ...data.localSettings }"
|
||||
@change="loadData"
|
||||
v-bind="{ ...renderTableProps }"
|
||||
:loading="data.localLoading"
|
||||
:row-key="(record) => record.id"
|
||||
@change="loadData"
|
||||
@expand="
|
||||
(expanded, record) => {
|
||||
emit('expand', expanded, record)
|
||||
}
|
||||
"
|
||||
:rowClassName="
|
||||
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
|
||||
"
|
||||
>
|
||||
<template #[item]="scope" v-for="item in renderSlots">
|
||||
<slot v-if="item && renderTableProps.columns.length > 0" :name="item" :scope="scope" v-bind="scope || {}"></slot>
|
||||
<slot
|
||||
v-if="item && renderTableProps.columns && renderTableProps.columns.length > 0"
|
||||
:name="item"
|
||||
:scope="scope"
|
||||
v-bind="scope || {}"
|
||||
/>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import './index.less'
|
||||
import { tableProps } from 'ant-design-vue/es/table/Table.js'
|
||||
import columnSetting from './columnSetting.vue'
|
||||
import { get } from 'lodash-es'
|
||||
import { useSlots } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { get } from 'lodash-es'
|
||||
const slots = useSlots()
|
||||
const route = useRoute()
|
||||
const emit = defineEmits(['expand'])
|
||||
|
@ -191,10 +197,8 @@
|
|||
}
|
||||
})
|
||||
)
|
||||
|
||||
const data = reactive({
|
||||
needTotalList: [],
|
||||
localLoading: false,
|
||||
localDataSource: [],
|
||||
localPagination: Object.assign({}, props.pagination),
|
||||
isFullscreen: false,
|
||||
|
@ -275,11 +279,9 @@
|
|||
getTableProps()
|
||||
}
|
||||
// 斑马纹勾选
|
||||
const changeRowClass = (value) => {
|
||||
const val = value.target.checked
|
||||
data.localSettings.rowClassNameSwitch = val
|
||||
const evenClass = val ? (_record, index) => (index % 2 === 1 ? 'table-striped' : null) : props.rowClassName
|
||||
data.localSettings.rowClassName = evenClass
|
||||
const changeRowClass = (v) => {
|
||||
data.localSettings.rowClassNameSwitch = v.target.checked
|
||||
getTableProps()
|
||||
}
|
||||
// 密度切换
|
||||
const changeHeight = (v) => {
|
||||
|
@ -287,13 +289,12 @@
|
|||
getTableProps()
|
||||
}
|
||||
// 列设置
|
||||
const columnChange = (val) => {
|
||||
data.columnsSetting = val
|
||||
const columnChange = (v) => {
|
||||
data.columnsSetting = v
|
||||
getTableProps()
|
||||
}
|
||||
// 列清空
|
||||
const rowClear = (callback) => {
|
||||
callback
|
||||
clearSelected()
|
||||
}
|
||||
// 初始化
|
||||
|
@ -317,6 +318,7 @@
|
|||
data.columnsSetting = props.columns
|
||||
loadData()
|
||||
}
|
||||
|
||||
const initTotalList = (columns) => {
|
||||
const totalList = []
|
||||
columns &&
|
||||
|
@ -331,9 +333,12 @@
|
|||
})
|
||||
return totalList
|
||||
}
|
||||
|
||||
// 加载数据方法 分页选项器 过滤条件 排序条件
|
||||
const loadData = (pagination, filters, sorter) => {
|
||||
// 设置loading
|
||||
data.localLoading = true
|
||||
// 获取请求数据
|
||||
const parameter = Object.assign(
|
||||
{
|
||||
current:
|
||||
|
@ -359,6 +364,7 @@
|
|||
...filters
|
||||
}
|
||||
)
|
||||
// 用请求数据请求该列表的返回数据
|
||||
const result = props.data(parameter)
|
||||
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
|
||||
result.then((r) => {
|
||||
|
@ -366,6 +372,7 @@
|
|||
data.localLoading = false
|
||||
return
|
||||
}
|
||||
// 获取分页数据及分页的显示内容
|
||||
data.localPagination =
|
||||
(props.showPagination &&
|
||||
Object.assign({}, data.localPagination, {
|
||||
|
@ -379,38 +386,32 @@
|
|||
pageSize: (pagination && pagination.pageSize) || data.localPagination.pageSize
|
||||
})) ||
|
||||
false
|
||||
|
||||
// 后端数据records为null保存修复
|
||||
if (r.records == null) {
|
||||
r.records = []
|
||||
}
|
||||
|
||||
// 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
|
||||
if (r.records.length === 0 && props.showPagination && data.localPagination.current > 1) {
|
||||
data.localPagination.current--
|
||||
loadData()
|
||||
return
|
||||
}
|
||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||
try {
|
||||
/*
|
||||
if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.size))) {
|
||||
data.localPagination.hideOnSinglePage = true
|
||||
}
|
||||
*/
|
||||
// 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能
|
||||
// 没有数据或只有一页数据时隐藏分页栏
|
||||
// if ((['auto', true].includes(props.showPagination) && r.total <= (r.pages * data.localPagination.pageSize))) {
|
||||
// data.localPagination.hideOnSinglePage = true
|
||||
// }
|
||||
if (!props.showPagination) {
|
||||
data.localPagination.hideOnSinglePage = true
|
||||
}
|
||||
} catch (e) {
|
||||
data.localPagination = false
|
||||
}
|
||||
|
||||
// 返回结果中的数组数据
|
||||
if (props.showPagination === false) {
|
||||
// 既然配置了不分页,那么我们这里接收到肯定是数组
|
||||
data.localDataSource = []
|
||||
if (r instanceof Array) {
|
||||
data.localDataSource = r
|
||||
}
|
||||
data.localDataSource = r instanceof Array ? r : r.records
|
||||
} else {
|
||||
data.localDataSource = r.records
|
||||
}
|
||||
|
@ -419,33 +420,37 @@
|
|||
})
|
||||
}
|
||||
}
|
||||
// 加载props
|
||||
|
||||
// 加载table的props
|
||||
const getTableProps = () => {
|
||||
let renderProps = {}
|
||||
const localKeys = Object.keys(data)
|
||||
Object.keys(tableProps()).forEach((k) => {
|
||||
// 这里拿到antd表格的可用API进行过滤
|
||||
Object.keys(Object.assign(tableProps(), props)).forEach((k) => {
|
||||
// 将本地的localdata等默认字段转换为API所提供字段
|
||||
const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}`
|
||||
// 这里去判断是否获取相同的值并且给 table 的 props 赋值
|
||||
if (localKeys.includes(localKey)) {
|
||||
renderProps[k] = data[localKey]
|
||||
return renderProps[k]
|
||||
return
|
||||
}
|
||||
|
||||
// 如果开启了alert,需要将 rowSelection 的事件重新绑定,在切换页面的时候选择栏不会被清空
|
||||
// 如果没打算开启 rowSelection 则清空默认的选择项
|
||||
if (k === 'rowSelection') {
|
||||
if (props.rowSelection) {
|
||||
// 如果需要使用alert,则重新绑定 rowSelection 事件
|
||||
renderProps[k] = {
|
||||
...props.rowSelection,
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
updateSelect(selectedRowKeys, selectedRows)
|
||||
typeof props[k].onChange !== 'undefined' && props[k].onChange(selectedRowKeys, selectedRows)
|
||||
}
|
||||
}
|
||||
return renderProps[k]
|
||||
} else if (!props.rowSelection) {
|
||||
// 如果没打算开启 rowSelection 则清空默认的选择项
|
||||
renderProps[k] = null
|
||||
return renderProps[k]
|
||||
}
|
||||
renderProps[k] = props.rowSelection
|
||||
? {
|
||||
...props.rowSelection,
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
updateSelect(selectedRowKeys, selectedRows)
|
||||
typeof props[k].onChange !== 'undefined' && props[k].onChange(selectedRowKeys, selectedRows)
|
||||
}
|
||||
}
|
||||
: null
|
||||
return
|
||||
}
|
||||
|
||||
// 设置行属性, 点击行时高亮
|
||||
if (k === 'customRow') {
|
||||
if (props.lineSelection && props.rowSelection) {
|
||||
// 如果需要 整行选择,则重新绑定 customRow 事件
|
||||
|
@ -488,19 +493,18 @@
|
|||
return renderProps[k]
|
||||
}
|
||||
}
|
||||
data[k] && (renderProps[k] = data[k])
|
||||
// 此处配置表格大小与要显示的列
|
||||
renderProps = {
|
||||
...renderProps,
|
||||
scroll: props.scroll,
|
||||
bordered: props.bordered,
|
||||
size: data.customSize, // 注意这个size是a-table组件需要的,这里不能跟别的地方成为compSize
|
||||
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked)
|
||||
}
|
||||
return renderProps[k]
|
||||
renderProps[k] = props[k]
|
||||
})
|
||||
renderTableProps.value = renderProps
|
||||
renderProps = {
|
||||
...renderProps,
|
||||
size: data.customSize, // 注意这个size是a-table组件需要的,这里不能跟别的地方成为compSize
|
||||
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
|
||||
...data.localSettings
|
||||
}
|
||||
// 将值为 undefined 或者 null 的 table里props属性进行一个过滤
|
||||
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})
|
||||
}
|
||||
|
||||
// 用于更新已选中的列表数据 total 统计
|
||||
const updateSelect = (selectedRowKeys, selectedRows) => {
|
||||
if (props.rowSelection) {
|
||||
|
@ -544,3 +548,19 @@
|
|||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.s-table-tool {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
.s-table-tool-left {
|
||||
flex: 1;
|
||||
}
|
||||
.s-table-tool-right {
|
||||
.s-tool-item {
|
||||
font-size: 16px;
|
||||
@apply ml-4;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<a-tree-select
|
||||
v-model:value="defaultSelectKeys"
|
||||
show-search
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择菜单"
|
||||
:field-names="treeFieldNames"
|
||||
|
|
|
@ -32,5 +32,33 @@
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import './index.less';
|
||||
.up,
|
||||
.down {
|
||||
margin-left: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.83);
|
||||
}
|
||||
}
|
||||
.item-text {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
.up {
|
||||
color: @red-6;
|
||||
}
|
||||
.down {
|
||||
color: @green-6;
|
||||
top: -1px;
|
||||
}
|
||||
&.reverse-color .up {
|
||||
color: @green-6;
|
||||
}
|
||||
&.reverse-color .down {
|
||||
color: @red-6;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<template>
|
||||
<a-popconfirm
|
||||
title="批量处理此信息?"
|
||||
:visible="batchVisible"
|
||||
@visibleChange="batchVisibleChange"
|
||||
@confirm="deleteBatch"
|
||||
>
|
||||
<a-popconfirm title="批量处理此信息?" :open="batchVisible" @openChange="batchVisibleChange" @confirm="deleteBatch">
|
||||
<a-button :type="props.buttonType" :danger="props.buttonDanger" :size="props.size" :loading="buttonLoading">
|
||||
<template #icon v-if="props.icon">
|
||||
<component :is="props.icon" :style="{ color: props.color }" />
|
||||
|
@ -30,11 +25,11 @@
|
|||
},
|
||||
buttonType: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
default: () => undefined
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
default: () => undefined
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
|
@ -74,7 +69,7 @@
|
|||
emit('batchCallBack', params)
|
||||
}
|
||||
// 打开loading
|
||||
const loading = () => {
|
||||
const openLoading = () => {
|
||||
buttonLoading.value = true
|
||||
}
|
||||
// 关闭loading
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<a-popconfirm
|
||||
title="删除此信息?"
|
||||
:visible="deleteVisible"
|
||||
@visibleChange="deleteVisibleChange"
|
||||
:open="deleteVisible"
|
||||
@openChange="deleteVisibleChange"
|
||||
@confirm="deleteBatch"
|
||||
>
|
||||
<a-button danger>
|
||||
|
|
|
@ -1,47 +1,49 @@
|
|||
<template>
|
||||
<a-space class="go-back-button">
|
||||
<a-button type="primary" :href="props.src" target="_blank">
|
||||
<a-button :href="props.src" size="small" target="_blank">
|
||||
<template #icon><download-outlined /></template>
|
||||
</a-button>
|
||||
<a-button type="primary" @click="emit('goBack')">
|
||||
<a-button type="primary" size="small" @click="emit('goBack')">
|
||||
<template #icon><rollback-outlined /></template>
|
||||
返回
|
||||
</a-button>
|
||||
</a-space>
|
||||
<a-card :bordered="false" :body-style="{ padding: '0px' }">
|
||||
<vue-office-docx
|
||||
v-if="props.fileType.toLowerCase() === 'doc' || props.fileType.toLowerCase() === 'docx'"
|
||||
:src="props.src"
|
||||
style="height: 82vh"
|
||||
@rendered="renderedHandler"
|
||||
/>
|
||||
<vue-office-excel
|
||||
v-else-if="props.fileType.toLowerCase() === 'xls' || props.fileType.toLowerCase() === 'xlsx'"
|
||||
:src="props.src"
|
||||
style="height: 82vh"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<vue-office-pdf
|
||||
v-else-if="props.fileType.toLowerCase() === 'pdf'"
|
||||
:src="props.src"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<img
|
||||
v-else-if="
|
||||
props.fileType.toLowerCase() === 'png' ||
|
||||
props.fileType.toLowerCase() === 'jpg' ||
|
||||
props.fileType.toLowerCase() === 'gif' ||
|
||||
props.fileType.toLowerCase() === 'bmp' ||
|
||||
props.fileType.toLowerCase() === 'jpeg' ||
|
||||
props.fileType.toLowerCase() === 'ico' ||
|
||||
props.fileType.toLowerCase() === 'svg'
|
||||
"
|
||||
:src="props.src"
|
||||
style="max-width: 100%"
|
||||
/>
|
||||
<a-result v-else status="warning" title="不支持预览的文件类型" />
|
||||
<a-spin :spinning="loading">
|
||||
<vue-office-docx
|
||||
v-if="fileType === 'doc' || fileType === 'docx'"
|
||||
:src="props.src"
|
||||
class="xn-ht82"
|
||||
@rendered="renderedHandler"
|
||||
/>
|
||||
<vue-office-excel
|
||||
v-else-if="fileType === 'xls' || fileType === 'xlsx'"
|
||||
:src="props.src"
|
||||
class="xn-ht82"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<vue-office-pdf
|
||||
v-else-if="fileType === 'pdf'"
|
||||
:src="props.src"
|
||||
@rendered="renderedHandler"
|
||||
@error="errorHandler"
|
||||
/>
|
||||
<img
|
||||
v-else-if="
|
||||
fileType === 'png' ||
|
||||
fileType === 'jpg' ||
|
||||
fileType === 'gif' ||
|
||||
fileType === 'bmp' ||
|
||||
fileType === 'jpeg' ||
|
||||
fileType === 'ico' ||
|
||||
fileType === 'svg'
|
||||
"
|
||||
:src="props.src"
|
||||
class="xn-mwh"
|
||||
/>
|
||||
<a-result v-else status="warning" title="不支持预览的文件类型" />
|
||||
</a-spin>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
|
@ -58,6 +60,7 @@
|
|||
//引入VueOfficePdf组件
|
||||
import VueOfficePdf from '@vue-office/pdf'
|
||||
|
||||
const loading = ref(false)
|
||||
const emit = defineEmits({ goBack: null })
|
||||
const props = defineProps({
|
||||
src: {
|
||||
|
@ -72,8 +75,31 @@
|
|||
required: false
|
||||
}
|
||||
})
|
||||
const fileType = ref()
|
||||
watch(
|
||||
() => props.src,
|
||||
() => {
|
||||
fileType.value = props.fileType.toLowerCase()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => props.src,
|
||||
() => {
|
||||
if (
|
||||
fileType.value === 'doc' ||
|
||||
fileType.value === 'docx' ||
|
||||
fileType.value === 'xls' ||
|
||||
fileType.value === 'xlsx' ||
|
||||
fileType.value === 'pdf'
|
||||
) {
|
||||
loading.value = true
|
||||
}
|
||||
}
|
||||
)
|
||||
// 渲染完成
|
||||
const renderedHandler = () => {}
|
||||
const renderedHandler = () => {
|
||||
loading.value = false
|
||||
}
|
||||
// 渲染失败
|
||||
const errorHandler = () => {
|
||||
message.warning('渲染失败,请尝试重新打开!')
|
||||
|
@ -81,6 +107,12 @@
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.xn-mwh {
|
||||
max-width: 100%;
|
||||
}
|
||||
.xn-ht82 {
|
||||
height: 82vh;
|
||||
}
|
||||
.go-back-button {
|
||||
position: absolute;
|
||||
float: right;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<a-modal v-if="isModal" :visible="visible" @cancel="cancel" v-bind="$attrs">
|
||||
<a-modal v-if="isModal" :open="visible" @cancel="cancel" v-bind="$attrs">
|
||||
<template v-for="slotKey in slotKeys" #[slotKey]>
|
||||
<slot :name="slotKey" />
|
||||
</template>
|
||||
</a-modal>
|
||||
<a-drawer v-else :visible="visible" v-bind="$attrs" @close="cancel" :footer-style="{ textAlign: 'right' }">
|
||||
<a-drawer v-else :open="visible" v-bind="$attrs" @close="cancel" :footer-style="{ textAlign: 'right' }">
|
||||
<template v-for="slotKey in slotKeys" #[slotKey]>
|
||||
<slot :name="slotKey" />
|
||||
</template>
|
||||
|
@ -13,23 +13,20 @@
|
|||
|
||||
<script setup>
|
||||
import { useSlots } from 'vue'
|
||||
const slots = useSlots()
|
||||
|
||||
import { globalStore } from '@/store'
|
||||
const slots = useSlots()
|
||||
const store = globalStore()
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
required: false
|
||||
}
|
||||
})
|
||||
|
||||
const FormContainerTypeEnum = {
|
||||
DRAWER: 'drawer',
|
||||
MODAL: 'modal'
|
||||
}
|
||||
|
||||
const formStyle = computed(() => {
|
||||
return store.formStyle
|
||||
})
|
||||
|
@ -44,7 +41,6 @@
|
|||
emit('close')
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// 声明额外的选项
|
||||
export default {
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
<template>
|
||||
<!-- 本组件这兄弟写的很好 请参照:https://blog.csdn.net/weixin_41897680/article/details/124925222-->
|
||||
<div class="hljs-container" :codetype="props.language">
|
||||
<a-button v-if="props.copy" size="small" type="primary" class="hljs-copy" @click="codeCopy">
|
||||
<CopyOutlined />
|
||||
拷贝
|
||||
</a-button>
|
||||
<highlightjs :language="props.language" :autodetect="!props.language" :code="props.code" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="XnHighlightjs">
|
||||
/*import 'highlight.js/styles/atom-one-dark.css'
|
||||
import 'highlight.js/lib/common'
|
||||
import hljsVuePlugin from '@highlightjs/vue-plugin'*/
|
||||
|
||||
import { message } from 'ant-design-vue'
|
||||
const props = defineProps({
|
||||
language: {
|
||||
type: String,
|
||||
|
@ -18,41 +19,27 @@
|
|||
code: {
|
||||
type: String,
|
||||
default: () => '无'
|
||||
},
|
||||
copy: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
}
|
||||
})
|
||||
const codeCopy = () => {
|
||||
copyTextToClipboard(props.code).then(() => {
|
||||
message.success('拷贝成功')
|
||||
})
|
||||
}
|
||||
const copyTextToClipboard = async (text) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
} catch (err) {
|
||||
message.warning('拷贝失败')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* 语法高亮 */
|
||||
/*.hljs-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 30px 5px 2px;
|
||||
overflow-x: hidden;
|
||||
line-height: 20px;
|
||||
text-align: left;
|
||||
background: #21252b;
|
||||
box-shadow: 0 10px 30px 0 rgb(0 0 0 / 40%);
|
||||
}*/
|
||||
/** 3个点 */
|
||||
/*.hljs-container::before {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 15px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
overflow: visible;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 12px;
|
||||
white-space: nowrap;
|
||||
text-indent: 75px;
|
||||
background-color: #fc625d;
|
||||
border-radius: 16px;
|
||||
box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
|
||||
content: attr(codetype);
|
||||
}*/
|
||||
|
||||
/** 滚动条 */
|
||||
:deep(.hljs, .hljs-container) {
|
||||
max-height: 300px !important;
|
||||
|
@ -88,4 +75,12 @@
|
|||
::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
}
|
||||
/** 复制样式 */
|
||||
.hljs-copy {
|
||||
float: right;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
v-model:value="modelValue"
|
||||
:options="options"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:placeholder="props.placeholder"
|
||||
:allow-clear="props.allowClear"
|
||||
:disabled="props.disabled"
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
<template>
|
||||
<xn-form-container
|
||||
ref="signModel"
|
||||
v-model:visible="visible"
|
||||
:width="700"
|
||||
title="电子签名"
|
||||
@close="handleClear"
|
||||
@ok="handleOk"
|
||||
>
|
||||
<xn-form-container :visible="visible" :width="700" title="电子签名" @close="handleClear" @ok="handleOk">
|
||||
<a-row :gutter="5">
|
||||
<a-col :span="15">
|
||||
<div style="border: 1px solid rgb(236 236 236)">
|
||||
<div class="xn-bdr236">
|
||||
<vue-esign
|
||||
ref="esign"
|
||||
ref="esignRef"
|
||||
v-model:bgColor="bgColor"
|
||||
:width="800"
|
||||
:height="400"
|
||||
|
@ -23,12 +16,12 @@
|
|||
</div>
|
||||
</a-col>
|
||||
<a-col :span="9">
|
||||
<div style="height: 90px; width: auto">
|
||||
<img :src="resultImg" style="height: 90px; width: 100%; border: 1px solid rgb(236 236 236)" />
|
||||
<div class="xn-h90wat">
|
||||
<img :src="resultImg" class="xn-bdr236 xn-h90w100" />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div style="margin-top: 10px">
|
||||
<div class="xn-mt10">
|
||||
<a-space>
|
||||
<a-form>
|
||||
<a-row :gutter="16">
|
||||
|
@ -39,7 +32,7 @@
|
|||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<div style="padding-right: 50px">是否裁剪:<a-checkbox v-model:checked="isCrop"></a-checkbox></div>
|
||||
<div class="xn-pr50">是否裁剪:<a-checkbox v-model:checked="isCrop"></a-checkbox></div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@ -49,7 +42,7 @@
|
|||
</a-space>
|
||||
</div>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="handleClear">取消</a-button>
|
||||
<a-button class="xn-mr8" @click="handleClear">取消</a-button>
|
||||
<a-button type="primary" @click="handleOk">确定</a-button>
|
||||
</template>
|
||||
</xn-form-container>
|
||||
|
@ -57,13 +50,12 @@
|
|||
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue'
|
||||
import vueEsign from './vueEsign.vue'
|
||||
const signModel = ref(false)
|
||||
import VueEsign from './vueEsign.vue'
|
||||
const visible = ref(false)
|
||||
const esign = ref(false)
|
||||
const esignRef = ref(false)
|
||||
const resultImg = ref('')
|
||||
const isCrop = ref(false)
|
||||
const lineWidth = ref(6)
|
||||
const lineWidth = ref(10)
|
||||
const lineColor = ref('#000000')
|
||||
const bgColor = ref('')
|
||||
const props = defineProps(['image'])
|
||||
|
@ -74,11 +66,11 @@
|
|||
visible.value = true
|
||||
}
|
||||
const handleReset = () => {
|
||||
esign.value.reset()
|
||||
esignRef.value.reset()
|
||||
resultImg.value = ''
|
||||
}
|
||||
const handleGenerate = () => {
|
||||
esign.value
|
||||
esignRef.value
|
||||
.generate()
|
||||
.then((res) => {
|
||||
resultImg.value = res
|
||||
|
@ -91,7 +83,7 @@
|
|||
visible.value = false
|
||||
}
|
||||
const handleOk = () => {
|
||||
esign.value
|
||||
esignRef.value
|
||||
.generate()
|
||||
.then((res) => {
|
||||
emit('successful', res)
|
||||
|
@ -107,7 +99,24 @@
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.xn-h90w100 {
|
||||
height: 90px;
|
||||
width: 100%;
|
||||
}
|
||||
.xn-mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.xn-h90wat {
|
||||
height: 90px;
|
||||
width: auto;
|
||||
}
|
||||
.xn-bdr236 {
|
||||
border: 1px solid rgb(236 236 236);
|
||||
}
|
||||
.ant-form-item {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
.xn-pr50 {
|
||||
padding-right: 50px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -87,7 +87,9 @@
|
|||
canvas.value.height = props.height
|
||||
canvas.value.width = props.width
|
||||
canvas.value.style.background = myBg.value
|
||||
$_resizeHandler()
|
||||
setTimeout(() => {
|
||||
$_resizeHandler()
|
||||
})
|
||||
// 在画板以外松开鼠标后冻结画笔
|
||||
document.onmouseup = () => {
|
||||
isDrawing.value = false
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
## 小诺人员选择器
|
||||
|
||||
### 说明
|
||||
|
||||
改组件为小诺人员选择器,可返回id用逗号隔离的字符串或id数组类型的数据格式
|
||||
|
||||
@author yubaoshan
|
||||
|
||||
@data 2024年4月13日23:59:23
|
||||
|
||||
### props定义
|
||||
|
||||
| 序号 | 编码 | 类型 | 说明 | 默认 |
|
||||
|-----|---------------------|---------------|------------------------------|--------|
|
||||
| 1 | radioModel | Boolean | 是否单选;与addShow隐藏同时可用 | false |
|
||||
| 2 | dataIsConverterFlw | Boolean | 是否为工作流格式 | false |
|
||||
| 3 | orgTreeApi | function | 机构树接口 | - |
|
||||
| 4 | userPageApi | function | 用户分页接口 | - |
|
||||
| 5 | userListByIdListApi | function | 通过id数组查询list数据接口 | - |
|
||||
| 6 | value | object或string | 通过v-model:value绑定数据 | - |
|
||||
| 7 | dataType | string | 数据类型object或string | string |
|
||||
| 8 | userShow | Boolean | 是否显示已选择用户(非表单内、单纯的选择用户需要隐藏) | true |
|
||||
| 9 | addShow | Boolean | 是否默认的增加人员按钮,与radioModel为或的关系 | true |
|
||||
|
||||
### emits定义
|
||||
|
||||
| 序号 | 方法名 | 参数类型 | 说明 |
|
||||
|----|--------|----------------|---------------------------------|
|
||||
| 1 | value | 根据 dataType 而定 | 当选择用户后通过v-model:value绑定到组件上 |
|
||||
| 2 | onBack | 根据 dataType 而定 | 通过@onBack 方法返回选中的数据,触发点为选中或删除用户 |
|
||||
|
||||
### slot定义
|
||||
|
||||
| 序号 | 插槽名 | 用途 | 用途 |
|
||||
|----|--------|-------------------|-------------------|
|
||||
| 1 | button | 在人员新增按钮后可以插入自定义按钮 | 不满足新增人员按钮样式,可以自定义 |
|
|
@ -0,0 +1,622 @@
|
|||
<template>
|
||||
<!-- 这是引入后展示的样式 -->
|
||||
<div style="display: flex" v-if="props.userShow">
|
||||
<div
|
||||
class="user-container"
|
||||
v-for="(user, index) in userObj"
|
||||
:key="user.id"
|
||||
@mouseover="onMouseEnter(index)"
|
||||
@mouseleave="onMouseLeave(index)"
|
||||
>
|
||||
<span class="user-delete">
|
||||
<CloseCircleFilled
|
||||
:class="index === deleteShow ? 'show-delete-icon' : ''"
|
||||
class="delete-icon"
|
||||
@click="deleteUser(user)"
|
||||
/>
|
||||
<a-avatar :src="user.avatar" />
|
||||
</span>
|
||||
<span class="user-name">{{ user.name }}</span>
|
||||
</div>
|
||||
<a-button shape="circle" @click="openModal" v-if="(props.radioModel ? userObj.length !== 1 : true) && addShow">
|
||||
<PlusOutlined />
|
||||
</a-button>
|
||||
<slot name="button"></slot>
|
||||
</div>
|
||||
|
||||
<!-- 以下是弹窗内容 -->
|
||||
<a-modal
|
||||
v-model:open="visible"
|
||||
title="用户选择"
|
||||
:width="1000"
|
||||
:mask-closable="false"
|
||||
:destroy-on-close="true"
|
||||
@ok="handleOk"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<a-row :gutter="10">
|
||||
<a-col :span="7">
|
||||
<a-card size="small" :loading="cardLoading" class="selectorTreeDiv">
|
||||
<a-tree
|
||||
v-if="treeData"
|
||||
v-model:expandedKeys="defaultExpandedKeys"
|
||||
:tree-data="treeData"
|
||||
:field-names="treeFieldNames"
|
||||
@select="treeSelect"
|
||||
>
|
||||
</a-tree>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="11">
|
||||
<div class="table-operator xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item name="searchKey">
|
||||
<a-input v-model:value="searchFormState.searchKey" placeholder="请输入用户名" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-button type="primary" class="xn-mr-10" @click="loadData()"> 查询 </a-button>
|
||||
<a-button @click="reset()"> 重置 </a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<div class="user-table">
|
||||
<a-table
|
||||
ref="tableRef"
|
||||
size="small"
|
||||
:columns="commons"
|
||||
:data-source="tableData"
|
||||
:expand-row-by-click="true"
|
||||
:loading="pageLoading"
|
||||
bordered
|
||||
:pagination="false"
|
||||
>
|
||||
<template #title>
|
||||
<span>待选择列表 {{ tableRecordNum }} 条</span>
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'avatar'">
|
||||
<a-avatar :src="record.avatar" style="margin-bottom: -5px; margin-top: -5px" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'category'">
|
||||
{{ $TOOL.dictTypeData('ROLE_CATEGORY', record.category) }}
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="mt-2">
|
||||
<a-pagination
|
||||
v-if="!isEmpty(tableData)"
|
||||
v-model:current="current"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
size="small"
|
||||
showSizeChanger
|
||||
@change="paginationChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div class="user-table">
|
||||
<a-table
|
||||
ref="selectedTable"
|
||||
size="small"
|
||||
:columns="selectedCommons"
|
||||
:data-source="selectedData"
|
||||
:expand-row-by-click="true"
|
||||
:loading="selectedTableListLoading"
|
||||
bordered
|
||||
>
|
||||
<template #title>
|
||||
<span>已选择: {{ selectedData.length }}</span>
|
||||
<div v-if="!radioModel" class="xn-fdr">
|
||||
<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup name="userSelector">
|
||||
import { message } from 'ant-design-vue'
|
||||
import { remove, isEmpty, cloneDeep } from 'lodash-es'
|
||||
// 弹窗是否打开
|
||||
const visible = ref(false)
|
||||
const deleteShow = ref('')
|
||||
// 主表格common
|
||||
const commons = [
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
dataIndex: 'avatar',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'name',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '账号',
|
||||
dataIndex: 'account'
|
||||
}
|
||||
]
|
||||
// 选中表格的表格common
|
||||
const selectedCommons = [
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
align: 'center',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'name',
|
||||
ellipsis: true
|
||||
}
|
||||
]
|
||||
const props = defineProps({
|
||||
radioModel: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
dataIsConverterFlw: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
},
|
||||
orgTreeApi: {
|
||||
type: Function,
|
||||
default: () => undefined
|
||||
},
|
||||
userPageApi: {
|
||||
type: Function,
|
||||
default: () => undefined
|
||||
},
|
||||
userListByIdListApi: {
|
||||
type: Function,
|
||||
default: () => undefined
|
||||
},
|
||||
value: {
|
||||
default: () => ''
|
||||
},
|
||||
dataType: {
|
||||
type: String,
|
||||
default: () => 'string'
|
||||
},
|
||||
userShow: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
},
|
||||
addShow: {
|
||||
type: Boolean,
|
||||
default: () => true
|
||||
}
|
||||
})
|
||||
// 主表格的ref 名称
|
||||
const tableRef = ref()
|
||||
// 选中表格的ref 名称
|
||||
const selectedTable = ref()
|
||||
const tableRecordNum = ref()
|
||||
const searchFormState = ref({})
|
||||
const searchFormRef = ref()
|
||||
const cardLoading = ref(true)
|
||||
const pageLoading = ref(false)
|
||||
const selectedTableListLoading = ref(false)
|
||||
// 替换treeNode 中 title,key,children
|
||||
const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
|
||||
// 获取机构树数据
|
||||
const treeData = ref()
|
||||
// 默认展开二级树的节点id
|
||||
const defaultExpandedKeys = ref([])
|
||||
const emit = defineEmits(['update:value', 'onBack'])
|
||||
const tableData = ref([])
|
||||
const selectedData = ref([])
|
||||
const recordIds = ref([])
|
||||
// 分页相关
|
||||
const current = ref(0) // 当前页数
|
||||
const pageSize = ref(20) // 每页条数
|
||||
const total = ref(0) // 数据总数
|
||||
// 打开弹框
|
||||
const showUserPlusModal = (ids = []) => {
|
||||
const data = goDataConverter(ids)
|
||||
recordIds.value = data
|
||||
getUserAvatarById(data)
|
||||
openModal()
|
||||
}
|
||||
const onMouseEnter = (index) => {
|
||||
deleteShow.value = index
|
||||
}
|
||||
const onMouseLeave = (index) => {
|
||||
deleteShow.value = ''
|
||||
}
|
||||
const openModal = () => {
|
||||
if (typeof props.orgTreeApi !== 'function') {
|
||||
message.warning('未配置选择器需要的orgTreeApi接口')
|
||||
return
|
||||
}
|
||||
if (typeof props.userPageApi !== 'function') {
|
||||
message.warning('未配置选择器需要的userPageApi接口')
|
||||
return
|
||||
}
|
||||
if (typeof props.userListByIdListApi !== 'function') {
|
||||
message.warning('未配置选择器需要的userListByIdListApi接口')
|
||||
return
|
||||
}
|
||||
visible.value = true
|
||||
// 获取机构树
|
||||
props
|
||||
.orgTreeApi()
|
||||
.then((data) => {
|
||||
if (data !== null) {
|
||||
treeData.value = data
|
||||
// 默认展开2级
|
||||
treeData.value.forEach((item) => {
|
||||
// 因为0的顶级
|
||||
if (item.parentId === '0') {
|
||||
defaultExpandedKeys.value.push(item.id)
|
||||
// 取到下级ID
|
||||
if (item.children) {
|
||||
item.children.forEach((items) => {
|
||||
defaultExpandedKeys.value.push(items.id)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
cardLoading.value = false
|
||||
})
|
||||
searchFormState.value.size = pageSize.value
|
||||
loadData()
|
||||
if (props.userListByIdListApi) {
|
||||
if (isEmpty(recordIds.value)) {
|
||||
return
|
||||
}
|
||||
const param = {
|
||||
idList: recordIds.value
|
||||
}
|
||||
selectedTableListLoading.value = true
|
||||
props
|
||||
.userListByIdListApi(param)
|
||||
.then((data) => {
|
||||
selectedData.value = data
|
||||
})
|
||||
.finally(() => {
|
||||
selectedTableListLoading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
// 点击头像删除用户
|
||||
const deleteUser = (user) => {
|
||||
// 删除显示的
|
||||
remove(userObj.value, (item) => item.id === user.id)
|
||||
// 删除缓存的
|
||||
remove(recordIds.value, (item) => item === user.id)
|
||||
const value = []
|
||||
const showUser = []
|
||||
userObj.value.forEach((item) => {
|
||||
const obj = {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}
|
||||
value.push(item.id)
|
||||
// 拷贝一份obj数据
|
||||
const objClone = cloneDeep(obj)
|
||||
objClone.avatar = item.avatar
|
||||
showUser.push(objClone)
|
||||
})
|
||||
userObj.value = showUser
|
||||
// 判断是否做数据的转换为工作流需要的
|
||||
const resultData = outDataConverter(value)
|
||||
emit('update:value', resultData)
|
||||
emit('onBack', resultData)
|
||||
}
|
||||
// 查询主表格数据
|
||||
const loadData = () => {
|
||||
pageLoading.value = true
|
||||
props
|
||||
.userPageApi(searchFormState.value)
|
||||
.then((data) => {
|
||||
current.value = data.current
|
||||
// pageSize.value = data.size
|
||||
total.value = data.total
|
||||
// 重置、赋值
|
||||
tableData.value = []
|
||||
tableRecordNum.value = 0
|
||||
tableData.value = data.records
|
||||
if (data.records) {
|
||||
tableRecordNum.value = data.records.length
|
||||
} else {
|
||||
tableRecordNum.value = 0
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
pageLoading.value = false
|
||||
})
|
||||
}
|
||||
// pageSize改变回调分页事件
|
||||
const paginationChange = (page, pageSize) => {
|
||||
searchFormState.value.current = page
|
||||
searchFormState.value.size = pageSize
|
||||
loadData()
|
||||
}
|
||||
const judge = () => {
|
||||
return !(props.radioModel && selectedData.value.length > 0)
|
||||
}
|
||||
// 添加记录
|
||||
const addRecord = (record) => {
|
||||
if (!judge()) {
|
||||
message.warning('只可选择一条')
|
||||
return
|
||||
}
|
||||
const selectedRecord = selectedData.value.filter((item) => item.id === record.id)
|
||||
if (selectedRecord.length === 0) {
|
||||
selectedData.value.push(record)
|
||||
} else {
|
||||
message.warning('该记录已存在')
|
||||
}
|
||||
}
|
||||
// 添加全部
|
||||
const addAllPageRecord = () => {
|
||||
let newArray = selectedData.value.concat(tableData.value)
|
||||
let list = []
|
||||
for (let item1 of newArray) {
|
||||
let flag = true
|
||||
for (let item2 of list) {
|
||||
if (item1.id === item2.id) {
|
||||
flag = false
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
list.push(item1)
|
||||
}
|
||||
}
|
||||
selectedData.value = list
|
||||
}
|
||||
// 删减记录
|
||||
const delRecord = (record) => {
|
||||
remove(selectedData.value, (item) => item.id === record.id)
|
||||
}
|
||||
// 删减记录
|
||||
const delAllRecord = () => {
|
||||
selectedData.value = []
|
||||
}
|
||||
// 点击树查询
|
||||
const treeSelect = (selectedKeys) => {
|
||||
searchFormState.value.current = 0
|
||||
if (selectedKeys.length > 0) {
|
||||
searchFormState.value.orgId = selectedKeys.toString()
|
||||
} else {
|
||||
delete searchFormState.value.orgId
|
||||
}
|
||||
loadData()
|
||||
}
|
||||
const userObj = ref([])
|
||||
// 确定
|
||||
const handleOk = () => {
|
||||
userObj.value = []
|
||||
const value = []
|
||||
const showUser = []
|
||||
selectedData.value.forEach((item) => {
|
||||
const obj = {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}
|
||||
value.push(item.id)
|
||||
// 拷贝一份obj数据
|
||||
const objClone = cloneDeep(obj)
|
||||
objClone.avatar = item.avatar
|
||||
showUser.push(objClone)
|
||||
})
|
||||
userObj.value = showUser
|
||||
// 判断是否做数据的转换为工作流需要的
|
||||
const resultData = outDataConverter(value)
|
||||
emit('update:value', resultData)
|
||||
emit('onBack', resultData)
|
||||
handleClose()
|
||||
}
|
||||
// 重置
|
||||
const reset = () => {
|
||||
delete searchFormState.value.searchKey
|
||||
loadData()
|
||||
}
|
||||
const handleClose = () => {
|
||||
searchFormState.value = {}
|
||||
tableRecordNum.value = 0
|
||||
tableData.value = []
|
||||
current.value = 0
|
||||
pageSize.value = 20
|
||||
total.value = 0
|
||||
selectedData.value = []
|
||||
// userObj.value = []
|
||||
visible.value = false
|
||||
}
|
||||
// 数据进入后转换
|
||||
const goDataConverter = (data) => {
|
||||
if (props.dataIsConverterFlw) {
|
||||
const resultData = []
|
||||
// 处理对象
|
||||
if (!isEmpty(data.value)) {
|
||||
const values = data.value.split(',')
|
||||
if (values.length > 0) {
|
||||
values.forEach((id) => {
|
||||
resultData.push(id)
|
||||
})
|
||||
} else {
|
||||
resultData.push(data.value)
|
||||
}
|
||||
} else {
|
||||
// 处理数组
|
||||
if (!isEmpty(data) && !isEmpty(data[0]) && !isEmpty(data[0].value)) {
|
||||
const values = data[0].value.split(',')
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
resultData.push(values[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultData
|
||||
} else {
|
||||
if (getValueType() !== 'string') {
|
||||
return data
|
||||
}
|
||||
if (data.length > 1) {
|
||||
const resultData = []
|
||||
data.split(',').forEach((id) => {
|
||||
resultData.push(id)
|
||||
})
|
||||
return resultData
|
||||
} else {
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
// 数据出口转换器
|
||||
const outDataConverter = (data) => {
|
||||
if (props.dataIsConverterFlw) {
|
||||
data = userObj.value
|
||||
const obj = {}
|
||||
let label = ''
|
||||
let value = ''
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data.length === i + 1) {
|
||||
label = label + data[i].name
|
||||
value = value + data[i].id
|
||||
} else {
|
||||
label = label + data[i].name + ','
|
||||
value = value + data[i].id + ','
|
||||
}
|
||||
}
|
||||
obj.key = 'USER'
|
||||
obj.label = label
|
||||
obj.value = value
|
||||
obj.extJson = ''
|
||||
return obj
|
||||
} else {
|
||||
if (getValueType() !== 'string') {
|
||||
return data
|
||||
}
|
||||
let resultData = ''
|
||||
data.forEach((id) => {
|
||||
resultData = resultData + ',' + id
|
||||
})
|
||||
resultData = resultData.substring(1, resultData.length)
|
||||
return resultData
|
||||
}
|
||||
}
|
||||
// 获取数据类型
|
||||
const getValueType = () => {
|
||||
if (props.dataType) {
|
||||
return props.dataType
|
||||
} else {
|
||||
if (props.radioModel) {
|
||||
return 'string'
|
||||
}
|
||||
return typeof typeof props.value
|
||||
}
|
||||
}
|
||||
const getUserAvatarById = (ids) => {
|
||||
if (isEmpty(userObj.value) && !isEmpty(ids)) {
|
||||
const param = {
|
||||
idList: recordIds.value
|
||||
}
|
||||
// 这里必须转为数组类型的
|
||||
props.userListByIdListApi(param).then((data) => {
|
||||
userObj.value = data
|
||||
})
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => props.value,
|
||||
(newValue) => {
|
||||
if (!isEmpty(props.value)) {
|
||||
const ids = goDataConverter(newValue)
|
||||
recordIds.value = ids
|
||||
getUserAvatarById(ids)
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true // 立即执行
|
||||
}
|
||||
)
|
||||
defineExpose({
|
||||
showUserPlusModal
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.xn-mr-5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.xn-mr-10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.selectorTreeDiv {
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
}
|
||||
.ant-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.user-table {
|
||||
overflow: auto;
|
||||
max-height: 450px;
|
||||
}
|
||||
|
||||
.user-container {
|
||||
display: flex;
|
||||
align-items: center; /* 垂直居中 */
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.user-avatar {
|
||||
width: 30px;
|
||||
border-radius: 50%; /* 设置为50%以创建圆形头像 */
|
||||
}
|
||||
.user-name {
|
||||
font-size: 12px;
|
||||
max-width: 50px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.user-delete {
|
||||
z-index: 99;
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.delete-icon {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
z-index: 5;
|
||||
top: -3px;
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
}
|
||||
.show-delete-icon {
|
||||
visibility: visible;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
||||
表单的值:{{ formData }}
|
||||
<a-form-item name="userIdList">
|
||||
<xn-user-selector
|
||||
ref="userSelectorPlusProRef"
|
||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||
:user-page-api="selectorApiFunction.userPageApi"
|
||||
:user-list-by-id-list-api="selectorApiFunction.userListByIdListApi"
|
||||
v-model:value="formData.userIdList"
|
||||
@onBack="userSelectorOnBack"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-button type="primary" @click="onSubmit">保存</a-button>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script setup name="userTest">
|
||||
import bizOrgApi from '@/api/biz/bizOrgApi'
|
||||
import userCenterApi from '@/api/sys/userCenterApi'
|
||||
import { required } from '@/utils/formRules'
|
||||
const formRef = ref()
|
||||
const formData = ref({
|
||||
userIdList: '1543837863788879871,1543837863788879873'
|
||||
// userIdList: ['1543837863788879871', '1543837863788879873']
|
||||
})
|
||||
const formRules = {
|
||||
userIdList: [required('请选择用户')]
|
||||
}
|
||||
const onSubmit = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then((result) => {
|
||||
console.log('最终表单数据:' + JSON.stringify(result))
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
// 传递设计器需要的API
|
||||
const selectorApiFunction = {
|
||||
orgTreeApi: (param) => {
|
||||
return bizOrgApi.orgTreeSelector(param).then((data) => {
|
||||
return Promise.resolve(data)
|
||||
})
|
||||
},
|
||||
userPageApi: (param) => {
|
||||
return bizOrgApi.orgUserSelector(param).then((data) => {
|
||||
return Promise.resolve(data)
|
||||
})
|
||||
},
|
||||
userListByIdListApi: (param) => {
|
||||
return userCenterApi.userCenterGetUserListByIdList(param).then((data) => {
|
||||
return Promise.resolve(data)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 如果用 v-model:value 来关联,这个可以不需要
|
||||
const userSelectorOnBack = (data) => {
|
||||
console.log('返回的:' + JSON.stringify(data))
|
||||
}
|
||||
</script>
|
|
@ -30,7 +30,7 @@ const DEFAULT_CONFIG = {
|
|||
// 请求是否开启缓存
|
||||
REQUEST_CACHE: false,
|
||||
|
||||
// 布局 经典:classical,双排菜单:doublerow
|
||||
// 布局 经典:classical,双排菜单:doublerow, 顶栏菜单:top
|
||||
SNOWY_LAYOUT: 'doublerow',
|
||||
|
||||
// 菜单是否折叠
|
||||
|
@ -54,11 +54,20 @@ const DEFAULT_CONFIG = {
|
|||
// 侧边菜单是否排他展开
|
||||
SNOWY_SIDE_UNIQUE_OPEN: true,
|
||||
|
||||
// 登录用户水印
|
||||
SNOWY_LOGIN_USER_WATERMARK_OPEN: false,
|
||||
|
||||
// 页脚版权信息
|
||||
SNOWY_FOOTER_COPYRIGHT_OPEN: true,
|
||||
|
||||
// 圆角风格
|
||||
SNOWY_ROUNDED_CORNER_STYLE_OPEN: true,
|
||||
|
||||
// 语言
|
||||
LANG: 'zh-cn',
|
||||
|
||||
// 主题颜色
|
||||
COLOR: '#1890FF',
|
||||
COLOR: '#1677FF',
|
||||
|
||||
// 默认整体主题
|
||||
SNOWY_THEME: 'dark',
|
||||
|
@ -66,15 +75,6 @@ const DEFAULT_CONFIG = {
|
|||
// 整体表单风格
|
||||
SNOWY_FORM_STYLE: 'drawer',
|
||||
|
||||
// 成功色
|
||||
success: '#52c41a',
|
||||
|
||||
// 警告色
|
||||
warning: '#faad14',
|
||||
|
||||
// 错误色
|
||||
error: '#f5222f',
|
||||
|
||||
// 系统基础配置,这些是数据库中保存起来的
|
||||
SYS_BASE_CONFIG: {
|
||||
// 默认logo
|
||||
|
|
|
@ -39,7 +39,7 @@ const colorList = [
|
|||
},
|
||||
{
|
||||
key: '拂晓蓝(默认)',
|
||||
color: '#1890FF'
|
||||
color: '#1677FF'
|
||||
},
|
||||
{
|
||||
key: '极客蓝',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="navMenus.length <= 0" style="padding: 20px">
|
||||
<div v-if="navMenus.length <= 0" class="xn-pd20">
|
||||
<a-alert message="无任何菜单" type="info" :closable="false" />
|
||||
</div>
|
||||
<template v-for="navMenu in navMenus" :key="navMenu">
|
||||
|
@ -26,6 +26,8 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { globalStore } from '@/store'
|
||||
const store = globalStore()
|
||||
const props = defineProps({
|
||||
navMenus: {
|
||||
type: Array,
|
||||
|
@ -44,3 +46,20 @@
|
|||
return false
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.ant-menu-light.ant-menu-horizontal > .ant-menu-submenu-selected {
|
||||
background-color: var(--primary-1);
|
||||
}
|
||||
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu-selected {
|
||||
background-color: var(--primary-5);
|
||||
}
|
||||
.ant-menu-light.ant-menu-horizontal > .ant-menu-item-selected {
|
||||
background-color: none;
|
||||
}
|
||||
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item-selected {
|
||||
background-color: var(--primary-5);
|
||||
}
|
||||
.xn-pd20 {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div class="admin-ui-breadcrumb">
|
||||
<div class="left-panel">
|
||||
<a-breadcrumb>
|
||||
<template v-for="item in breadList" :key="item.title">
|
||||
<a-breadcrumb-item v-if="item.path !== '/' && !item.meta.hiddenBreadcrumb" :key="item.meta.title">{{
|
||||
item.meta.title
|
||||
}}</a-breadcrumb-item>
|
||||
</template>
|
||||
</a-breadcrumb>
|
||||
</div>
|
||||
<div class="center-panel"></div>
|
||||
<div class="right-panel">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const breadList = ref([])
|
||||
|
||||
watch(route, () => {
|
||||
getBreadcrumb()
|
||||
})
|
||||
|
||||
onBeforeMount(() => {
|
||||
getBreadcrumb()
|
||||
})
|
||||
|
||||
const getBreadcrumb = () => {
|
||||
breadList.value = route.meta.breadcrumb
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.admin-ui-breadcrumb {
|
||||
padding-left: 15px;
|
||||
background: var(--breadcrumb-background);
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--header-bottom);
|
||||
}
|
||||
.admin-ui-breadcrumb .left-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.admin-ui-breadcrumb .right-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
|
@ -3,7 +3,7 @@
|
|||
<a-badge :count="unreadMessageNum" class="badge">
|
||||
<comment-outlined />
|
||||
</a-badge>
|
||||
<a-drawer v-model:visible="msgVisible" title="新消息" placement="right" :width="500">
|
||||
<a-drawer v-model:open="msgVisible" title="新消息" placement="right" :width="500">
|
||||
<a-list :data-source="messageList" size="small" class="mb-3" :loading="miniMessageLoading">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item>
|
||||
|
@ -15,12 +15,12 @@
|
|||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
<a-space style="float: right">
|
||||
<a-space class="xn-fdr">
|
||||
<a-button v-if="unreadMessageNum > 0" @click="markRead">全部设为已读</a-button>
|
||||
<a-button type="primary" @click="leaveFor('/usercenter')">消息中心</a-button>
|
||||
</a-space>
|
||||
</a-drawer>
|
||||
<xn-form-container title="详情" :width="700" :visible="visible" :destroy-on-close="true" @close="onClose">
|
||||
<xn-form-container title="详情" :width="700" :open="visible" :destroy-on-close="true" @close="onClose">
|
||||
<a-form ref="formRef" :model="formData" layout="vertical">
|
||||
<a-form-item label="主题:" name="subject">
|
||||
<span>{{ formData.subject }}</span>
|
||||
|
@ -43,8 +43,8 @@
|
|||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'read'">
|
||||
<span v-if="record.read" style="color: #d9d9d9">已读</span>
|
||||
<span v-else style="color: #ff4d4f">未读</span>
|
||||
<span v-if="record.read" class="xn-color-d9d9d9">已读</span>
|
||||
<span v-else class="xn-color-ff4d4f">未读</span>
|
||||
</template>
|
||||
</template>
|
||||
</s-table>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="layout-items-center" v-if="moduleUnfoldOpen">
|
||||
<div class="layout-items-center" v-if="moduleUnfoldOpen && layout !== layoutEnum.TOP">
|
||||
<a-menu
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
mode="horizontal"
|
||||
|
@ -10,14 +10,14 @@
|
|||
<a-menu-item
|
||||
v-for="item in menu"
|
||||
:key="item.id"
|
||||
class="!px-3"
|
||||
style="position: relative"
|
||||
class="xn-pxn-r"
|
||||
@click="moduleClick(item.id)"
|
||||
:class="{ 'ant-menu-item-select': item.id === module }"
|
||||
>
|
||||
<template #icon>
|
||||
<component :is="item.meta.icon" />
|
||||
</template>
|
||||
<span style="margin-left: -5px">{{ item.meta.title }}</span>
|
||||
<span class="xn-ml-5">{{ item.meta.title }}</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
|
@ -27,7 +27,12 @@
|
|||
<a-row :gutter="[0, 5]" class="module-row">
|
||||
<div v-for="item in menu" :key="item.id">
|
||||
<a-col :span="6">
|
||||
<a-tag class="module-card" :color="item.color" @click="moduleClick(item.id)">
|
||||
<a-tag
|
||||
class="module-card"
|
||||
:class="roundedCornerStyleOpen ? 'module-card-radius-round' : 'module-card-radius-default'"
|
||||
:color="item.color"
|
||||
@click="moduleClick(item.id)"
|
||||
>
|
||||
<component :is="item.meta.icon" class="module-card-icon" />
|
||||
<div class="module-card-font">{{ item.meta.title }}</div>
|
||||
</a-tag>
|
||||
|
@ -48,33 +53,69 @@
|
|||
import { globalStore } from '@/store'
|
||||
import { watch } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
import { layoutEnum } from '@/layout/enum/layoutEnum'
|
||||
const store = globalStore()
|
||||
|
||||
const { moduleUnfoldOpen, topHeaderThemeColorOpen } = storeToRefs(store)
|
||||
const moduleBackColor = ref(topHeaderThemeColorOpen)
|
||||
const layout = ref()
|
||||
const module = computed(() => {
|
||||
return store.module
|
||||
})
|
||||
const isMobile = computed(() => {
|
||||
return store.isMobile
|
||||
})
|
||||
const themeColor = computed(() => {
|
||||
return store.themeColor
|
||||
})
|
||||
const theme = computed(() => {
|
||||
return store.theme
|
||||
})
|
||||
// 圆角风格
|
||||
const roundedCornerStyleOpen = computed(() => {
|
||||
return store.roundedCornerStyleOpen
|
||||
})
|
||||
// 监听目录是否折叠
|
||||
watch(moduleUnfoldOpen, (newValue) => {
|
||||
watch(moduleUnfoldOpen, () => {
|
||||
nextTick(() => {
|
||||
setModuleBackColor()
|
||||
})
|
||||
})
|
||||
// 切换应用后
|
||||
watch(module, (newValue) => {
|
||||
selectedKeys.value = [newValue]
|
||||
setSelectedKeys()
|
||||
})
|
||||
// 颜色变化后
|
||||
watch(themeColor, () => {
|
||||
nextTick(() => {
|
||||
setModuleBackColor()
|
||||
})
|
||||
})
|
||||
// 暗黑明亮变化后
|
||||
watch(theme, () => {
|
||||
nextTick(() => {
|
||||
setModuleBackColor()
|
||||
})
|
||||
})
|
||||
// 屏幕缩小后再放大
|
||||
watch(isMobile, (newValue) => {
|
||||
if (!newValue) {
|
||||
nextTick(() => {
|
||||
setModuleBackColor()
|
||||
})
|
||||
}
|
||||
})
|
||||
// 监听是否开启了顶栏颜色
|
||||
watch(topHeaderThemeColorOpen, (newValue) => {
|
||||
moduleBackColor.value = newValue
|
||||
setModuleBackColor()
|
||||
})
|
||||
|
||||
// 监听圆角变化
|
||||
watch(roundedCornerStyleOpen, () => {
|
||||
nextTick(() => {
|
||||
setModuleBackColor()
|
||||
})
|
||||
})
|
||||
const emit = defineEmits({ switchModule: null })
|
||||
const menu = router.getMenu()
|
||||
const selectedKeys = ref([module.value])
|
||||
|
@ -85,9 +126,9 @@
|
|||
setSelectedKeys()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setModuleBackColor()
|
||||
layout.value = tool.data.get('SNOWY_LAYOUT')
|
||||
})
|
||||
// 设置背景色
|
||||
const setModuleBackColor = () => {
|
||||
|
@ -112,26 +153,33 @@
|
|||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.xn-pxn-r {
|
||||
position: relative;
|
||||
}
|
||||
.module-row {
|
||||
max-width: 357px;
|
||||
}
|
||||
.module-card {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
background-color: #0d84ff;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.module-card-radius-default {
|
||||
border-radius: 2px;
|
||||
}
|
||||
.module-card-radius-round {
|
||||
border-radius: 6px;
|
||||
}
|
||||
.module-card-icon {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.module-card-font {
|
||||
color: white;
|
||||
font-size: 8px;
|
||||
}
|
||||
.ant-menu-horizontal > .ant-menu-item::after,
|
||||
.ant-menu-horizontal > .ant-menu-submenu::after {
|
||||
|
@ -139,7 +187,7 @@
|
|||
}
|
||||
.module-menu {
|
||||
line-height: 50px;
|
||||
border-bottom: 0px;
|
||||
border-bottom: 0;
|
||||
width: 105%;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
@ -153,4 +201,15 @@
|
|||
.module-card-scope {
|
||||
height: 49px;
|
||||
}
|
||||
.ant-menu-item-select {
|
||||
color: #ccc;
|
||||
background-color: var(--primary-7);
|
||||
}
|
||||
.xn-ml-5 {
|
||||
margin-left: -5px;
|
||||
}
|
||||
.ant-menu-horizontal > .ant-menu-item::after,
|
||||
.ant-menu-horizontal > .ant-menu-submenu::after {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
<a-input
|
||||
ref="inputRef"
|
||||
v-model="searchText"
|
||||
class="search-box"
|
||||
style="width: 100%"
|
||||
class="search-box xn-wd"
|
||||
allowClear
|
||||
placeholder="搜索页面(支持拼音检索)"
|
||||
@change="querySearch"
|
||||
|
@ -39,7 +38,8 @@
|
|||
@mouseleave="onCardOut"
|
||||
@keypress.up="handleKeyUp"
|
||||
@keypress.down="handleKeyDown"
|
||||
style="margin: 10px 0"
|
||||
class="xn-mn10p0"
|
||||
|
||||
>
|
||||
<div ref="cardListRef" class="search-card beauty-scroll">
|
||||
<a-list size="small" :data-source="resultsList">
|
||||
|
@ -47,8 +47,7 @@
|
|||
<a-list-item
|
||||
@click="handleSelect(item.fullPath)"
|
||||
@mouseover="onCardItemHover(index)"
|
||||
:class="{ active: index === cardIndex }"
|
||||
style="padding-right: 10px"
|
||||
:class="{ active: index === cardIndex },'xn-pr10'"
|
||||
>
|
||||
<template #actions>
|
||||
<a>
|
||||
|
@ -279,6 +278,12 @@
|
|||
:deep(.ant-list-item.active) {
|
||||
background-color: var(--primary-1);
|
||||
}
|
||||
.xn-mn10p0 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.xn-pr10 {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.search-box {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -321,7 +326,10 @@
|
|||
padding-bottom: 2px;
|
||||
margin: 0px 4px;
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 -2px #cdcde6, inset 0 0 1px 1px #fff, 0 1px 2px 1px #1e235a66;
|
||||
box-shadow:
|
||||
inset 0 -2px #cdcde6,
|
||||
inset 0 0 1px 1px #fff,
|
||||
0 1px 2px 1px #1e235a66;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="setting-drawer-index-content">
|
||||
<div class="scrollbar">
|
||||
<h3>整体风格设置</h3>
|
||||
<h3 class="setting-item-title">整体风格设置</h3>
|
||||
<div class="snowy-setting-checkbox">
|
||||
<a-tooltip v-for="(a, i) in sideStyleList" :key="i" placement="top">
|
||||
<template #title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<h3>整体界面布局</h3>
|
||||
<h3 class="setting-item-title">整体界面布局</h3>
|
||||
<div class="snowy-setting-checkbox">
|
||||
<a-tooltip v-for="(a, i) in layoutList" :key="i" placement="top">
|
||||
<template #title>
|
||||
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
<a-divider />
|
||||
<div class="mb-4">
|
||||
<h3>主题色</h3>
|
||||
<h3 class="setting-item-title">主题色</h3>
|
||||
<div class="h-[50px]">
|
||||
<a-tooltip v-for="(item, index) in colorList" :key="index" class="snowy-setting-theme-color-colorBlock">
|
||||
<template #title>
|
||||
|
@ -39,23 +39,35 @@
|
|||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 layout-slide">
|
||||
<h4 class="">顶栏应用主题色:</h4>
|
||||
<a-switch :checked="topHeaderThemeColorOpen" @change="changeTopHanderThemeColorOpen" />
|
||||
</div>
|
||||
<div class="mb-4 layout-slide">
|
||||
<h4>顶栏主题色通栏:</h4>
|
||||
<div class="mb-4 layout-slide" v-if="!topHeaderThemeColorOpenDisabled" style="padding-top: 10px">
|
||||
<h4 class="setting-item-title">顶栏应用主题色:</h4>
|
||||
<a-switch
|
||||
style="float: right"
|
||||
:checked="topHeaderThemeColorSpread"
|
||||
:disabled="!topHeaderThemeColorOpen"
|
||||
@change="changeTopHanderThemeColorSpread"
|
||||
:checked="topHeaderThemeColorOpen"
|
||||
@change="changeTopHeaderThemeColorOpen"
|
||||
:disabled="topHeaderThemeColorOpenDisabled"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-4 layout-slide" v-if="!topHeaderThemeColorSpreadDisabled">
|
||||
<h4 class="setting-item-title">顶栏主题色通栏:</h4>
|
||||
<a-switch
|
||||
class="xn-fdr"
|
||||
:checked="topHeaderThemeColorSpread"
|
||||
:disabled="!topHeaderThemeColorOpen || topHeaderThemeColorSpreadDisabled"
|
||||
@change="changeTopHeaderThemeColorSpread"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<a-divider />
|
||||
<a-form ref="formRef" class="text-right">
|
||||
<a-form-item label="模块坞">
|
||||
<a-switch :checked="moduleUnfoldOpen" @change="toggleState('moduleUnfoldOpen')" />
|
||||
<a-form-item label="模块坞" v-if="!moduleUnfoldDisabled">
|
||||
<a-switch
|
||||
:checked="moduleUnfoldOpen"
|
||||
@change="toggleState('moduleUnfoldOpen')"
|
||||
:disabled="moduleUnfoldDisabled"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="固定宽度" v-if="layout == layoutEnum.TOP">
|
||||
<a-switch :checked="fixedWidth" @change="toggleState('fixedWidth')" />
|
||||
</a-form-item>
|
||||
<a-form-item label="面包屑">
|
||||
<a-switch :checked="breadcrumbOpen" @change="toggleState('breadcrumbOpen')" />
|
||||
|
@ -63,11 +75,28 @@
|
|||
<a-form-item label="多标签">
|
||||
<a-switch :checked="layoutTagsOpen" @change="toggleState('layoutTagsOpen')" />
|
||||
</a-form-item>
|
||||
<a-form-item label="折叠菜单">
|
||||
<a-switch :checked="menuIsCollapse" @change="toggleState('menuIsCollapse')" />
|
||||
<a-form-item label="折叠菜单" v-if="!menuIsCollapseDisabled">
|
||||
<a-switch
|
||||
:checked="menuIsCollapse"
|
||||
@change="toggleState('menuIsCollapse')"
|
||||
:disabled="menuIsCollapseDisabled"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="菜单排他展开">
|
||||
<a-switch :checked="sideUniqueOpen" @change="toggleState('sideUniqueOpen')" />
|
||||
<a-form-item label="菜单排他展开" v-if="!sideUniqueOpenDisabled">
|
||||
<a-switch
|
||||
:checked="sideUniqueOpen"
|
||||
@change="toggleState('sideUniqueOpen')"
|
||||
:disabled="sideUniqueOpenDisabled"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="登录用户水印">
|
||||
<a-switch :checked="loginUserWatermarkOpen" @change="toggleState('loginUserWatermarkOpen')" />
|
||||
</a-form-item>
|
||||
<a-form-item label="页脚版权信息">
|
||||
<a-switch :checked="footerCopyrightOpen" @change="toggleState('footerCopyrightOpen')" />
|
||||
</a-form-item>
|
||||
<a-form-item label="圆角风格">
|
||||
<a-switch :checked="roundedCornerStyleOpen" @change="toggleState('roundedCornerStyleOpen')" />
|
||||
</a-form-item>
|
||||
<a-form-item label="表单风格">
|
||||
<a-select
|
||||
|
@ -88,50 +117,63 @@
|
|||
</template>
|
||||
<script setup>
|
||||
import { colorList } from '@/config/settingConfig'
|
||||
import { ThemeModeEnum } from '@/utils/enum'
|
||||
import { themeEnum } from '@/layout/enum/themeEnum'
|
||||
import { layoutEnum } from '@/layout/enum/layoutEnum'
|
||||
import { globalStore } from '@/store'
|
||||
import tool from '@/utils/tool'
|
||||
const store = globalStore()
|
||||
const topHeaderThemeColorOpenDisabled = ref(false)
|
||||
const topHeaderThemeColorSpreadDisabled = ref(false)
|
||||
const moduleUnfoldDisabled = ref(false)
|
||||
const menuIsCollapseDisabled = ref(false)
|
||||
const sideUniqueOpenDisabled = ref(false)
|
||||
const toolDataNameMap = {
|
||||
menuIsCollapse: 'MENU_COLLAPSE',
|
||||
sideUniqueOpen: 'SIDE_UNIQUE_OPEN',
|
||||
layoutTagsOpen: 'LAYOUT_TAGS_OPEN',
|
||||
breadcrumbOpen: 'BREADCRUMD_OPEN',
|
||||
fixedWidth: 'FIXEDWIDTH_OPEN',
|
||||
topHeaderThemeColorOpen: 'TOP_HEADER_THEME_COLOR_OPEN',
|
||||
topHeaderThemeColorSpread: 'TOP_HEADER_THEME_COLOR_SPREAD',
|
||||
loginUserWatermarkOpen: 'LOGIN_USER_WATERMARK_OPEN',
|
||||
footerCopyrightOpen: 'FOOTER_COPYRIGHT_OPEN',
|
||||
roundedCornerStyleOpen: 'ROUNDED_CORNER_STYLE_OPEN',
|
||||
moduleUnfoldOpen: 'MODULE_UNFOLD_OPEN'
|
||||
}
|
||||
const sideStyleList = ref([
|
||||
{
|
||||
tips: '暗色主题风格',
|
||||
value: ThemeModeEnum.DARK,
|
||||
value: themeEnum.DARK,
|
||||
style: 'snowy-setting-checkbox-item-dark'
|
||||
},
|
||||
{
|
||||
tips: '亮色主题风格',
|
||||
value: ThemeModeEnum.LIGHT,
|
||||
value: themeEnum.LIGHT,
|
||||
style: 'snowy-setting-checkbox-item-light'
|
||||
},
|
||||
{
|
||||
tips: '暗黑模式',
|
||||
value: ThemeModeEnum.REAL_DARK,
|
||||
value: themeEnum.REAL_DARK,
|
||||
style: 'snowy-setting-checkbox-item-realdark'
|
||||
}
|
||||
])
|
||||
|
||||
const layoutList = ref([
|
||||
{
|
||||
tips: '经典',
|
||||
value: 'classical',
|
||||
value: layoutEnum.CLASSICAL,
|
||||
style: 'snowy-setting-layout-menu-classical'
|
||||
},
|
||||
{
|
||||
tips: '双排菜单',
|
||||
value: 'doublerow',
|
||||
value: layoutEnum.DOUBLEROW,
|
||||
style: 'snowy-setting-layout-menu-doublerow'
|
||||
},
|
||||
{
|
||||
tips: '顶部菜单',
|
||||
value: layoutEnum.TOP,
|
||||
style: 'snowy-setting-layout-menu-top'
|
||||
}
|
||||
])
|
||||
|
||||
const xnFormStyleOptions = ref([
|
||||
{
|
||||
label: '抽屉',
|
||||
|
@ -142,7 +184,6 @@
|
|||
value: 'modal'
|
||||
}
|
||||
])
|
||||
|
||||
const theme = computed(() => {
|
||||
return store.theme
|
||||
})
|
||||
|
@ -158,12 +199,24 @@
|
|||
const sideUniqueOpen = computed(() => {
|
||||
return store.sideUniqueOpen
|
||||
})
|
||||
const loginUserWatermarkOpen = computed(() => {
|
||||
return store.loginUserWatermarkOpen
|
||||
})
|
||||
const footerCopyrightOpen = computed(() => {
|
||||
return store.footerCopyrightOpen
|
||||
})
|
||||
const roundedCornerStyleOpen = computed(() => {
|
||||
return store.roundedCornerStyleOpen
|
||||
})
|
||||
const layoutTagsOpen = computed(() => {
|
||||
return store.layoutTagsOpen
|
||||
})
|
||||
const breadcrumbOpen = computed(() => {
|
||||
return store.breadcrumbOpen
|
||||
})
|
||||
const fixedWidth = computed(() => {
|
||||
return store.fixedWidth
|
||||
})
|
||||
const moduleUnfoldOpen = computed(() => {
|
||||
return store.moduleUnfoldOpen
|
||||
})
|
||||
|
@ -176,16 +229,14 @@
|
|||
const formStyle = computed(() => {
|
||||
return store.formStyle
|
||||
})
|
||||
|
||||
const changeTopHanderThemeColorOpen = () => {
|
||||
const changeTopHeaderThemeColorOpen = () => {
|
||||
toggleState('topHeaderThemeColorOpen')
|
||||
if (!topHeaderThemeColorOpen) {
|
||||
if (!topHeaderThemeColorOpen.value) {
|
||||
store.topHeaderThemeColorSpread = false
|
||||
tool.data.set('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD', false)
|
||||
}
|
||||
}
|
||||
|
||||
const changeTopHanderThemeColorSpread = () => {
|
||||
const changeTopHeaderThemeColorSpread = () => {
|
||||
toggleState('topHeaderThemeColorSpread')
|
||||
}
|
||||
const toggleState = (stateName) => {
|
||||
|
@ -197,11 +248,13 @@
|
|||
const setSideStyle = (value) => {
|
||||
store.setTheme(value)
|
||||
tool.data.set('SNOWY_THEME', value)
|
||||
layoutChange(layout.value)
|
||||
}
|
||||
// 设置整体界面布局
|
||||
const layoutStyle = (value) => {
|
||||
store.setLayout(value)
|
||||
tool.data.set('SNOWY_LAYOUT', value)
|
||||
layoutChange(value)
|
||||
}
|
||||
// 切换颜色
|
||||
const tagColor = (value) => {
|
||||
|
@ -213,6 +266,48 @@
|
|||
tool.data.set('SNOWY_FORM_STYLE', value)
|
||||
store.setFormStyle(value)
|
||||
}
|
||||
// 更改布局后设置
|
||||
const layoutChange = (layout) => {
|
||||
// 暗黑色情况下,将其禁用顶栏颜色跟通栏功能
|
||||
if (theme.value === themeEnum.REAL_DARK) {
|
||||
topHeaderThemeColorOpenDisabled.value = true
|
||||
topHeaderThemeColorSpreadDisabled.value = true
|
||||
// 在切换主题风格的时候判断顶栏相关的,暗黑模式下是不允许开启顶栏变色的
|
||||
if (topHeaderThemeColorOpen.value) {
|
||||
toggleState('topHeaderThemeColorOpen')
|
||||
tool.data.set('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD', false)
|
||||
}
|
||||
} else {
|
||||
if (layout !== layoutEnum.TOP) {
|
||||
topHeaderThemeColorSpreadDisabled.value = false
|
||||
topHeaderThemeColorOpenDisabled.value = false
|
||||
} else {
|
||||
topHeaderThemeColorOpenDisabled.value = false
|
||||
}
|
||||
}
|
||||
// 如果是顶栏布局,限制一些配置
|
||||
if (layout === layoutEnum.TOP) {
|
||||
// 将其模块坞功能禁用
|
||||
moduleUnfoldDisabled.value = true
|
||||
// 禁用折叠菜单
|
||||
menuIsCollapseDisabled.value = true
|
||||
// 菜单排他展开
|
||||
if (sideUniqueOpen.value) {
|
||||
toggleState('sideUniqueOpen')
|
||||
}
|
||||
sideUniqueOpenDisabled.value = true
|
||||
topHeaderThemeColorSpreadDisabled.value = true
|
||||
} else {
|
||||
moduleUnfoldDisabled.value = false
|
||||
menuIsCollapseDisabled.value = false
|
||||
sideUniqueOpenDisabled.value = false
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
const layout = tool.data.get('SNOWY_LAYOUT')
|
||||
// 这里主要为了dom销毁后重新打开设置界面,界面上禁用相关
|
||||
layoutChange(layout)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -294,12 +389,11 @@
|
|||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
color: #1890ff;
|
||||
color: #1677FF;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.snowy-setting-theme-color-colorBlock {
|
||||
margin-top: 8px;
|
||||
width: 20px;
|
||||
|
@ -314,7 +408,6 @@
|
|||
color: #fff;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.snowy-setting-layout-menu-doublerow {
|
||||
z-index: 1;
|
||||
background-color: #ebeef1;
|
||||
|
@ -364,8 +457,33 @@
|
|||
background-color: #fff;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.snowy-setting-layout-menu-top {
|
||||
z-index: 1;
|
||||
background-color: #ebeef1;
|
||||
content: '';
|
||||
}
|
||||
.snowy-setting-layout-menu-top::before {
|
||||
z-index: 1;
|
||||
background-color: #ebeef1;
|
||||
content: '';
|
||||
}
|
||||
.snowy-setting-layout-menu-top::after {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
background-color: #001529;
|
||||
content: '';
|
||||
}
|
||||
.scrollbar {
|
||||
margin: 0 auto;
|
||||
}
|
||||
.setting-item-title {
|
||||
color: var(--font-color);
|
||||
}
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 12px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div v-drag class="mobile-nav-button" draggable="false" @click="showMobileNav($event)">
|
||||
<appstore-outlined style="font-size: 20px; color: white" />
|
||||
<appstore-outlined class="xn-appout-line" />
|
||||
</div>
|
||||
<a-drawer v-model:visible="visible" :width="210" :closable="false" placement="left">
|
||||
<a-drawer v-model:open="visible" :width="210" :closable="false" placement="left">
|
||||
<header class="snowy-header-logo mobile-nav">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
|
@ -11,7 +11,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<a-menu style="width: 208px; margin-left: -24px" mode="inline" @select="onSelect">
|
||||
<a-menu class="xn-inline-line" mode="inline" @select="onSelect">
|
||||
<NavMenu :nav-menus="menu"></NavMenu>
|
||||
</a-menu>
|
||||
</a-drawer>
|
||||
|
@ -113,6 +113,14 @@
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.xn-appout-line {
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
}
|
||||
.xn-inline-line {
|
||||
width: 208px;
|
||||
margin-left: -24px;
|
||||
}
|
||||
.mobile-nav {
|
||||
margin-top: -24px;
|
||||
margin-left: -24px;
|
||||
|
|
|
@ -9,32 +9,33 @@
|
|||
>
|
||||
<div class="right-menu-item" @click="refreshTab">
|
||||
<reload-outlined class="snowy-header-tags-right" />
|
||||
<div class="pl-3">刷新</div>
|
||||
<div class="pl-3 snowy-header-tags-right-font">刷新</div>
|
||||
</div>
|
||||
|
||||
<div class="right-menu-item" @click="closeTabs">
|
||||
<close-outlined class="snowy-header-tags-right" />
|
||||
<div class="pl-3">关闭</div>
|
||||
<div class="pl-3 snowy-header-tags-right-font">关闭</div>
|
||||
</div>
|
||||
|
||||
<div class="right-menu-item" @click="closeOtherTabs">
|
||||
<close-outlined class="snowy-header-tags-right" />
|
||||
<div class="pl-3">关闭其他标签</div>
|
||||
<div class="pl-3 snowy-header-tags-right-font">关闭其他标签</div>
|
||||
</div>
|
||||
|
||||
<div class="right-menu-item" @click="maximize">
|
||||
<expand-outlined class="snowy-header-tags-right" />
|
||||
<div class="pl-3">最大化</div>
|
||||
<div class="pl-3 snowy-header-tags-right-font">最大化</div>
|
||||
</div>
|
||||
<div class="right-menu-item" @click="openWindow">
|
||||
<select-outlined class="snowy-header-tags-right" />
|
||||
<div class="pl-3">新窗口打开</div>
|
||||
<div class="pl-3 snowy-header-tags-right-font">新窗口打开</div>
|
||||
</div>
|
||||
</xn-context-menu>
|
||||
<a-tabs
|
||||
v-model:activeKey="activeKey"
|
||||
type="editable-card"
|
||||
class="snowy-admin-tabs"
|
||||
:class="[{ 'snowy-radius': roundedCornerStyleOpen }, 'snowy-admin-tabs']"
|
||||
:animated="!roundedCornerStyleOpen"
|
||||
hide-add
|
||||
ref="tabs"
|
||||
@edit="onTabRemove"
|
||||
|
@ -85,11 +86,13 @@
|
|||
const layoutTagsOpen = computed(() => {
|
||||
return store.layoutTagsOpen
|
||||
})
|
||||
const roundedCornerStyleOpen = computed(() => {
|
||||
return store.roundedCornerStyleOpen
|
||||
})
|
||||
|
||||
const tagList = computed(() => {
|
||||
return viewTags.value
|
||||
})
|
||||
|
||||
watch(route, (to) => {
|
||||
addViewTags(to)
|
||||
activeKey.value = to.fullPath
|
||||
|
@ -97,7 +100,6 @@
|
|||
watch(layoutTagsOpen, () => {
|
||||
// closeOtherCacheTabs()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const tabNavList = document.querySelector('.ant-tabs-nav-list')
|
||||
if (tabNavList) {
|
||||
|
@ -299,9 +301,8 @@
|
|||
</script>
|
||||
<style lang="less">
|
||||
.snowy-admin-tabs {
|
||||
overflow: hidden; // 新增
|
||||
&.ant-tabs {
|
||||
background: var(--component-background);
|
||||
box-shadow: var(--header-light-shadow);
|
||||
z-index: 99;
|
||||
.ant-tabs-nav {
|
||||
margin-bottom: 0;
|
||||
|
@ -336,7 +337,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.snowy-admin-tabs-drop,
|
||||
.snowy-admin-tabs-arrow,
|
||||
.ant-tabs-nav-operations .ant-tabs-nav-more {
|
||||
|
@ -355,7 +355,7 @@
|
|||
}
|
||||
.right-menu {
|
||||
position: fixed;
|
||||
background: #fff;
|
||||
background: var(--tag-background);
|
||||
z-index: 999;
|
||||
border: 1px solid #eee;
|
||||
box-shadow: 0 0.5em 1em 0 rgb(0 0 0 / 10%);
|
||||
|
@ -374,4 +374,101 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.snowy-tags {
|
||||
height: 40px;
|
||||
background: var(--snowy-background-color);
|
||||
}
|
||||
.snowy-tags ul {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
padding-left: 0;
|
||||
}
|
||||
.snowy-tags li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
line-height: 39.5px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.snowy-tags li::after {
|
||||
content: ' ';
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
background-image: linear-gradient(#fff, #e6e6e6);
|
||||
}
|
||||
.snowy-tags li a {
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.snowy-tags li i {
|
||||
margin-left: 10px;
|
||||
border-radius: 3px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.snowy-tags li i:hover {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: @body-background;
|
||||
}
|
||||
.snowy-tags li:hover {
|
||||
background: @body-background;
|
||||
}
|
||||
.snowy-tags li.active {
|
||||
background: @primary-color;
|
||||
}
|
||||
.snowy-tags li.active a {
|
||||
color: var(--font-color);
|
||||
}
|
||||
.snowy-tags li.sortable-ghost {
|
||||
opacity: 0;
|
||||
}
|
||||
.snowy-header-tags-right {
|
||||
margin-right: 10px;
|
||||
color: var(--font-color);
|
||||
}
|
||||
.snowy-header-tags-right-font {
|
||||
color: var(--font-color);
|
||||
}
|
||||
.snowy-radius .ant-tabs-tab-active {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border-radius: 10px 10px 0 0 !important;
|
||||
box-shadow:
|
||||
12px 15px 0 0 var(--primary-1),
|
||||
-12px 15px 0 0 var(--primary-1);
|
||||
}
|
||||
.snowy-radius .ant-tabs-tab-active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -13px;
|
||||
bottom: 1px;
|
||||
width: 13px;
|
||||
height: 40px;
|
||||
background: var(--primary-radius);
|
||||
border-radius: 0 0 20px 0;
|
||||
}
|
||||
.snowy-radius .ant-tabs-tab-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -13px;
|
||||
bottom: 1px;
|
||||
width: 13px;
|
||||
height: 40px;
|
||||
background: var(--primary-radius);
|
||||
border-radius: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.snowy-radius .ant-tabs-ink-bar {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,22 +8,22 @@
|
|||
<!-- <dev-user-message />-->
|
||||
<a-dropdown class="user panel-item">
|
||||
<div class="user-avatar">
|
||||
<a-avatar :src="userInfo.avatar" />
|
||||
<a-avatar :src="userInfo ? userInfo.avatar : undefined" />
|
||||
<label>{{ userName }}</label>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="uc" @click="handleUser('uc')">
|
||||
<UserOutlined style="margin-right: 8px" />
|
||||
<UserOutlined class="xn-mr8" />
|
||||
<span>个人中心</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="clearCache" @click="handleUser('clearCache')">
|
||||
<loading3-quarters-outlined style="margin-right: 8px" />
|
||||
<loading3-quarters-outlined class="xn-mr8" />
|
||||
<span>清理缓存</span>
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="outLogin" @click="handleUser('outLogin')">
|
||||
<export-outlined style="margin-right: 8px" />
|
||||
<export-outlined class="xn-mr8" />
|
||||
<span>退出登录</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
|
||||
<!-- 整体风格设置抽屉 -->
|
||||
<a-drawer v-model:visible="settingDialog" :closable="false" width="300">
|
||||
<a-drawer v-model:open="settingDialog" :closable="false" width="300">
|
||||
<setting />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
@ -128,6 +128,10 @@
|
|||
tool.data.remove('MENU')
|
||||
tool.data.remove('PERMISSIONS')
|
||||
router.replace({ path: '/login' })
|
||||
nextTick(() => {
|
||||
// 清理缓存内的个人信息
|
||||
store.userInfo = undefined
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
tool.data.clear()
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
export const layoutEnum = {
|
||||
CLASSICAL: 'classical',
|
||||
DOUBLEROW: 'doublerow',
|
||||
TOP: 'top'
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
export const themeEnum = {
|
||||
LIGHT: 'light',
|
||||
DARK: 'dark',
|
||||
REAL_DARK: 'realDark'
|
||||
}
|
|
@ -1,191 +1,86 @@
|
|||
<template>
|
||||
<!-- 经典布局 -->
|
||||
<a-layout v-if="layout === 'classical'">
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
v-model:collapsed="menuIsCollapse"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:theme="sideTheme"
|
||||
width="210"
|
||||
>
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div :class="menuIsCollapse ? 'admin-ui-side isCollapse' : 'admin-ui-side'">
|
||||
<div class="admin-ui-side-scroll">
|
||||
<a-menu
|
||||
v-model:openKeys="openKeys"
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
:theme="sideTheme"
|
||||
mode="inline"
|
||||
@select="onSelect"
|
||||
@openChange="onOpenChange"
|
||||
>
|
||||
<NavMenu :nav-menus="menu" />
|
||||
</a-menu>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" />
|
||||
<!-- 右侧布局 -->
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header">
|
||||
<div class="snowy-header-left" style="padding-left: 0px">
|
||||
<div v-if="!isMobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
|
||||
<MenuUnfoldOutlined v-if="menuIsCollapse" />
|
||||
<MenuFoldOutlined v-else />
|
||||
</div>
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" />
|
||||
<top-bar v-if="!isMobile && breadcrumbOpen" />
|
||||
</div>
|
||||
<div class="snowy-header-right">
|
||||
<user-bar />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||
<a-layout-content class="main-content-wrapper">
|
||||
<div id="admin-ui-main" class="admin-ui-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="kStore.keepLiveRoute">
|
||||
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<iframe-view />
|
||||
<div class="main-bottom-wrapper">
|
||||
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
|
||||
sysBaseConfig.SNOWY_SYS_COPYRIGHT
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
<ClassicalMenu
|
||||
v-if="layout === layoutEnum.CLASSICAL"
|
||||
:layout="layout"
|
||||
:isMobile="isMobile"
|
||||
:menuIsCollapse="menuIsCollapse"
|
||||
:sideTheme="sideTheme"
|
||||
:sysBaseConfig="sysBaseConfig"
|
||||
:openKeys="openKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
:menu="menu"
|
||||
:breadcrumbOpen="breadcrumbOpen"
|
||||
:layoutTagsOpen="layoutTagsOpen"
|
||||
:kStore="kStore"
|
||||
:footerCopyrightOpen="footerCopyrightOpen"
|
||||
:moduleMenuShow="moduleMenuShow"
|
||||
@onSelect="onSelect"
|
||||
@onOpenChange="onOpenChange"
|
||||
@switchModule="switchModule"
|
||||
@menuIsCollapseClick="menuIsCollapseClick"
|
||||
/>
|
||||
<!-- 双排菜单布局 -->
|
||||
<a-layout v-else-if="layout === 'doublerow'">
|
||||
<a-layout-sider v-if="!isMobile" width="80" :theme="sideTheme" :trigger="null" collapsible>
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<router-link to="/">
|
||||
<img class="logo" :title="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<a-menu
|
||||
v-model:selectedKeys="doublerowSelectedKey"
|
||||
:theme="sideTheme"
|
||||
class="snowy-doublerow-layout-menu"
|
||||
v-for="item in menu"
|
||||
:key="item.path"
|
||||
>
|
||||
<a-menu-item
|
||||
:key="item.path"
|
||||
style="
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
"
|
||||
@click="showMenu(item)"
|
||||
v-if="!item.meta.hidden"
|
||||
>
|
||||
<a v-if="item.meta && item.meta.type === 'link'" :href="item.path" target="_blank" @click.stop="() => {}" />
|
||||
<template #icon>
|
||||
<component :is="item.meta.icon" style="padding-left: 10px" />
|
||||
</template>
|
||||
<div class="snowy-doublerow-layout-menu-item-fort-div">
|
||||
<span class="snowy-doublerow-layout-menu-item-fort-div-span">
|
||||
{{ item.meta.title }}
|
||||
</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
v-show="layoutSiderDowbleMenu"
|
||||
v-model:collapsed="menuIsCollapse"
|
||||
:trigger="null"
|
||||
width="170"
|
||||
collapsible
|
||||
:theme="secondMenuSideTheme"
|
||||
>
|
||||
<div v-if="!menuIsCollapse" id="snowyDoublerowSideTop" class="snowy-doublerow-side-top">
|
||||
<h2 class="snowy-title">{{ pMenu.meta.title }}</h2>
|
||||
</div>
|
||||
<a-menu
|
||||
v-model:collapsed="menuIsCollapse"
|
||||
v-model:openKeys="openKeys"
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
mode="inline"
|
||||
:theme="secondMenuSideTheme"
|
||||
@select="onSelect"
|
||||
>
|
||||
<NavMenu :nav-menus="nextMenu" />
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" />
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header">
|
||||
<div class="snowy-header-left" style="padding-left: 0px">
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" />
|
||||
<top-bar v-if="!isMobile && breadcrumbOpen" />
|
||||
</div>
|
||||
<div class="snowy-header-right">
|
||||
<user-bar />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||
<a-layout-content class="main-content-wrapper">
|
||||
<div id="admin-ui-main" class="admin-ui-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="kStore.keepLiveRoute">
|
||||
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<iframe-view />
|
||||
<div class="main-bottom-wrapper">
|
||||
<a style="color: #a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
|
||||
sysBaseConfig.SNOWY_SYS_COPYRIGHT
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
<DoubleRowMenu
|
||||
v-else-if="layout === layoutEnum.DOUBLEROW"
|
||||
:layout="layout"
|
||||
:isMobile="isMobile"
|
||||
:sideTheme="sideTheme"
|
||||
:secondMenuSideTheme="secondMenuSideTheme"
|
||||
:sysBaseConfig="sysBaseConfig"
|
||||
:openKeys="openKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
:menuIsCollapse="menuIsCollapse"
|
||||
:doublerowSelectedKey="doublerowSelectedKey"
|
||||
:menu="menu"
|
||||
:nextMenu="nextMenu"
|
||||
:breadcrumbOpen="breadcrumbOpen"
|
||||
:layoutTagsOpen="layoutTagsOpen"
|
||||
:layoutSiderDowbleMenu="layoutSiderDowbleMenu"
|
||||
:kStore="kStore"
|
||||
:footerCopyrightOpen="footerCopyrightOpen"
|
||||
:moduleMenuShow="moduleMenuShow"
|
||||
@onSelect="onSelect"
|
||||
@switchModule="switchModule"
|
||||
@showMenu="showMenu"
|
||||
/>
|
||||
<!-- 顶部菜单布局 -->
|
||||
<TopMenu
|
||||
v-else-if="layout === layoutEnum.TOP"
|
||||
:layout="layout"
|
||||
:menuList="menuList"
|
||||
:menu="menu"
|
||||
:sysBaseConfig="sysBaseConfig"
|
||||
:moduleMenuShow="moduleMenuShow"
|
||||
:openKeys="openKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
:breadcrumbOpen="breadcrumbOpen"
|
||||
:footerCopyrightOpen="footerCopyrightOpen"
|
||||
:sideTheme="sideTheme"
|
||||
:isMobile="isMobile"
|
||||
:kStore="kStore"
|
||||
:layoutTagsOpen="layoutTagsOpen"
|
||||
@switchModule="switchModule"
|
||||
@onOpenChange="onOpenChange"
|
||||
@onSelect="onSelect"
|
||||
/>
|
||||
|
||||
<!-- 退出最大化 -->
|
||||
<div class="main-maximize-exit" @click="exitMaximize">
|
||||
<fullscreen-exit-outlined style="color: #fff" />
|
||||
<fullscreen-exit-outlined class="xn-color-fff" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import UserBar from '@/layout/components/userbar.vue'
|
||||
import Tags from '@/layout/components/tags.vue'
|
||||
import SideM from '@/layout/components/sideM.vue'
|
||||
import NavMenu from '@/layout/components/NavMenu.vue'
|
||||
import ModuleMenu from '@/layout/components/moduleMenu.vue'
|
||||
import IframeView from '@/layout/components/iframeView.vue'
|
||||
import TopBar from '@/layout/components/topbar.vue'
|
||||
import { globalStore, keepAliveStore } from '@/store'
|
||||
import { ThemeModeEnum } from '@/utils/enum'
|
||||
import { themeEnum } from '@/layout/enum/themeEnum'
|
||||
import { layoutEnum } from '@/layout/enum/layoutEnum'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import tool from '@/utils/tool'
|
||||
import { message } from 'ant-design-vue'
|
||||
import ClassicalMenu from '@/layout/menu/classicalMenu.vue'
|
||||
import DoubleRowMenu from '@/layout/menu/doubleRowMenu.vue'
|
||||
import TopMenu from '@/layout/menu/topMenu.vue'
|
||||
|
||||
const store = globalStore()
|
||||
const kStore = keepAliveStore()
|
||||
|
@ -197,10 +92,11 @@
|
|||
const selectedKeys = ref([])
|
||||
const openKeys = ref([])
|
||||
const onSelectTag = ref(false)
|
||||
const moduleMenuData = ref([])
|
||||
const moduleMenu = ref([])
|
||||
const moduleMenuShow = ref(true)
|
||||
const doublerowSelectedKey = ref([])
|
||||
const layoutSiderDowbleMenu = ref(true)
|
||||
const menuList = ref([])
|
||||
// computed计算方法 - start
|
||||
const layout = computed(() => {
|
||||
return store.layout
|
||||
|
@ -214,6 +110,9 @@
|
|||
const theme = computed(() => {
|
||||
return store.theme
|
||||
})
|
||||
const themeColor = computed(() => {
|
||||
return store.themeColor
|
||||
})
|
||||
const layoutTagsOpen = computed(() => {
|
||||
// 当关闭多标签时,清理keepAlive的缓存
|
||||
if (!store.layoutTagsOpen) {
|
||||
|
@ -224,6 +123,9 @@
|
|||
const breadcrumbOpen = computed(() => {
|
||||
return store.breadcrumbOpen
|
||||
})
|
||||
const fixedWidth = computed(() => {
|
||||
return store.fixedWidth
|
||||
})
|
||||
const topHeaderThemeColorOpen = computed(() => {
|
||||
return store.topHeaderThemeColorOpen
|
||||
})
|
||||
|
@ -233,6 +135,9 @@
|
|||
const sideUniqueOpen = computed(() => {
|
||||
return store.sideUniqueOpen
|
||||
})
|
||||
const footerCopyrightOpen = computed(() => {
|
||||
return store.footerCopyrightOpen
|
||||
})
|
||||
const sysBaseConfig = computed(() => {
|
||||
return store.sysBaseConfig
|
||||
})
|
||||
|
@ -240,10 +145,13 @@
|
|||
return store.module
|
||||
})
|
||||
const sideTheme = computed(() => {
|
||||
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme.value
|
||||
return theme.value === themeEnum.REAL_DARK ? themeEnum.DARK : theme.value
|
||||
})
|
||||
const secondMenuSideTheme = computed(() => {
|
||||
return theme.value === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : ThemeModeEnum.LIGHT
|
||||
return theme.value === themeEnum.REAL_DARK ? themeEnum.DARK : themeEnum.LIGHT
|
||||
})
|
||||
const roundedCornerStyleOpen = computed(() => {
|
||||
return store.roundedCornerStyleOpen
|
||||
})
|
||||
// 路由监听高亮
|
||||
const showThis = () => {
|
||||
|
@ -266,14 +174,14 @@
|
|||
}
|
||||
const nextTickMenu = pMenu.value.children
|
||||
if (pidKey) {
|
||||
const modelPidKey = getParentKeys(moduleMenuData.value, route.path)
|
||||
moduleMenuData.value.forEach((item) => {
|
||||
const modelPidKey = getParentKeys(moduleMenu.value, route.path)
|
||||
moduleMenu.value.forEach((item) => {
|
||||
if (modelPidKey.includes(item.path)) {
|
||||
tagSwitchModule(item.id)
|
||||
}
|
||||
})
|
||||
const parentPath = pidKey[pidKey.length - 1]
|
||||
if (layout.value === 'doublerow') {
|
||||
if (layout.value === layoutEnum.DOUBLEROW) {
|
||||
// 这一串操作下来只为取到最上面的路由的孩子们,最后成为双排菜单的第二排
|
||||
const nextMenuTemp = nextTickMenu.filter((item) => item.path === parentPath)[0].children
|
||||
if (nextMenuTemp) {
|
||||
|
@ -285,14 +193,14 @@
|
|||
openKeys.value = pidKey
|
||||
}
|
||||
// 双排菜单下
|
||||
if (layout.value === 'doublerow') {
|
||||
if (layout.value === layoutEnum.DOUBLEROW) {
|
||||
setDoubleRowSelectedKey()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 执行-start
|
||||
moduleMenuData.value = router.getMenu()
|
||||
moduleMenu.value = router.getMenu()
|
||||
// 获取缓存中的菜单模块是哪个
|
||||
const menuModuleId = tool.data.get('SNOWY_MENU_MODULE_ID')
|
||||
if (menuModuleId) {
|
||||
|
@ -307,13 +215,86 @@
|
|||
menu.value = router.getMenu()[0].children
|
||||
}
|
||||
showThis()
|
||||
|
||||
onMounted(() => {
|
||||
onLayoutResize()
|
||||
window.addEventListener('resize', onLayoutResize)
|
||||
window.addEventListener('resize', getNav)
|
||||
switchoverTopHeaderThemeColor()
|
||||
settingTopHeaderThemeOrColor(theme.value, layout.value)
|
||||
settingFixedWidth()
|
||||
nextTick(() => {
|
||||
getNav(menu.value)
|
||||
})
|
||||
})
|
||||
watch(route, (newValue) => {
|
||||
// 动态获取横向导航栏隐藏数量
|
||||
const getNav = (items) => {
|
||||
const item = menu.value
|
||||
// 判断一下是不是顶部导航栏的模式
|
||||
if (layout.value !== 'top') return
|
||||
const menuNavList = menu.value
|
||||
menuList.value = menuNavList
|
||||
nextTick(() => {
|
||||
// 获取所有的导航菜单
|
||||
let liArr = document.querySelector('#topHeaderMenu').querySelectorAll('li')
|
||||
let allWidth = document.querySelector('#xn-line-nav').offsetWidth // 可以显示区域的宽度
|
||||
|
||||
// 计算显示的宽度
|
||||
let num = 0
|
||||
let startIndex = 0
|
||||
for (const [index, item] of liArr.entries()) {
|
||||
num += item.offsetWidth
|
||||
if (num > allWidth) {
|
||||
startIndex = index - 1
|
||||
break
|
||||
}
|
||||
}
|
||||
// 判断显示出来的导航栏长度是否小于可以显示的区域
|
||||
if (num < allWidth) {
|
||||
menuList.value = menuNavList
|
||||
return
|
||||
}
|
||||
// 如果大于了课显示的区域,就将其隐藏
|
||||
const showNav = menuNavList.slice(0, startIndex)
|
||||
const hiddenNav = menuNavList.slice(startIndex, menuNavList.length)
|
||||
menuList.value = showNav
|
||||
menuList.value.push({
|
||||
meta: {
|
||||
icon: 'rightCircle-outlined',
|
||||
title: '更多',
|
||||
type: 'catalog'
|
||||
},
|
||||
children: hiddenNav
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 鼠标滚动事件
|
||||
const handleMouseWheel = (event) => {
|
||||
let element = document.querySelector('#xn-line-nav')
|
||||
let element2 = document.querySelector('#topHeaderMenu')
|
||||
|
||||
// 判断鼠标是向上滚动还是向下滚动的
|
||||
let delta = event.deltaY
|
||||
// 滚动菜单时变换的一个大小
|
||||
const num = 20
|
||||
|
||||
// 滚动的距离
|
||||
let leftMove = Number(element2.style.left.slice(0, -2))
|
||||
// 父盒子相对子盒子滚动的一个判断,用来给盒子加一个临界点
|
||||
let remove = element.offsetWidth - element2.scrollWidth
|
||||
|
||||
// 鼠标向下滚动
|
||||
// 满足子元素移动的距离大于两个元素相差的距离时
|
||||
if (delta < 0 && leftMove > remove) {
|
||||
element2.style.left = leftMove - num + 'px'
|
||||
} else if (delta > 0 && leftMove < 0) {
|
||||
// 鼠标向上滚动
|
||||
// 当移动的距离小于0的时候,可以向后滚动
|
||||
element2.style.left = leftMove + num + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
watch(route, () => {
|
||||
// 清理选中的
|
||||
selectedKeys.value = []
|
||||
showThis()
|
||||
|
@ -321,50 +302,128 @@
|
|||
// 监听是否开启了顶栏颜色
|
||||
watch(layout, (newValue) => {
|
||||
document.body.setAttribute('data-layout', newValue)
|
||||
if (newValue.includes('doublerow')) {
|
||||
if (newValue.includes(layoutEnum.DOUBLEROW)) {
|
||||
showThis()
|
||||
setDoubleRowSelectedKey()
|
||||
}
|
||||
nextTick(() => {
|
||||
// 顶栏主题色
|
||||
switchoverTopHeaderThemeColor()
|
||||
// top下的顶栏
|
||||
settingTopHeaderThemeOrColor(theme.value, newValue)
|
||||
getNav(menu.value)
|
||||
settingFixedWidth()
|
||||
let element = document.querySelector('#xn-line-nav')
|
||||
if (element) {
|
||||
element.addEventListener('mousewheel', handleMouseWheel, false)
|
||||
}
|
||||
})
|
||||
})
|
||||
watch(topHeaderThemeColorOpen, () => {
|
||||
switchoverTopHeaderThemeColor()
|
||||
})
|
||||
watch(fixedWidth, () => {
|
||||
settingFixedWidth()
|
||||
})
|
||||
watch(layoutTagsOpen, () => {
|
||||
settingFixedWidth()
|
||||
})
|
||||
watch(breadcrumbOpen, () => {
|
||||
settingFixedWidth()
|
||||
})
|
||||
watch(topHeaderThemeColorSpread, () => {
|
||||
switchoverTopHeaderThemeColor()
|
||||
})
|
||||
watch(theme, (newValue) => {
|
||||
settingTopHeaderThemeOrColor(newValue, layout.value)
|
||||
})
|
||||
watch(themeColor, () => {
|
||||
settingTopHeaderThemeOrColor(theme.value, layout.value)
|
||||
})
|
||||
watch(topHeaderThemeColorOpen, (newValue) => {
|
||||
switchoverTopHeaderThemeColor()
|
||||
const header = document.getElementById('snowyHeader')
|
||||
const topHeaderMenu = document.getElementById('topHeaderMenu')
|
||||
if (layout.value === layoutEnum.TOP) {
|
||||
if (newValue) {
|
||||
header.classList.add('top-snowy-header-layout')
|
||||
topHeaderMenu.classList.add('top-snowy-header-layout')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header-layout')
|
||||
topHeaderMenu.classList.remove('top-snowy-header-layout')
|
||||
}
|
||||
}
|
||||
})
|
||||
watch(topHeaderThemeColorSpread, (newValue) => {
|
||||
switchoverTopHeaderThemeColor()
|
||||
watch(roundedCornerStyleOpen, () => {
|
||||
settingTopHeaderThemeOrColor(theme.value, layout.value)
|
||||
})
|
||||
// 设置固定宽度
|
||||
const settingFixedWidth = () => {
|
||||
nextTick(() => {
|
||||
const breadcrumbWidth = document.querySelector('.admin-ui-breadcrumb')
|
||||
const showWidth = document.querySelector('.snowy-tags')
|
||||
const mainWidth = document.querySelector('.ant-layout-content')
|
||||
if (fixedWidth.value && layout.value === layoutEnum.TOP) {
|
||||
breadcrumbWidth?.classList.add('xn-mg050')
|
||||
showWidth?.classList.add('xn-mg050')
|
||||
mainWidth?.classList.add('xn-pd1180')
|
||||
} else {
|
||||
breadcrumbWidth?.classList.remove('xn-mg050')
|
||||
showWidth?.classList.remove('xn-mg050')
|
||||
mainWidth?.classList.remove('xn-pd1180')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 设置顶栏颜色或者主题
|
||||
const settingTopHeaderThemeOrColor = (theme, layout) => {
|
||||
const header = document.getElementById('snowyHeader')
|
||||
const topHeaderMenu = document.getElementById('topHeaderMenu')
|
||||
|
||||
if (topHeaderThemeColorOpen.value && layout === layoutEnum.TOP) {
|
||||
nextTick(() => {
|
||||
topHeaderMenu.classList.add('top-snowy-header-layout')
|
||||
header.classList.add('top-snowy-header-layout')
|
||||
})
|
||||
} else if (!topHeaderThemeColorOpen.value && layout === layoutEnum.TOP) {
|
||||
nextTick(() => {
|
||||
topHeaderMenu.classList.remove('top-snowy-header-layout')
|
||||
header.classList.remove('top-snowy-header-layout')
|
||||
})
|
||||
}
|
||||
if (theme === themeEnum.LIGHT && layout === layoutEnum.TOP) {
|
||||
header.classList.remove('top-snowy-header')
|
||||
header.classList.add('top-snowy-header-light')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header-light')
|
||||
if (layout === layoutEnum.TOP) {
|
||||
header.classList.add('top-snowy-header')
|
||||
} else {
|
||||
if (theme === themeEnum.REAL_DARK) {
|
||||
header.classList.add('top-snowy-header')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const menuIsCollapseClick = () => {
|
||||
store.toggleConfig('menuIsCollapse')
|
||||
}
|
||||
// 切换顶栏颜色
|
||||
const switchoverTopHeaderThemeColor = () => {
|
||||
// 界面顶栏设置颜色
|
||||
const header = document.getElementById('snowyHeader')
|
||||
topHeaderThemeColorOpen.value
|
||||
? header.classList.add('snowy-header-primary-color')
|
||||
: header.classList.remove('snowy-header-primary-color')
|
||||
// 判断是否开启了通栏
|
||||
const headerLogin = document.getElementById('snowyHeaderLogo')
|
||||
try {
|
||||
// 界面顶栏设置颜色
|
||||
const header = document.getElementById('snowyHeader')
|
||||
topHeaderThemeColorOpen.value
|
||||
? header.classList.add('snowy-header-primary-color')
|
||||
: header.classList.remove('snowy-header-primary-color')
|
||||
// 判断是否开启了通栏
|
||||
const headerLogin = document.getElementById('snowyHeaderLogo')
|
||||
topHeaderThemeColorSpread.value
|
||||
? headerLogin.classList.add('snowy-header-logo-primary-color')
|
||||
: headerLogin.classList.remove('snowy-header-logo-primary-color')
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
// 如果是双排菜单,吧第二排的也给渲染了
|
||||
if (layout.value === 'doublerow') {
|
||||
const snowyDoublerowSideTop = document.getElementById('snowyDoublerowSideTop')
|
||||
try {
|
||||
topHeaderThemeColorSpread.value
|
||||
? snowyDoublerowSideTop.classList.add('snowy-doublerow-side-top-primary-color')
|
||||
: snowyDoublerowSideTop.classList.remove('snowy-doublerow-side-top-primary-color')
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置双排菜单下的首列默认选中
|
||||
|
@ -447,7 +506,7 @@
|
|||
layoutSiderDowbleMenu.value = false
|
||||
}
|
||||
}
|
||||
if (layout.value === 'doublerow') {
|
||||
if (layout.value === layoutEnum.DOUBLEROW) {
|
||||
doublerowSelectedKey.value = [route.path]
|
||||
}
|
||||
}
|
||||
|
@ -466,9 +525,9 @@
|
|||
}
|
||||
// 切换应用
|
||||
const switchModule = (id) => {
|
||||
if (moduleMenuData.value.length > 0) {
|
||||
if (moduleMenu.value.length > 0) {
|
||||
showThis()
|
||||
const menus = moduleMenuData.value.filter((item) => item.id === id)[0].children
|
||||
const menus = moduleMenu.value.filter((item) => item.id === id)[0].children
|
||||
if (menus.length > 0) {
|
||||
// 正儿八百的菜单
|
||||
menu.value = menus
|
||||
|
@ -487,6 +546,7 @@
|
|||
message.warning('该模块下无任何菜单')
|
||||
}
|
||||
}
|
||||
getNav(menu.value)
|
||||
}
|
||||
// 通过标签切换应用
|
||||
const tagSwitchModule = (id) => {
|
||||
|
@ -494,7 +554,7 @@
|
|||
tool.data.set('SNOWY_MENU_MODULE_ID', id)
|
||||
store.setModule(id)
|
||||
// 正儿八百的菜单
|
||||
menu.value = moduleMenuData.value.filter((item) => item.id === id)[0].children
|
||||
menu.value = moduleMenu.value.filter((item) => item.id === id)[0].children
|
||||
}
|
||||
// 遍历获取子集
|
||||
const traverseChild = (menu) => {
|
||||
|
@ -519,3 +579,46 @@
|
|||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.xn-color-fff {
|
||||
color: #fff;
|
||||
}
|
||||
.xn-pdl25 {
|
||||
padding-left: 11px;
|
||||
}
|
||||
.xn-menu-line {
|
||||
text-align: center;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
.xn-navmenu-line {
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
// padding: 0 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.xn-bb0 {
|
||||
border-bottom: none;
|
||||
position: relative;
|
||||
}
|
||||
.ant-layout-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.xn-pd1180 {
|
||||
padding: 10px 150px 0 150px;
|
||||
}
|
||||
.xn-pd050 {
|
||||
padding: 0 50px;
|
||||
}
|
||||
.xn-pl10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.xn-mg050 {
|
||||
margin: 0px 150px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<a-layout>
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
:collapsed="menuIsCollapse"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:theme="sideTheme"
|
||||
width="210"
|
||||
>
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div :class="menuIsCollapse ? 'admin-ui-side isCollapse' : 'admin-ui-side'">
|
||||
<div class="admin-ui-side-scroll">
|
||||
<a-menu
|
||||
v-bind:openKeys="openKeys"
|
||||
v-bind:selectedKeys="selectedKeys"
|
||||
:theme="sideTheme"
|
||||
mode="inline"
|
||||
@select="onSelect"
|
||||
@openChange="onOpenChange"
|
||||
>
|
||||
<NavMenu :nav-menus="menu" />
|
||||
</a-menu>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" />
|
||||
<!-- 右侧布局 -->
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header">
|
||||
<div class="snowy-header-left xn-pl0">
|
||||
<div v-if="!isMobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
|
||||
<MenuUnfoldOutlined v-if="menuIsCollapse" />
|
||||
<MenuFoldOutlined v-else />
|
||||
</div>
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" />
|
||||
</div>
|
||||
<div class="snowy-header-right">
|
||||
<user-bar />
|
||||
</div>
|
||||
</div>
|
||||
<Breadcrumb v-if="!isMobile && breadcrumbOpen" />
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||
<a-layout-content class="main-content-wrapper">
|
||||
<div id="admin-ui-main" class="admin-ui-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="kStore.keepLiveRoute">
|
||||
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<iframe-view />
|
||||
<div v-if="footerCopyrightOpen" class="main-bottom-wrapper">
|
||||
<a class="xn-color-a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
|
||||
sysBaseConfig.SNOWY_SYS_COPYRIGHT
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
import UserBar from '@/layout/components/userbar.vue'
|
||||
import Tags from '@/layout/components/tags.vue'
|
||||
import SideM from '@/layout/components/sideM.vue'
|
||||
import NavMenu from '@/layout/components/NavMenu.vue'
|
||||
import ModuleMenu from '@/layout/components/moduleMenu.vue'
|
||||
import IframeView from '@/layout/components/iframeView.vue'
|
||||
import Breadcrumb from '@/layout/components/breadcrumb.vue'
|
||||
|
||||
const props = defineProps({
|
||||
layout: { type: String }, // 布局信息
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
menuIsCollapse: { type: Boolean }, // 菜单是否折叠
|
||||
sideTheme: { type: String },
|
||||
sysBaseConfig: { type: Object },
|
||||
openKeys: { type: Array },
|
||||
selectedKeys: { type: Array },
|
||||
menu: { type: Array }, // 菜单
|
||||
breadcrumbOpen: { type: Boolean }, //面包屑
|
||||
layoutTagsOpen: { type: Boolean },
|
||||
kStore: { type: Object }, // 获取的仓库数据
|
||||
footerCopyrightOpen: { type: Boolean }, //页脚版权信息
|
||||
moduleMenuShow: { type: Boolean }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onSelect', 'onOpenChange', 'switchModule', 'menuIsCollapseClick'])
|
||||
const onSelect = (obj) => {
|
||||
emit('onSelect', obj)
|
||||
}
|
||||
const onOpenChange = (keys) => {
|
||||
emit('onOpenChange', keys)
|
||||
}
|
||||
const switchModule = (id) => {
|
||||
emit('switchModule', id)
|
||||
}
|
||||
const menuIsCollapseClick = () => {
|
||||
emit('menuIsCollapseClick')
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.xn-color-fff {
|
||||
color: #fff;
|
||||
}
|
||||
.xn-pdl25 {
|
||||
padding-left: 11px;
|
||||
}
|
||||
.xn-menu-line {
|
||||
text-align: center;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
.xn-navmenu-line {
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.xn-bb0 {
|
||||
border-bottom: none;
|
||||
position: relative;
|
||||
}
|
||||
.ant-layout-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.xn-pd1180 {
|
||||
padding: 10px 150px 0 150px;
|
||||
}
|
||||
.xn-pd050 {
|
||||
padding: 0 50px;
|
||||
}
|
||||
.xn-pl10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.xn-mg050 {
|
||||
margin: 0px 150px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,185 @@
|
|||
<template>
|
||||
<a-layout>
|
||||
<a-layout-sider v-if="!isMobile" width="80" :theme="sideTheme" :trigger="null" collapsible>
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<router-link to="/">
|
||||
<img class="logo" :title="sysBaseConfig.SNOWY_SYS_NAME" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<a-menu
|
||||
:selectedKeys="doublerowSelectedKey"
|
||||
:theme="sideTheme"
|
||||
class="snowy-doublerow-layout-menu"
|
||||
v-for="item in menu"
|
||||
:key="item.path"
|
||||
>
|
||||
<a-menu-item
|
||||
:key="item.path"
|
||||
style="
|
||||
text-align: center;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
"
|
||||
@click="showMenu(item)"
|
||||
v-if="!item.meta.hidden"
|
||||
>
|
||||
<a v-if="item.meta && item.meta.type === 'link'" :href="item.path" target="_blank" @click.stop="() => {}" />
|
||||
<template #icon>
|
||||
<component :is="item.meta.icon" class="xn-pl10" />
|
||||
</template>
|
||||
<div class="snowy-doublerow-layout-menu-item-fort-div">
|
||||
<span class="snowy-doublerow-layout-menu-item-fort-div-span">
|
||||
{{ item.meta.title }}
|
||||
</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" />
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header">
|
||||
<div class="snowy-header-left xn-pl0">
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" />
|
||||
</div>
|
||||
<div class="snowy-header-right">
|
||||
<user-bar />
|
||||
</div>
|
||||
</div>
|
||||
<a-layout>
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
v-show="layoutSiderDowbleMenu"
|
||||
:collapsed="menuIsCollapse"
|
||||
:trigger="null"
|
||||
width="170"
|
||||
collapsible
|
||||
:theme="secondMenuSideTheme"
|
||||
>
|
||||
<a-menu
|
||||
:collapsed="menuIsCollapse"
|
||||
:openKeys="openKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
mode="inline"
|
||||
:theme="secondMenuSideTheme"
|
||||
@select="onSelect"
|
||||
>
|
||||
<NavMenu :nav-menus="nextMenu" />
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout-content>
|
||||
<breadcrumb v-if="!isMobile && breadcrumbOpen" />
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||
<div class="main-content-wrapper">
|
||||
<div id="admin-ui-main" class="admin-ui-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="kStore.keepLiveRoute">
|
||||
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<iframe-view />
|
||||
<div v-if="footerCopyrightOpen" class="main-bottom-wrapper">
|
||||
<a class="xn-color-a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
|
||||
sysBaseConfig.SNOWY_SYS_COPYRIGHT
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
import UserBar from '@/layout/components/userbar.vue'
|
||||
import Tags from '@/layout/components/tags.vue'
|
||||
import SideM from '@/layout/components/sideM.vue'
|
||||
import NavMenu from '@/layout/components/NavMenu.vue'
|
||||
import ModuleMenu from '@/layout/components/moduleMenu.vue'
|
||||
import IframeView from '@/layout/components/iframeView.vue'
|
||||
import Breadcrumb from '@/layout/components/breadcrumb.vue'
|
||||
|
||||
const props = defineProps({
|
||||
layout: { type: String }, // 布局信息
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
sideTheme: { type: String },
|
||||
menuIsCollapse: {},
|
||||
sysBaseConfig: { type: Object },
|
||||
openKeys: { type: Array },
|
||||
selectedKeys: { type: Array },
|
||||
doublerowSelectedKey: { type: Array },
|
||||
nextMenu: { type: Array },
|
||||
menu: { type: Array }, // 菜单
|
||||
breadcrumbOpen: { type: Boolean }, //面包屑
|
||||
layoutTagsOpen: { type: Boolean },
|
||||
layoutSiderDowbleMenu: { type: Boolean },
|
||||
kStore: { type: Object }, // 获取的仓库数据
|
||||
footerCopyrightOpen: { type: Boolean }, //页脚版权信息
|
||||
moduleMenuShow: { type: Boolean },
|
||||
secondMenuSideTheme: {}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onSelect', 'switchModule', 'showMenu'])
|
||||
const onSelect = (obj) => {
|
||||
emit('onSelect', obj)
|
||||
}
|
||||
const switchModule = (id) => {
|
||||
emit('switchModule', id)
|
||||
}
|
||||
const showMenu = (route) => {
|
||||
emit('showMenu', route)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.xn-color-fff {
|
||||
color: #fff;
|
||||
}
|
||||
.xn-pdl25 {
|
||||
padding-left: 11px;
|
||||
}
|
||||
.xn-menu-line {
|
||||
text-align: center;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
.xn-navmenu-line {
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.xn-bb0 {
|
||||
border-bottom: none;
|
||||
position: relative;
|
||||
}
|
||||
.ant-layout-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.xn-pd1180 {
|
||||
padding: 10px 150px 0 150px;
|
||||
}
|
||||
.xn-pd050 {
|
||||
padding: 0 50px;
|
||||
}
|
||||
.xn-pl10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.xn-mg050 {
|
||||
margin: 0px 150px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<a-layout>
|
||||
<a-layout class="layout">
|
||||
<div id="snowyHeader" class="snowy-header top-snowy-header xn-pd050">
|
||||
<div class="snowy-header-left xn-pl0">
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" class="xn-pdl25" />
|
||||
<div class="xn-navmenu-line" id="xn-line-nav">
|
||||
<a-menu
|
||||
class="xn-bb0"
|
||||
id="topHeaderMenu"
|
||||
:selectedKeys="selectedKeys"
|
||||
:theme="sideTheme"
|
||||
mode="horizontal"
|
||||
@select="onSelect"
|
||||
@openChange="onOpenChange"
|
||||
collapsed="true"
|
||||
>
|
||||
<NavMenu :nav-menus="menuList" />
|
||||
</a-menu>
|
||||
</div>
|
||||
<div class="snowy-header-right">
|
||||
<user-bar />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" />
|
||||
<breadcrumb v-if="!isMobile && breadcrumbOpen" />
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" />
|
||||
<a-layout-content class="main-content-wrapper">
|
||||
<div id="admin-ui-main" class="admin-ui-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="kStore.keepLiveRoute">
|
||||
<component :is="Component" v-if="kStore.routeShow" :key="route.name" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<iframe-view />
|
||||
<div v-if="footerCopyrightOpen" class="main-bottom-wrapper">
|
||||
<a class="xn-color-a0a0a0" :href="sysBaseConfig.SNOWY_SYS_COPYRIGHT_URL" target="_blank">{{
|
||||
sysBaseConfig.SNOWY_SYS_COPYRIGHT
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
import UserBar from '@/layout/components/userbar.vue'
|
||||
import Tags from '@/layout/components/tags.vue'
|
||||
import SideM from '@/layout/components/sideM.vue'
|
||||
import NavMenu from '@/layout/components/NavMenu.vue'
|
||||
import ModuleMenu from '@/layout/components/moduleMenu.vue'
|
||||
import IframeView from '@/layout/components/iframeView.vue'
|
||||
import Breadcrumb from '@/layout/components/breadcrumb.vue'
|
||||
|
||||
const props = defineProps({
|
||||
layout: {},
|
||||
menu: { type: Array }, // 菜单
|
||||
menuList: { type: Array }, // 菜单
|
||||
sysBaseConfig: { type: Object },
|
||||
moduleMenuShow: { type: Boolean },
|
||||
selectedKeys: { type: Array },
|
||||
openKeys: { type: Array },
|
||||
sideTheme: { type: String },
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
breadcrumbOpen: { type: Boolean }, //面包屑
|
||||
layoutTagsOpen: { type: Boolean },
|
||||
layoutSiderDowbleMenu: { type: Boolean },
|
||||
kStore: { type: Object }, // 获取的仓库数据
|
||||
footerCopyrightOpen: { type: Boolean } //页脚版权信息
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onSelect', 'switchModule', 'onOpenChange'])
|
||||
const onSelect = (obj) => {
|
||||
emit('onSelect', obj)
|
||||
}
|
||||
const switchModule = (id) => {
|
||||
emit('switchModule', id)
|
||||
}
|
||||
const onOpenChange = (keys) => {
|
||||
emit('onOpenChange', keys)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.xn-color-fff {
|
||||
color: #fff;
|
||||
}
|
||||
.xn-pdl25 {
|
||||
padding-left: 11px;
|
||||
}
|
||||
.xn-menu-line {
|
||||
text-align: center;
|
||||
height: auto;
|
||||
line-height: 20px;
|
||||
flex: none;
|
||||
display: block;
|
||||
padding: 12px 0 !important;
|
||||
}
|
||||
.xn-navmenu-line {
|
||||
min-width: 0;
|
||||
flex: 1 1 0%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.xn-bb0 {
|
||||
border-bottom: none;
|
||||
position: relative;
|
||||
}
|
||||
.ant-layout-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.xn-pd1180 {
|
||||
padding: 10px 150px 0 150px;
|
||||
}
|
||||
.xn-pd050 {
|
||||
padding: 0 50px;
|
||||
}
|
||||
.xn-pl10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.xn-mg050 {
|
||||
margin: 0px 150px;
|
||||
}
|
||||
</style>
|
|
@ -27,20 +27,12 @@ const getCacheConfig = (value) => {
|
|||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* deprecated 请使用 useGlobalStore
|
||||
*/
|
||||
// deprecated 请使用 useGlobalStore
|
||||
export const globalStore = defineStore('global', () => {
|
||||
// 利用Vue3组合式API,ref()定义state的属性
|
||||
// function() 定义actions
|
||||
// computed 定义getters
|
||||
|
||||
// 定义state
|
||||
// 移动端布局
|
||||
const isMobile = ref(false)
|
||||
// 布局
|
||||
const layout = ref(getCacheConfig('SNOWY_LAYOUT'))
|
||||
|
||||
// 菜单是否折叠 toggle
|
||||
const menuIsCollapse = ref(getCacheConfig('SNOWY_MENU_COLLAPSE'))
|
||||
// 侧边菜单是否排他展开
|
||||
|
@ -49,17 +41,24 @@ export const globalStore = defineStore('global', () => {
|
|||
const layoutTagsOpen = ref(getCacheConfig('SNOWY_LAYOUT_TAGS_OPEN'))
|
||||
// 是否展示面包屑
|
||||
const breadcrumbOpen = ref(getCacheConfig('SNOWY_BREADCRUMD_OPEN'))
|
||||
// 是否开启固定宽度(顶栏菜单)
|
||||
const fixedWidth = ref(getCacheConfig('SNOWY_FIXEDWIDTH_OPEN'))
|
||||
// 顶栏是否应用主题色
|
||||
const topHeaderThemeColorOpen = ref(getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_OPEN'))
|
||||
// 顶栏主题色通栏
|
||||
const topHeaderThemeColorSpread = ref(getCacheConfig('SNOWY_TOP_HEADER_THEME_COLOR_SPREAD'))
|
||||
// 登录用户水印
|
||||
const loginUserWatermarkOpen = ref(getCacheConfig('SNOWY_LOGIN_USER_WATERMARK_OPEN'))
|
||||
// 页脚版权信息
|
||||
const footerCopyrightOpen = ref(getCacheConfig('SNOWY_FOOTER_COPYRIGHT_OPEN'))
|
||||
// 模块坞
|
||||
const moduleUnfoldOpen = ref(getCacheConfig('SNOWY_MODULE_UNFOLD_OPEN'))
|
||||
|
||||
// 主题
|
||||
const theme = ref(getCacheConfig('SNOWY_THEME'))
|
||||
// 主题颜色
|
||||
const themeColor = ref(toolDataGet('SNOWY_THEME_COLOR') || config.COLOR)
|
||||
// 圆角分格
|
||||
const roundedCornerStyleOpen = ref(getCacheConfig('SNOWY_ROUNDED_CORNER_STYLE_OPEN'))
|
||||
// 整体表单风格
|
||||
const formStyle = ref(getCacheConfig('SNOWY_FORM_STYLE'))
|
||||
// 用户信息
|
||||
|
@ -107,12 +106,24 @@ export const globalStore = defineStore('global', () => {
|
|||
case 'breadcrumbOpen':
|
||||
breadcrumbOpen.value = !breadcrumbOpen.value
|
||||
break
|
||||
case 'fixedWidth':
|
||||
fixedWidth.value = !fixedWidth.value
|
||||
break
|
||||
case 'topHeaderThemeColorOpen':
|
||||
topHeaderThemeColorOpen.value = !topHeaderThemeColorOpen.value
|
||||
topHeaderThemeColorSpread.value = topHeaderThemeColorOpen.value
|
||||
? topHeaderThemeColorSpread.value
|
||||
: topHeaderThemeColorOpen.value
|
||||
break
|
||||
case 'loginUserWatermarkOpen':
|
||||
loginUserWatermarkOpen.value = !loginUserWatermarkOpen.value
|
||||
break
|
||||
case 'footerCopyrightOpen':
|
||||
footerCopyrightOpen.value = !footerCopyrightOpen.value
|
||||
break
|
||||
case 'roundedCornerStyleOpen':
|
||||
roundedCornerStyleOpen.value = !roundedCornerStyleOpen.value
|
||||
break
|
||||
case 'moduleUnfoldOpen':
|
||||
moduleUnfoldOpen.value = !moduleUnfoldOpen.value
|
||||
break
|
||||
|
@ -137,11 +148,15 @@ export const globalStore = defineStore('global', () => {
|
|||
sideUniqueOpen,
|
||||
layoutTagsOpen,
|
||||
breadcrumbOpen,
|
||||
fixedWidth,
|
||||
topHeaderThemeColorOpen,
|
||||
topHeaderThemeColorSpread,
|
||||
loginUserWatermarkOpen,
|
||||
footerCopyrightOpen,
|
||||
moduleUnfoldOpen,
|
||||
theme,
|
||||
themeColor,
|
||||
roundedCornerStyleOpen,
|
||||
formStyle,
|
||||
userInfo,
|
||||
sysBaseConfig,
|
||||
|
|
|
@ -1,398 +1,399 @@
|
|||
@import 'ant-design-vue/es/style/themes/default.less';
|
||||
|
||||
:root {
|
||||
--blue-1: #e6f7ff;
|
||||
--blue-2: #bae7ff;
|
||||
--blue-3: #91d5ff;
|
||||
--blue-4: #69c0ff;
|
||||
--blue-5: #40a9ff;
|
||||
--blue-6: #1890ff;
|
||||
--blue-7: #096dd9;
|
||||
--blue-8: #0050b3;
|
||||
--blue-9: #003a8c;
|
||||
--blue-10: #002766;
|
||||
|
||||
--green-1: #f6ffed;
|
||||
--green-2: #d9f7be;
|
||||
--green-3: #b7eb8f;
|
||||
--green-4: #95de64;
|
||||
--green-5: #73d13d;
|
||||
--green-6: #52c41a;
|
||||
--green-7: #389e0d;
|
||||
--green-8: #237804;
|
||||
--green-9: #135200;
|
||||
--green-10: #092b00;
|
||||
|
||||
--red-1: #fff1f0;
|
||||
--red-2: #ffccc7;
|
||||
--red-3: #ffa39e;
|
||||
--red-4: #ff7875;
|
||||
--red-5: #ff4d4f;
|
||||
--red-6: #f5222d;
|
||||
--red-7: #cf1322;
|
||||
--red-8: #a8071a;
|
||||
--red-9: #820014;
|
||||
--red-10: #5c0011;
|
||||
|
||||
--gold-1: #fffbe6;
|
||||
--gold-2: #fff1b8;
|
||||
--gold-3: #ffe58f;
|
||||
--gold-4: #ffd666;
|
||||
--gold-5: #ffc53d;
|
||||
--gold-6: #faad14;
|
||||
--gold-7: #d48806;
|
||||
--gold-8: #ad6800;
|
||||
--gold-9: #874d00;
|
||||
--gold-10: #613400;
|
||||
|
||||
--purple-1: #f9f0ff;
|
||||
--purple-2: #efdbff;
|
||||
--purple-3: #d3adf7;
|
||||
--purple-4: #b37feb;
|
||||
--purple-5: #9254de;
|
||||
--purple-6: #722ed1;
|
||||
--purple-7: #531dab;
|
||||
--purple-8: #391085;
|
||||
--purple-9: #22075e;
|
||||
--purple-10: #120338;
|
||||
|
||||
--cyan-1: #e6fffb;
|
||||
--cyan-2: #b5f5ec;
|
||||
--cyan-3: #87e8de;
|
||||
--cyan-4: #5cdbd3;
|
||||
--cyan-5: #36cfc9;
|
||||
--cyan-6: #13c2c2;
|
||||
--cyan-7: #08979c;
|
||||
--cyan-8: #006d75;
|
||||
--cyan-9: #00474f;
|
||||
--cyan-10: #002329;
|
||||
|
||||
--pink-1: #fff0f6;
|
||||
--pink-2: #ffd6e7;
|
||||
--pink-3: #ffadd2;
|
||||
--pink-4: #ff85c0;
|
||||
--pink-5: #f759ab;
|
||||
--pink-6: #eb2f96;
|
||||
--pink-7: #c41d7f;
|
||||
--pink-8: #9e1068;
|
||||
--pink-9: #780650;
|
||||
--pink-10: #520339;
|
||||
|
||||
--orange-1: #fff7e6;
|
||||
--orange-2: #ffe7ba;
|
||||
--orange-3: #ffd591;
|
||||
--orange-4: #ffc069;
|
||||
--orange-5: #ffa940;
|
||||
--orange-6: #fa8c16;
|
||||
--orange-7: #d46b08;
|
||||
--orange-8: #ad4e00;
|
||||
--orange-9: #873800;
|
||||
--orange-10: #612500;
|
||||
|
||||
--primary-1: var(--blue-1);
|
||||
--primary-2: var(--blue-2);
|
||||
--primary-3: var(--blue-3);
|
||||
--primary-4: var(--blue-4);
|
||||
--primary-5: var(--blue-5);
|
||||
--primary-6: var(--blue-6);
|
||||
--primary-7: var(--blue-7);
|
||||
--primary-8: var(--blue-8);
|
||||
--primary-9: var(--blue-9);
|
||||
--primary-10: var(--blue-10);
|
||||
|
||||
--primary-color: var(--primary-6);
|
||||
--primary-color-hover: var(--primary-5);
|
||||
--primary-color-active: var(--primary-7);
|
||||
--primary-color-outline: var(--primary-2);
|
||||
|
||||
--info-color: var(--primary-color);
|
||||
--success-color: var(--green-6);
|
||||
--processing-color: var(--blue-6);
|
||||
--highlight-color: var(--red-5);
|
||||
|
||||
--warning-color: var(--gold-6);
|
||||
--warning-color-hover: var(--gold-5);
|
||||
--warning-color-active: var(--gold-7);
|
||||
--warning-color-outline: var(--gold-2);
|
||||
|
||||
--error-color: var(--red-5);
|
||||
--error-color-hover: var(--red-4);
|
||||
--error-color-active: var(--red-7);
|
||||
--error-color-outline: var(--red-2);
|
||||
|
||||
--body-background: #fff;
|
||||
--component-background: #fff;
|
||||
|
||||
--popover-background: @component-background;
|
||||
--popover-customize-border-color: @border-color-split;
|
||||
|
||||
--text-color: fade(@black, 85%);
|
||||
--text-color-secondary: fade(@black, 45%);
|
||||
--text-color-inverse: @white;
|
||||
--icon-color-hover: fade(@black, 75%);
|
||||
--heading-color: fade(@black, 85%);
|
||||
|
||||
--item-hover-bg: #f5f5f5;
|
||||
|
||||
// Border color
|
||||
--border-color-base: hsv(0, 0, 85%);
|
||||
--border-color-split: hsv(0, 0, 94%);
|
||||
//--border-color-inverse: @white;
|
||||
|
||||
//
|
||||
--background-color-light: hsv(0, 0, 98%);
|
||||
--background-color-base: hsv(0, 0, 96%);
|
||||
|
||||
// Disabled states
|
||||
--disabled-color: fade(#000, 25%);
|
||||
--disabled-bg: @background-color-base;
|
||||
--disabled-color-dark: fade(#fff, 35%);
|
||||
|
||||
// Shadow
|
||||
--shadow-color: rgba(0, 0, 0, 0.15);
|
||||
--shadow-color-inverse: @component-background;
|
||||
--box-shadow-base: @shadow-1-down;
|
||||
--shadow-1-up: 0 -2px 8px @shadow-color;
|
||||
--shadow-1-down: 0 2px 8px @shadow-color;
|
||||
--shadow-1-left: -2px 0 8px @shadow-color;
|
||||
--shadow-1-right: 2px 0 8px @shadow-color;
|
||||
--shadow-2: 0 4px 12px @shadow-color;
|
||||
|
||||
// Buttons
|
||||
--btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
--btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
--btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
--btn-default-bg: @component-background;
|
||||
|
||||
--btn-default-ghost-color: @component-background;
|
||||
--btn-default-ghost-border: @component-background;
|
||||
|
||||
--btn-text-hover-bg: rgba(0, 0, 0, 0.018);
|
||||
--btn-text-active-bg: rgba(0, 0, 0, 0.028);
|
||||
|
||||
// Checkbox
|
||||
--checkbox-check-bg: @checkbox-check-color;
|
||||
|
||||
// Descriptions
|
||||
--descriptions-bg: #fafafa;
|
||||
|
||||
// Divider
|
||||
--divider-color: rgba(0, 0, 0, 6%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-submenu-disabled-bg: @component-background;
|
||||
|
||||
// Radio
|
||||
--radio-dot-disabled-color: fade(@black, 20%);
|
||||
--radio-solid-checked-color: @component-background;
|
||||
|
||||
// Radio buttons
|
||||
--radio-disabled-button-checked-bg: coverTintMixin(@black, 90%);
|
||||
--radio-disabled-button-checked-color: @disabled-color;
|
||||
|
||||
// Layout
|
||||
--layout-body-background: #f0f2f5;
|
||||
--layout-header-background: #001529;
|
||||
--layout-trigger-background: #002140;
|
||||
//--layout-sider-background-1: coverTintMixin(#001529, 10%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-bg: @component-background;
|
||||
|
||||
// Input
|
||||
--input-placeholder-color: hsv(0, 0, 75%);
|
||||
--input-icon-color: @input-color;
|
||||
--input-bg: @component-background;
|
||||
--input-number-handler-active-bg: #f4f4f4;
|
||||
--input-icon-hover-color: fade(@black, 85%);
|
||||
|
||||
// Mentions
|
||||
--mentions-dropdown-bg: @component-background;
|
||||
|
||||
// Select
|
||||
--select-dropdown-bg: @component-background;
|
||||
--select-background: @component-background;
|
||||
--select-clear-background: @select-background;
|
||||
--select-selection-item-bg: @background-color-base;
|
||||
--select-selection-item-border-color: @border-color-split;
|
||||
--select-multiple-disabled-background: @input-disabled-bg;
|
||||
--select-multiple-item-disabled-color: #bfbfbf;
|
||||
--select-multiple-item-disabled-border-color: @select-border-color;
|
||||
|
||||
// Cascader
|
||||
--cascader-bg: @component-background;
|
||||
--cascader-menu-bg: @component-background;
|
||||
--cascader-menu-border-color-split: @border-color-split;
|
||||
|
||||
// Tooltip
|
||||
--tooltip-bg: rgba(0, 0, 0, 0.75);
|
||||
|
||||
// Popover
|
||||
--popover-bg: @component-background;
|
||||
|
||||
// Modal
|
||||
--modal-header-bg: @component-background;
|
||||
--modal-header-border-color-split: @border-color-split;
|
||||
--modal-content-bg: @component-background;
|
||||
--modal-footer-border-color-split: @border-color-split;
|
||||
|
||||
// Progress
|
||||
--progress-steps-item-bg: #f3f3f3;
|
||||
|
||||
// Menu
|
||||
--menu-popup-bg: @component-background;
|
||||
--menu-dark-bg: @layout-header-background;
|
||||
--menu-dark-inline-submenu-bg: #000c17;
|
||||
|
||||
// Table
|
||||
--table-header-bg: @background-color-light;
|
||||
--table-header-sort-bg: @background-color-base;
|
||||
--table-body-sort-bg: #fafafa;
|
||||
--table-row-hover-bg: @background-color-light;
|
||||
--table-expanded-row-bg: #fbfbfb;
|
||||
--table-header-cell-split-color: rgba(0, 0, 0, 0.06);
|
||||
--table-header-sort-active-bg: rgba(0, 0, 0, 0.04);
|
||||
--table-header-filter-active-bg: rgba(0, 0, 0, 0.04);
|
||||
--table-filter-btns-bg: inherit;
|
||||
--table-filter-dropdown-bg: @component-background;
|
||||
--table-expand-icon-bg: @component-background;
|
||||
|
||||
// TimePicker
|
||||
--picker-bg: @component-background;
|
||||
--picker-basic-cell-disabled-bg: @disabled-bg;
|
||||
--picker-border-color: @border-color-split;
|
||||
|
||||
// Calendar
|
||||
--calendar-bg: @component-background;
|
||||
--calendar-input-bg: @input-bg;
|
||||
--calendar-border-color: @border-color-inverse;
|
||||
--calendar-full-bg: @calendar-bg;
|
||||
|
||||
// Badge
|
||||
--badge-text-color: @component-background;
|
||||
|
||||
// Rate
|
||||
--rate-star-bg: @border-color-split;
|
||||
|
||||
// Card
|
||||
--card-actions-background: @component-background;
|
||||
--card-skeleton-bg: #cfd8dc;
|
||||
--card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16),
|
||||
0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09);
|
||||
|
||||
// Comment
|
||||
--comment-bg: inherit;
|
||||
--comment-author-time-color: #ccc;
|
||||
--comment-action-hover-color: #595959;
|
||||
|
||||
// BackTop
|
||||
--back-top-bg: @text-color-secondary;
|
||||
--back-top-hover-bg: @text-color;
|
||||
|
||||
// Avatar
|
||||
--avatar-bg: #ccc;
|
||||
|
||||
// Switch
|
||||
--switch-bg: @component-background;
|
||||
|
||||
// Pagination
|
||||
--pagination-item-bg: @component-background;
|
||||
--pagination-item-bg-active: @component-background;
|
||||
--pagination-item-link-bg: @component-background;
|
||||
--pagination-item-disabled-color-active: @white;
|
||||
--pagination-item-disabled-bg-active: darken(hsv(0, 0, 96%), 10%);
|
||||
--pagination-item-input-bg: @component-background;
|
||||
|
||||
// PageHeader
|
||||
--page-header-back-color: #000;
|
||||
--page-header-ghost-bg: inherit;
|
||||
|
||||
// Slider
|
||||
--slider-rail-background-color: @background-color-base;
|
||||
--slider-rail-background-color-hover: #e1e1e1;
|
||||
--slider-dot-border-color: @border-color-split;
|
||||
--slider-dot-border-color-active: @primary-4;
|
||||
|
||||
// Tree
|
||||
--tree-bg: @component-background;
|
||||
|
||||
// Skeleton
|
||||
--skeleton-to-color: coverShadeMixin(@skeleton-color, 5%);
|
||||
|
||||
// Transfer
|
||||
--transfer-item-hover-bg: @item-hover-bg;
|
||||
|
||||
// Message
|
||||
--message-notice-content-bg: @component-background;
|
||||
|
||||
// List
|
||||
--list-customize-card-bg: @component-background;
|
||||
|
||||
// Drawer
|
||||
--drawer-bg: @component-background;
|
||||
|
||||
// Timeline
|
||||
--timeline-color: @border-color-split;
|
||||
--timeline-dot-color: @primary-color;
|
||||
|
||||
// Image
|
||||
--image-preview-operation-disabled-color: rgba(255, 255, 255, 0.45);
|
||||
|
||||
// Steps
|
||||
--steps-nav-arrow-color: fade(@black, 25%);
|
||||
--steps-background: @component-background;
|
||||
|
||||
// Notification
|
||||
--notification-bg: @component-background;
|
||||
|
||||
// 侧边栏
|
||||
--sidebar-light-shadow: 1px 3px 3px rgba(0, 21, 41, 0.08);
|
||||
--sidebar-dark-shadow: 0 4px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
// 顶栏
|
||||
--header-light-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
--header-dark-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
||||
--header-tool-hover-bg: rgba(0, 0, 0, 0.025);
|
||||
--header-dark-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-color-split: rgba(0, 0, 0, 0.08);
|
||||
|
||||
// logo
|
||||
--logo-light-shadow: 1px 2px 3px rgba(0, 21, 41, 0.08);
|
||||
--logo-dark-shadow: 0 3px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
//
|
||||
--gradient-min: fade(#cfd8dc, 20%);
|
||||
--gradient-max: fade(#cfd8dc, 40%);
|
||||
|
||||
//
|
||||
--success-fade-20: fade(#52c41a, 20%);
|
||||
--error-fade-20: fade(#ff4d4f, 20%);
|
||||
--warning-fade-20: fade(#faad14, 20%);
|
||||
|
||||
//--primary-fade-20: fade(#1890ff, 20%);
|
||||
--primary-fade-20: var(--primary-2);
|
||||
//--primary-fade-8: fade(#1890ff, 8%);
|
||||
|
||||
--white--fade--65: rgba(255,255,255,.65);
|
||||
--menu-dark-highlight-color: #fff;
|
||||
--btn-primary-color: #fff;
|
||||
--tooltip-color: #fff;
|
||||
|
||||
// workfolw design
|
||||
--node-wrap-box-color: rgb(255, 255, 255);
|
||||
--node-wrap-box-before-color: #FFFFFF;
|
||||
--node-wrap-box-before-borde-color: rgb(202, 202, 202);
|
||||
--auto-judge-before-color: @component-background;
|
||||
}
|
||||
|
||||
|
||||
#app .form-designer-container-9136076486841527{
|
||||
--form-designer-primary-color: var(--primary-6);
|
||||
--primary-background-color: @component-background;
|
||||
--layout-background-color: fade(#9867f7, 12%);
|
||||
--layout-hover-bg-color: fade(#9867f7, 24%);
|
||||
|
||||
--title-text-color: fade(@white, 85%);
|
||||
--border-color: var(--border-color-split);
|
||||
--blue-1: #e6f7ff;
|
||||
--blue-2: #bae7ff;
|
||||
--blue-3: #91d5ff;
|
||||
--blue-4: #69c0ff;
|
||||
--blue-5: #40a9ff;
|
||||
--blue-6: #1677FF;
|
||||
--blue-7: #096dd9;
|
||||
--blue-8: #0050b3;
|
||||
--blue-9: #003a8c;
|
||||
--blue-10: #002766;
|
||||
|
||||
--green-1: #f6ffed;
|
||||
--green-2: #d9f7be;
|
||||
--green-3: #b7eb8f;
|
||||
--green-4: #95de64;
|
||||
--green-5: #73d13d;
|
||||
--green-6: #52c41a;
|
||||
--green-7: #389e0d;
|
||||
--green-8: #237804;
|
||||
--green-9: #135200;
|
||||
--green-10: #092b00;
|
||||
|
||||
--red-1: #fff1f0;
|
||||
--red-2: #ffccc7;
|
||||
--red-3: #ffa39e;
|
||||
--red-4: #ff7875;
|
||||
--red-5: #ff4d4f;
|
||||
--red-6: #f5222d;
|
||||
--red-7: #cf1322;
|
||||
--red-8: #a8071a;
|
||||
--red-9: #820014;
|
||||
--red-10: #5c0011;
|
||||
|
||||
--gold-1: #fffbe6;
|
||||
--gold-2: #fff1b8;
|
||||
--gold-3: #ffe58f;
|
||||
--gold-4: #ffd666;
|
||||
--gold-5: #ffc53d;
|
||||
--gold-6: #faad14;
|
||||
--gold-7: #d48806;
|
||||
--gold-8: #ad6800;
|
||||
--gold-9: #874d00;
|
||||
--gold-10: #613400;
|
||||
|
||||
--purple-1: #f9f0ff;
|
||||
--purple-2: #efdbff;
|
||||
--purple-3: #d3adf7;
|
||||
--purple-4: #b37feb;
|
||||
--purple-5: #9254de;
|
||||
--purple-6: #722ed1;
|
||||
--purple-7: #531dab;
|
||||
--purple-8: #391085;
|
||||
--purple-9: #22075e;
|
||||
--purple-10: #120338;
|
||||
|
||||
--cyan-1: #e6fffb;
|
||||
--cyan-2: #b5f5ec;
|
||||
--cyan-3: #87e8de;
|
||||
--cyan-4: #5cdbd3;
|
||||
--cyan-5: #36cfc9;
|
||||
--cyan-6: #13c2c2;
|
||||
--cyan-7: #08979c;
|
||||
--cyan-8: #006d75;
|
||||
--cyan-9: #00474f;
|
||||
--cyan-10: #002329;
|
||||
|
||||
--pink-1: #fff0f6;
|
||||
--pink-2: #ffd6e7;
|
||||
--pink-3: #ffadd2;
|
||||
--pink-4: #ff85c0;
|
||||
--pink-5: #f759ab;
|
||||
--pink-6: #eb2f96;
|
||||
--pink-7: #c41d7f;
|
||||
--pink-8: #9e1068;
|
||||
--pink-9: #780650;
|
||||
--pink-10: #520339;
|
||||
|
||||
--orange-1: #fff7e6;
|
||||
--orange-2: #ffe7ba;
|
||||
--orange-3: #ffd591;
|
||||
--orange-4: #ffc069;
|
||||
--orange-5: #ffa940;
|
||||
--orange-6: #fa8c16;
|
||||
--orange-7: #d46b08;
|
||||
--orange-8: #ad4e00;
|
||||
--orange-9: #873800;
|
||||
--orange-10: #612500;
|
||||
|
||||
--primary-radius: #fff;
|
||||
--primary-1: var(--blue-1);
|
||||
--primary-2: var(--blue-2);
|
||||
--primary-3: var(--blue-3);
|
||||
--primary-4: var(--blue-4);
|
||||
--primary-5: var(--blue-5);
|
||||
--primary-6: var(--blue-6);
|
||||
--primary-7: var(--blue-7);
|
||||
--primary-8: var(--blue-8);
|
||||
--primary-9: var(--blue-9);
|
||||
--primary-10: var(--blue-10);
|
||||
|
||||
--primary-color: var(--primary-6);
|
||||
--primary-color-hover: var(--primary-5);
|
||||
--primary-color-active: var(--primary-7);
|
||||
--primary-color-outline: var(--primary-2);
|
||||
|
||||
--info-color: var(--primary-color);
|
||||
--success-color: var(--green-6);
|
||||
--processing-color: var(--blue-6);
|
||||
--highlight-color: var(--red-5);
|
||||
|
||||
--warning-color: var(--gold-6);
|
||||
--warning-color-hover: var(--gold-5);
|
||||
--warning-color-active: var(--gold-7);
|
||||
--warning-color-outline: var(--gold-2);
|
||||
|
||||
--error-color: var(--red-5);
|
||||
--error-color-hover: var(--red-4);
|
||||
--error-color-active: var(--red-7);
|
||||
--error-color-outline: var(--red-2);
|
||||
|
||||
--body-background: #fff;
|
||||
--component-background: #fff;
|
||||
|
||||
--popover-background: @component-background;
|
||||
--popover-customize-border-color: @border-color-split;
|
||||
|
||||
--text-color: fade(@black, 85%);
|
||||
--text-color-secondary: fade(@black, 45%);
|
||||
--text-color-inverse: @white;
|
||||
--icon-color-hover: fade(@black, 75%);
|
||||
--heading-color: fade(@black, 85%);
|
||||
|
||||
--item-hover-bg: #f5f5f5;
|
||||
|
||||
// Border color
|
||||
--border-color-base: hsv(0, 0, 85%);
|
||||
--border-color-split: hsv(0, 0, 94%);
|
||||
//--border-color-inverse: @white;
|
||||
|
||||
//
|
||||
--background-color-light: hsv(0, 0, 98%);
|
||||
--background-color-base: hsv(0, 0, 96%);
|
||||
|
||||
// Disabled states
|
||||
--disabled-color: fade(#000, 25%);
|
||||
--disabled-bg: @background-color-base;
|
||||
--disabled-color-dark: fade(#fff, 35%);
|
||||
|
||||
// Shadow
|
||||
--shadow-color: rgba(195, 62, 62, 0.15);
|
||||
--shadow-color-inverse: @component-background;
|
||||
--box-shadow-base: @shadow-1-down;
|
||||
--shadow-1-up: 0 -2px 8px @shadow-color;
|
||||
--shadow-1-down: 0 2px 8px @shadow-color;
|
||||
--shadow-1-left: -2px 0 8px @shadow-color;
|
||||
--shadow-1-right: 2px 0 8px @shadow-color;
|
||||
--shadow-2: 0 4px 12px @shadow-color;
|
||||
|
||||
// Buttons
|
||||
--btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
--btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
--btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
--btn-default-bg: @component-background;
|
||||
|
||||
--btn-default-ghost-color: @component-background;
|
||||
--btn-default-ghost-border: @component-background;
|
||||
|
||||
--btn-text-hover-bg: rgba(0, 0, 0, 0.018);
|
||||
--btn-text-active-bg: rgba(0, 0, 0, 0.028);
|
||||
|
||||
// Checkbox
|
||||
--checkbox-check-bg: @checkbox-check-color;
|
||||
|
||||
// Descriptions
|
||||
--descriptions-bg: #fafafa;
|
||||
|
||||
// Divider
|
||||
--divider-color: rgba(0, 0, 0, 6%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-submenu-disabled-bg: @component-background;
|
||||
|
||||
// Radio
|
||||
--radio-dot-disabled-color: fade(@black, 20%);
|
||||
--radio-solid-checked-color: @component-background;
|
||||
|
||||
// Radio buttons
|
||||
--radio-disabled-button-checked-bg: coverTintMixin(@black, 90%);
|
||||
--radio-disabled-button-checked-color: @disabled-color;
|
||||
|
||||
// Layout
|
||||
--layout-body-background: #f0f2f5;
|
||||
--layout-header-background: #001529;
|
||||
--layout-trigger-background: #002140;
|
||||
//--layout-sider-background-1: coverTintMixin(#001529, 10%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-bg: @component-background;
|
||||
|
||||
// Input
|
||||
--input-placeholder-color: hsv(0, 0, 75%);
|
||||
--input-icon-color: @input-color;
|
||||
--input-bg: @component-background;
|
||||
--input-number-handler-active-bg: #f4f4f4;
|
||||
--input-icon-hover-color: fade(@black, 85%);
|
||||
|
||||
// Mentions
|
||||
--mentions-dropdown-bg: @component-background;
|
||||
|
||||
// Select
|
||||
--select-dropdown-bg: @component-background;
|
||||
--select-background: @component-background;
|
||||
--select-clear-background: @select-background;
|
||||
--select-selection-item-bg: @background-color-base;
|
||||
--select-selection-item-border-color: @border-color-split;
|
||||
--select-multiple-disabled-background: @input-disabled-bg;
|
||||
--select-multiple-item-disabled-color: #bfbfbf;
|
||||
--select-multiple-item-disabled-border-color: @select-border-color;
|
||||
|
||||
// Cascader
|
||||
--cascader-bg: @component-background;
|
||||
--cascader-menu-bg: @component-background;
|
||||
--cascader-menu-border-color-split: @border-color-split;
|
||||
|
||||
// Tooltip
|
||||
--tooltip-bg: rgba(0, 0, 0, 0.75);
|
||||
|
||||
// Popover
|
||||
--popover-bg: @component-background;
|
||||
|
||||
// Modal
|
||||
--modal-header-bg: @component-background;
|
||||
--modal-header-border-color-split: @border-color-split;
|
||||
--modal-content-bg: @component-background;
|
||||
--modal-footer-border-color-split: @border-color-split;
|
||||
|
||||
// Progress
|
||||
--progress-steps-item-bg: #f3f3f3;
|
||||
|
||||
// Menu
|
||||
--menu-popup-bg: @component-background;
|
||||
--menu-dark-bg: @layout-header-background;
|
||||
--menu-dark-inline-submenu-bg: #000c17;
|
||||
|
||||
// Table
|
||||
--table-header-bg: @background-color-light;
|
||||
--table-header-sort-bg: @background-color-base;
|
||||
--table-body-sort-bg: #fafafa;
|
||||
--table-row-hover-bg: @background-color-light;
|
||||
--table-expanded-row-bg: #fbfbfb;
|
||||
--table-header-cell-split-color: rgba(0, 0, 0, 0.06);
|
||||
--table-header-sort-active-bg: rgba(0, 0, 0, 0.04);
|
||||
--table-header-filter-active-bg: rgba(0, 0, 0, 0.04);
|
||||
--table-filter-btns-bg: inherit;
|
||||
--table-filter-dropdown-bg: @component-background;
|
||||
--table-expand-icon-bg: @component-background;
|
||||
|
||||
// TimePicker
|
||||
--picker-bg: @component-background;
|
||||
--picker-basic-cell-disabled-bg: @disabled-bg;
|
||||
--picker-border-color: @border-color-split;
|
||||
|
||||
// Calendar
|
||||
--calendar-bg: @component-background;
|
||||
--calendar-input-bg: @input-bg;
|
||||
--calendar-border-color: @border-color-inverse;
|
||||
--calendar-full-bg: @calendar-bg;
|
||||
|
||||
// Badge
|
||||
--badge-text-color: @component-background;
|
||||
|
||||
// Rate
|
||||
--rate-star-bg: @border-color-split;
|
||||
|
||||
// Card
|
||||
--card-actions-background: @component-background;
|
||||
--card-skeleton-bg: #cfd8dc;
|
||||
--card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16),
|
||||
0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09);
|
||||
|
||||
// Comment
|
||||
--comment-bg: inherit;
|
||||
--comment-author-time-color: #ccc;
|
||||
--comment-action-hover-color: #595959;
|
||||
|
||||
// BackTop
|
||||
--back-top-bg: @text-color-secondary;
|
||||
--back-top-hover-bg: @text-color;
|
||||
|
||||
// Avatar
|
||||
--avatar-bg: #ccc;
|
||||
|
||||
// Switch
|
||||
--switch-bg: @component-background;
|
||||
|
||||
// Pagination
|
||||
--pagination-item-bg: @component-background;
|
||||
--pagination-item-bg-active: @component-background;
|
||||
--pagination-item-link-bg: @component-background;
|
||||
--pagination-item-disabled-color-active: @white;
|
||||
--pagination-item-disabled-bg-active: darken(hsv(0, 0, 96%), 10%);
|
||||
--pagination-item-input-bg: @component-background;
|
||||
|
||||
// PageHeader
|
||||
--page-header-back-color: #000;
|
||||
--page-header-ghost-bg: inherit;
|
||||
|
||||
// Slider
|
||||
--slider-rail-background-color: @background-color-base;
|
||||
--slider-rail-background-color-hover: #e1e1e1;
|
||||
--slider-dot-border-color: @border-color-split;
|
||||
--slider-dot-border-color-active: @primary-4;
|
||||
|
||||
// Tree
|
||||
--tree-bg: @component-background;
|
||||
|
||||
// Skeleton
|
||||
--skeleton-to-color: coverShadeMixin(@skeleton-color, 5%);
|
||||
|
||||
// Transfer
|
||||
--transfer-item-hover-bg: @item-hover-bg;
|
||||
|
||||
// Message
|
||||
--message-notice-content-bg: @component-background;
|
||||
|
||||
// List
|
||||
--list-customize-card-bg: @component-background;
|
||||
|
||||
// Drawer
|
||||
--drawer-bg: @component-background;
|
||||
|
||||
// Timeline
|
||||
--timeline-color: @border-color-split;
|
||||
--timeline-dot-color: @primary-color;
|
||||
|
||||
// Image
|
||||
--image-preview-operation-disabled-color: rgba(255, 255, 255, 0.45);
|
||||
|
||||
// Steps
|
||||
--steps-nav-arrow-color: fade(@black, 25%);
|
||||
--steps-background: @component-background;
|
||||
|
||||
// Notification
|
||||
--notification-bg: @component-background;
|
||||
|
||||
// 侧边栏
|
||||
--sidebar-light-shadow: 1px 3px 3px rgba(0, 21, 41, 0.08);
|
||||
--sidebar-dark-shadow: 0 4px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
// 顶栏
|
||||
--header-light-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
--header-dark-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
||||
--header-tool-hover-bg: rgba(0, 0, 0, 0.025);
|
||||
--header-dark-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-color-split: rgba(0, 0, 0, 0.08);
|
||||
|
||||
// logo
|
||||
--logo-light-shadow: 1px 2px 3px rgba(0, 21, 41, 0.08);
|
||||
--logo-dark-shadow: 0 3px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
//
|
||||
--gradient-min: fade(#cfd8dc, 20%);
|
||||
--gradient-max: fade(#cfd8dc, 40%);
|
||||
|
||||
// font
|
||||
--font-color: rgba(0, 0, 0, 0.88);
|
||||
// header-bottom
|
||||
--header-bottom: rgba(246, 246, 246, 0.85);
|
||||
// breadcrumb-background
|
||||
--breadcrumb-background: rgba(253, 253, 253, 0.85);
|
||||
// background-color
|
||||
--snowy-background-color: #FFFFFF;
|
||||
// tag-background
|
||||
--tag-background: rgba(253, 253, 253);
|
||||
//
|
||||
--success-fade-20: fade(#52c41a, 20%);
|
||||
--error-fade-20: fade(#ff4d4f, 20%);
|
||||
--warning-fade-20: fade(#faad14, 20%);
|
||||
|
||||
//--primary-fade-20: fade(#1890ff, 20%);
|
||||
--primary-fade-20: var(--primary-2);
|
||||
//--primary-fade-8: fade(#1890ff, 8%);
|
||||
|
||||
--white--fade--65: rgba(255,255,255,.65);
|
||||
--menu-dark-highlight-color: #fff;
|
||||
--btn-primary-color: #fff;
|
||||
--tooltip-color: #fff;
|
||||
--card-above-color: #F0F0F0;
|
||||
--card-above-border-color: #CCCCCC;
|
||||
|
||||
// workfolw design
|
||||
--node-wrap-box-color: rgb(255, 255, 255);
|
||||
--node-wrap-box-before-color: #FFFFFF;
|
||||
--node-wrap-box-before-borde-color: rgb(202, 202, 202);
|
||||
--auto-judge-before-color: #FFF;
|
||||
--cover-line-before-color: #FFF;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
@import 'ant-design-vue/dist/antd';
|
||||
|
||||
@import 'ant-design-vue/es/style/themes/default.less';
|
||||
@import './realdark';
|
||||
@import './default';
|
||||
|
||||
/* 全局 */
|
||||
/*
|
||||
#app, body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f6f8f9;
|
||||
}
|
||||
*/
|
||||
.body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -56,6 +45,7 @@ a, button, input, textarea {
|
|||
padding: 11px 11px 0px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.main-bottom-wrapper {
|
||||
|
@ -71,7 +61,6 @@ a, button, input, textarea {
|
|||
|
||||
/* 双排菜单布局 */
|
||||
.snowy-doublerow-layout-menu {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
line-height: 0;
|
||||
align-items: center;
|
||||
|
@ -86,26 +75,10 @@ a, button, input, textarea {
|
|||
}
|
||||
|
||||
.snowy-doublerow-layout-menu-item-fort-div-span {
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.snowy-doublerow-side-top {
|
||||
border-bottom: 1px solid var(--border-color-split);
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
padding-left: 20px;
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
// 应用主题色
|
||||
.snowy-doublerow-side-top-primary-color {
|
||||
background-color: var(--primary-color);
|
||||
.snowy-title {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.snowy-title{
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
@ -120,7 +93,6 @@ a, button, input, textarea {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* 设置抽屉样式 */
|
||||
.layout-setting {
|
||||
position: fixed;
|
||||
|
@ -147,14 +119,13 @@ a, button, input, textarea {
|
|||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid var(--border-color-split);
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
|
||||
background-color: var(--body-background);
|
||||
|
||||
border-bottom: 1px solid var(--header-bottom);
|
||||
box-shadow: 0 0.4px 0.5px rgb(0 21 41 / 12%);
|
||||
.ant-menu-item{
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
background: var(--snowy-background-color);
|
||||
}
|
||||
// 应用主题色
|
||||
.snowy-header-primary-color {
|
||||
|
@ -197,7 +168,7 @@ a, button, input, textarea {
|
|||
}
|
||||
|
||||
.snowy-header-logo {
|
||||
height: 50px;
|
||||
height: 49px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
|
||||
|
@ -221,105 +192,29 @@ a, button, input, textarea {
|
|||
height: 35px;
|
||||
}
|
||||
|
||||
/* 面包屑 */
|
||||
.admin-ui-topbar {
|
||||
padding-left: 15px
|
||||
.top-snowy-header {
|
||||
background: #001529;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.admin-ui-topbar .left-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.top-snowy-header-light {
|
||||
background: #ffffff;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.admin-ui-topbar .right-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.top-snowy-header-layout {
|
||||
background: var(--primary-color);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.panel-item {
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/*color: var(--font-color);*/
|
||||
}
|
||||
.panel-item:hover {
|
||||
background: var(--header-color-split);
|
||||
}
|
||||
|
||||
/* 多标签 */
|
||||
.snowy-tags {
|
||||
height: 40px;
|
||||
background: var(--component-background);
|
||||
}
|
||||
|
||||
.snowy-tags ul {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.snowy-tags li {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
line-height: 39.5px;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.snowy-tags li::after {
|
||||
content: " ";
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
background-image: linear-gradient(#fff, #e6e6e6);
|
||||
}
|
||||
|
||||
.snowy-tags li a {
|
||||
padding: 0 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.snowy-tags li i {
|
||||
margin-left: 10px;
|
||||
border-radius: 3px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.snowy-tags li i:hover {
|
||||
background: rgba(0, 0, 0, .2);
|
||||
color: @body-background;
|
||||
}
|
||||
|
||||
.snowy-tags li:hover {
|
||||
background: @body-background;
|
||||
}
|
||||
|
||||
.snowy-tags li.active {
|
||||
background: @primary-color;
|
||||
}
|
||||
|
||||
.snowy-tags li.active a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.snowy-tags li.sortable-ghost {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.snowy-header-tags-right {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.contextmenu {
|
||||
position: fixed;
|
||||
width: 200px;
|
||||
|
@ -407,6 +302,10 @@ a, button, input, textarea {
|
|||
.ant-card-extra {
|
||||
padding: 12px 0!important;
|
||||
}
|
||||
.ant-card-head {
|
||||
border-bottom: 0px !important;
|
||||
min-height: 50px !important;
|
||||
}
|
||||
|
||||
/* 重写antdv的表格滚动条 */
|
||||
.ant-table-body, .ant-table-content{
|
||||
|
@ -427,9 +326,9 @@ a, button, input, textarea {
|
|||
}
|
||||
|
||||
.left-span-label {
|
||||
border-left: 4px solid @primary-color;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
font-size: 15px;
|
||||
color: #212121;
|
||||
color: var(--font-color);
|
||||
font-weight: 600;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
@ -464,8 +363,8 @@ body,
|
|||
.admin-ui-main{
|
||||
&::-webkit-scrollbar {
|
||||
/*滚动条整体样式*/
|
||||
width : 0px; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 0px;
|
||||
width : 0; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
height: 0;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
/*滚动条里面小方块*/
|
||||
|
@ -498,3 +397,115 @@ body,
|
|||
display: none!important;
|
||||
}
|
||||
}
|
||||
.ant-modal-close-x .anticon {
|
||||
padding: 2px !important;
|
||||
}
|
||||
.xn-mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.xn-mt4 {
|
||||
margin-top: 4px;
|
||||
}
|
||||
.xn-mg08 {
|
||||
margin: 0 8px;
|
||||
}
|
||||
.xn-fdr {
|
||||
float: right;
|
||||
}
|
||||
.xn-wd {
|
||||
width: 100%;
|
||||
}
|
||||
.xn-wd90 {
|
||||
width: 90px;
|
||||
}
|
||||
.xn-wdcalc-70 {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
.xn-mr8 {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.xn-ht400 {
|
||||
height: 400px;
|
||||
}
|
||||
.xn-wh25 {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
}
|
||||
.xn-ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.xn-pl0 {
|
||||
padding-left: 0px;
|
||||
}
|
||||
.xn-pd8 {
|
||||
padding: 8px;
|
||||
}
|
||||
.xn-pb10 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.xn-color-a0a0a0 {
|
||||
color: #a0a0a0;
|
||||
}
|
||||
.xn-color-d9d9d9 {
|
||||
color: #d9d9d9;
|
||||
}
|
||||
.xn-color-ff4d4f {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
.xn-color-00025 {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.xn-jk-line {
|
||||
width: 188px;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
.xn-findform-line {
|
||||
border: 1px solid var(--border-color-split);
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
.odd {
|
||||
background-color: var(--table-row-hover-bg);
|
||||
}
|
||||
.snowy-theme-dark .odd {
|
||||
background-color: #1d1d1d
|
||||
}
|
||||
// 以下是重写表单设计器的样式
|
||||
.list-main {
|
||||
background: var(--auto-judge-before-color) !important;
|
||||
}
|
||||
.drag-move-box:before {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.drag-move-box>.delete {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.drag-move-box>.copy {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.drag-move-box .show-key-box {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
.left-ul-item:hover {
|
||||
color: var(--primary-color) !important;
|
||||
border: 1px solid var(--primary-color) !important;
|
||||
-webkit-box-shadow: 0 2px 6px var(--primary-color) !important;
|
||||
box-shadow: 0 2px 6px var(--primary-color) !important;
|
||||
}
|
||||
.list-main>.moving:before {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.operating-area a:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
.batch-box>.delete {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.batch-box>.copy {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
.batch-box.active:before {
|
||||
background: var(--primary-color) !important;
|
||||
}
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
@media (max-width: 992px) {
|
||||
// 移动端样式覆盖
|
||||
.el-form-item {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
padding: 0 0 10px;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
width: 90% !important;
|
||||
}
|
||||
|
||||
.el-dialog.is-fullscreen {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.el-drawer.rtl {
|
||||
width: 90% !important;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
|
||||
.admin-ui-main {
|
||||
> .el-container {
|
||||
display: block;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
> .el-container > .el-aside {
|
||||
width: 100% !important;
|
||||
border: 0
|
||||
}
|
||||
}
|
||||
|
||||
.scTable {
|
||||
.el-table,
|
||||
.el-table__body-wrapper {
|
||||
display: block !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.scTable-page {
|
||||
padding: 0 5px !important;
|
||||
}
|
||||
|
||||
.el-pagination__total,
|
||||
.el-pagination__jump,
|
||||
.scTable-do {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.headerPublic {
|
||||
height: auto !important;
|
||||
display: block;
|
||||
|
||||
.left-panel {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.left-panel::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.right-panel .right-panel-search {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.right-panel .right-panel-search > * {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) {
|
||||
border: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > *:first-child:not(.el-aside):not(.el-header) + .el-aside {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-aside {
|
||||
border-bottom: 1px solid #ebeef5 !important;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-container {
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-header {
|
||||
@extend . headerPublic;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-main {
|
||||
border-top: 1px solid #ebeef5;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-main + .el-aside {
|
||||
border-left: 0 !important;
|
||||
border-top: 1px solid #ebeef5;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.admin-ui-main > .el-container > .el-container > .el-header {
|
||||
@extend . headerPublic
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/* USERCENTER */
|
||||
.user-info {
|
||||
padding: 20px 40px;
|
||||
}
|
||||
|
||||
.user-info-top {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-info-top h2 {
|
||||
margin-top: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.user-info-top p {
|
||||
color: #999;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.user-info-top button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.user-info-main {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.user-info-main li {
|
||||
list-style-type: none;
|
||||
line-height: 2;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-info-main li i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.user-info-bottom {
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.user-info-bottom h2 {
|
||||
font-size: 14px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
/*static-table*/
|
||||
.static-table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
margin-bottom: 45px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.static-table th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
color: #909399;
|
||||
font-weight: 400;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.static-table td {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
/*header-tabs*/
|
||||
.header-tabs {
|
||||
padding: 0;
|
||||
display: block;
|
||||
border: 0 !important;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.header-tabs .el-tabs {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.header-tabs .el-tabs__content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-tabs .el-tabs__item {
|
||||
font-size: 12px;
|
||||
}
|
|
@ -3,5 +3,5 @@
|
|||
|
||||
直接 var(--primary-color)
|
||||
|
||||
例如:新建个变量,黑的白的在不同的less中设定好,这个时候就会跟着颜色的主题变化
|
||||
例如:新建个变量,在default.less跟realdark.less中设定好,这个时候就会跟着颜色的主题变化
|
||||
|
||||
|
|
|
@ -11,16 +11,10 @@
|
|||
@functions: ~`(function() {
|
||||
this.fade = function(color, amount) {
|
||||
if (String(color).indexOf('var(') === 0) {
|
||||
/*
|
||||
(var(--primary-color), 7) -> var(--primary-7)
|
||||
*/
|
||||
if (color.indexOf('--primary-color') !== -1 ) {
|
||||
var m = amount > 10 ? amount/10 :amount
|
||||
return color.replace('-color)', '-' + m + ')')
|
||||
}
|
||||
/*
|
||||
(var(--error-color), 70%) ===> var(--error-color--fade-7)
|
||||
*/
|
||||
return color.replace(')', '--fade--' + parseInt(amount) + ')')
|
||||
}
|
||||
return color
|
||||
|
@ -29,403 +23,395 @@
|
|||
}
|
||||
.fade();
|
||||
|
||||
@import 'ant-design-vue/es/style/themes/default.less';
|
||||
|
||||
|
||||
//@import '../themes/default.less';
|
||||
@import 'ant-design-vue/dist/reset.css';
|
||||
|
||||
.snowy-theme-dark {
|
||||
--blue-1: #111d2c;
|
||||
--blue-2: #112a45;
|
||||
--blue-3: #15395b;
|
||||
--blue-4: #164c7e;
|
||||
--blue-5: #1765ad;
|
||||
--blue-6: #177ddc;
|
||||
--blue-7: #3c9ae8;
|
||||
--blue-8: #65b7f3;
|
||||
--blue-9: #8dcff8;
|
||||
--blue-10: #b7e3fa;
|
||||
|
||||
--green-1: #162312;
|
||||
--green-2: #1d3712;
|
||||
--green-3: #274916;
|
||||
--green-4: #306317;
|
||||
--green-5: #3c8618;
|
||||
--green-6: #49aa19;
|
||||
--green-7: #6abe39;
|
||||
--green-8: #8fd460;
|
||||
--green-9: #b2e58b;
|
||||
--green-10: #d5f2bb;
|
||||
|
||||
--red-1: #2a1215;
|
||||
--red-2: #431418;
|
||||
--red-3: #58181c;
|
||||
--red-4: #791a1f;
|
||||
--red-5: #a61d24;
|
||||
--red-6: #f5222d;
|
||||
--red-7: #e84749;
|
||||
--red-8: #f37370;
|
||||
--red-9: #f89f9a;
|
||||
--red-10: #fac8c3;
|
||||
|
||||
--gold-1: #2b2111;
|
||||
--gold-2: #443111;
|
||||
--gold-3: #594214;
|
||||
--gold-4: #7c5914;
|
||||
--gold-5: #aa7714;
|
||||
--gold-6: #d89614;
|
||||
--gold-7: #e8b339;
|
||||
--gold-8: #f3cc62;
|
||||
--gold-9: #f8df8b;
|
||||
--gold-10: #faedb5;
|
||||
|
||||
--purple-1: #1a1325;
|
||||
--purple-2: #24163a;
|
||||
--purple-3: #301c4d;
|
||||
--purple-4: #3e2069;
|
||||
--purple-5: #51258f;
|
||||
--purple-6: #642ab5;
|
||||
--purple-7: #854eca;
|
||||
--purple-8: #ab7ae0;
|
||||
--purple-9: #cda8f0;
|
||||
--purple-10: #ebd7fa;
|
||||
|
||||
--cyan-1: #112123;
|
||||
--cyan-2: #113536;
|
||||
--cyan-3: #144848;
|
||||
--cyan-4: #146262;
|
||||
--cyan-5: #138585;
|
||||
--cyan-6: #13a8a8;
|
||||
--cyan-7: #33bcb7;
|
||||
--cyan-8: #58d1c9;
|
||||
--cyan-9: #84e2d8;
|
||||
--cyan-10: #b2f1e8;
|
||||
|
||||
--pink-1: #291321;
|
||||
--pink-2: #40162f;
|
||||
--pink-3: #551c3b;
|
||||
--pink-4: #75204f;
|
||||
--pink-5: #a02669;
|
||||
--pink-6: #cb2b83;
|
||||
--pink-7: #e0529c;
|
||||
--pink-8: #f37fb7;
|
||||
--pink-9: #f8a8cc;
|
||||
--pink-10: #fad2e3;
|
||||
|
||||
--orange-1: #2b1d11;
|
||||
--orange-2: #442a11;
|
||||
--orange-3: #593815;
|
||||
--orange-4: #7c4a15;
|
||||
--orange-5: #aa6215;
|
||||
--orange-6: #d87a16;
|
||||
--orange-7: #e89a3c;
|
||||
--orange-8: #f3b765;
|
||||
--orange-9: #f8cf8d;
|
||||
--orange-10: #fae3b7;
|
||||
|
||||
--primary-1: var(--blue-1);
|
||||
--primary-2: var(--blue-2);
|
||||
--primary-3: var(--blue-3);
|
||||
--primary-4: var(--blue-4);
|
||||
--primary-5: var(--blue-5);
|
||||
--primary-6: var(--blue-6);
|
||||
--primary-7: var(--blue-7);
|
||||
--primary-8: var(--blue-8);
|
||||
--primary-9: var(--blue-9);
|
||||
--primary-10: var(--blue-10);
|
||||
|
||||
--primary-color: var(--primary-6);
|
||||
--primary-color-hover: var(--primary-5);
|
||||
--primary-color-active: var(--primary-7);
|
||||
--primary-color-outline: var(--primary-2);
|
||||
|
||||
--info-color: var(--primary-color);
|
||||
--success-color: var(--green-6);
|
||||
--processing-color: var(--blue-6);
|
||||
--highlight-color: var(--red-5);
|
||||
|
||||
--warning-color: var(--gold-6);
|
||||
--warning-color-hover: var(--gold-5);
|
||||
--warning-color-active: var(--gold-7);
|
||||
--warning-color-outline: var(--gold-2);
|
||||
|
||||
--error-color: var(--red-5);
|
||||
--error-color-hover: var(--red-4);
|
||||
--error-color-active: var(--red-7);
|
||||
--error-color-outline: var(--red-2);
|
||||
|
||||
--body-background: @black;
|
||||
--component-background: #141414;
|
||||
|
||||
--popover-background: #1f1f1f;
|
||||
--popover-customize-border-color: #3a3a3a;
|
||||
|
||||
--text-color: fade(@white, 85%);
|
||||
--text-color-secondary: fade(@white, 45%);
|
||||
--text-color-inverse: @white;
|
||||
--icon-color-hover: fade(@white, 75%);
|
||||
--heading-color: fade(@white, 85%);
|
||||
|
||||
--item-hover-bg: fade(@white, 8%);
|
||||
|
||||
// Border color
|
||||
--border-color-base: #434343;
|
||||
--border-color-split: #303030;
|
||||
//--border-color-inverse: @black;
|
||||
|
||||
//
|
||||
--background-color-light: fade(@white, 4%);
|
||||
--background-color-base: fade(@white, 8%);
|
||||
|
||||
// Disabled states
|
||||
--disabled-color: fade(@white, 30%);
|
||||
--disabled-bg: @background-color-base;
|
||||
--disabled-color-dark: fade(@white, 30%);
|
||||
|
||||
// Shadow
|
||||
--shadow-color: rgba(0, 0, 0, 0.45);
|
||||
--shadow-color-inverse: @component-background;
|
||||
--box-shadow-base: @shadow-2;
|
||||
--shadow-1-up: 0 -6px 16px -8px rgba(0, 0, 0, 0.32),
|
||||
0 -9px 28px 0 rgba(0, 0, 0, 0.2), 0 -12px 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-1-down: 0 6px 16px -8px rgba(0, 0, 0, 0.32),
|
||||
0 9px 28px 0 rgba(0, 0, 0, 0.2), 0 12px 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-1-right: 6px 0 16px -8px rgba(0, 0, 0, 0.32),
|
||||
9px 0 28px 0 rgba(0, 0, 0, 0.2), 12px 0 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-2: 0 3px 6px -4px rgba(0, 0, 0, 0.48),
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 9px 28px 8px rgba(0, 0, 0, 0.2);
|
||||
|
||||
// Buttons
|
||||
--btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
--btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
--btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
--btn-default-bg: transparent;
|
||||
|
||||
--btn-default-ghost-color: @text-color;
|
||||
--btn-default-ghost-border: fade(@white, 25%);
|
||||
|
||||
--btn-text-hover-bg: rgba(255, 255, 255, 0.03);
|
||||
--btn-text-active-bg: rgba(255, 255, 255, 0.04);
|
||||
|
||||
// Checkbox
|
||||
--checkbox-check-bg: transparent;
|
||||
|
||||
// Descriptions
|
||||
--descriptions-bg: @background-color-light;
|
||||
|
||||
// Divider
|
||||
--divider-color: rgba(255, 255, 255, 12%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-submenu-disabled-bg: transparent;
|
||||
|
||||
// Radio
|
||||
--radio-dot-disabled-color: fade(@white, 20%);
|
||||
--radio-solid-checked-color: @white;
|
||||
|
||||
// Radio buttons
|
||||
--radio-disabled-button-checked-bg: fade(@white, 20%);
|
||||
--radio-disabled-button-checked-color: @disabled-color;
|
||||
|
||||
// Layout
|
||||
--layout-body-background: @body-background;
|
||||
--layout-header-background: @popover-background;
|
||||
--layout-trigger-background: #262626;
|
||||
//--layout-sider-background-1: tint(#1f1f1f, 10%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-bg: @popover-background;
|
||||
|
||||
// Input
|
||||
--input-placeholder-color: fade(@white, 30%);
|
||||
--input-icon-color: fade(@white, 30%);
|
||||
--input-bg: transparent;
|
||||
--input-number-handler-active-bg: @item-hover-bg;
|
||||
--input-icon-hover-color: fade(@white, 85%);
|
||||
|
||||
// Mentions
|
||||
--mentions-dropdown-bg: @popover-background;
|
||||
|
||||
// Select
|
||||
--select-dropdown-bg: @popover-background;
|
||||
--select-background: transparent;
|
||||
--select-clear-background: @component-background;
|
||||
--select-selection-item-bg: fade(@white, 8);
|
||||
--select-selection-item-border-color: @border-color-split;
|
||||
--select-multiple-disabled-background: @component-background;
|
||||
--select-multiple-item-disabled-color: #595959;
|
||||
--select-multiple-item-disabled-border-color: @popover-background;
|
||||
|
||||
// Cascader
|
||||
--cascader-bg: transparent;
|
||||
--cascader-menu-bg: @popover-background;
|
||||
--cascader-menu-border-color-split: @border-color-split;
|
||||
|
||||
// Tooltip
|
||||
--tooltip-bg: #434343;
|
||||
|
||||
// Popover
|
||||
--popover-bg: @popover-background;
|
||||
|
||||
// Modal
|
||||
--modal-header-bg: @popover-background;
|
||||
--modal-header-border-color-split: @border-color-split;
|
||||
--modal-content-bg: @popover-background;
|
||||
--modal-footer-border-color-split: @border-color-split;
|
||||
|
||||
// Progress
|
||||
--progress-steps-item-bg: fade(@white, 8%);
|
||||
|
||||
// Menu
|
||||
--menu-popup-bg: @popover-background;
|
||||
--menu-dark-bg: @popover-background;
|
||||
--menu-dark-inline-submenu-bg: @component-background;
|
||||
|
||||
// Table
|
||||
--table-header-bg: #1d1d1d;
|
||||
--table-header-sort-bg: #262626;
|
||||
--table-body-sort-bg: fade(@white, 1%);
|
||||
--table-row-hover-bg: #262626;
|
||||
--table-expanded-row-bg: @table-header-bg;
|
||||
--table-header-cell-split-color: fade(@white, 8%);
|
||||
--table-header-sort-active-bg: #303030;
|
||||
--table-header-filter-active-bg: #434343;
|
||||
--table-filter-btns-bg: @popover-background;
|
||||
--table-filter-dropdown-bg: @popover-background;
|
||||
--table-expand-icon-bg: transparent;
|
||||
|
||||
// TimePicker
|
||||
--picker-bg: transparent;
|
||||
--picker-basic-cell-disabled-bg: #303030;
|
||||
--picker-border-color: @border-color-split;
|
||||
|
||||
// Calendar
|
||||
--calendar-bg: @popover-background;
|
||||
--calendar-input-bg: @calendar-bg;
|
||||
--calendar-border-color: transparent;
|
||||
--calendar-full-bg: @component-background;
|
||||
|
||||
// Badge
|
||||
--badge-text-color: @white;
|
||||
|
||||
// Rate
|
||||
--rate-star-bg: fade(@white, 12%);
|
||||
|
||||
// Card
|
||||
--card-actions-background: @component-background;
|
||||
--card-skeleton-bg: #303030;
|
||||
--card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.64),
|
||||
0 3px 6px 0 rgba(0, 0, 0, 0.48), 0 5px 12px 4px rgba(0, 0, 0, 0.36);
|
||||
|
||||
// Comment
|
||||
--comment-bg: transparent;
|
||||
--comment-author-time-color: fade(@white, 30%);
|
||||
--comment-action-hover-color: fade(@white, 65%);
|
||||
|
||||
// BackTop
|
||||
--back-top-bg: var(--tooltip-bg);
|
||||
--back-top-hover-bg: var(--border-color-split);
|
||||
|
||||
// Avatar
|
||||
--avatar-bg: fade(@white, 30%);
|
||||
|
||||
// Switch
|
||||
--switch-bg: @white;
|
||||
|
||||
// Pagination
|
||||
--pagination-item-bg: transparent;
|
||||
--pagination-item-bg-active: transparent;
|
||||
--pagination-item-link-bg: transparent;
|
||||
--pagination-item-disabled-color-active: @black;
|
||||
--pagination-item-disabled-bg-active: fade(@white, 25%);
|
||||
--pagination-item-input-bg: @pagination-item-bg;
|
||||
|
||||
// PageHeader
|
||||
--page-header-back-color: @icon-color;
|
||||
--page-header-ghost-bg: transparent;
|
||||
|
||||
// Slider
|
||||
--slider-rail-background-color: #262626;
|
||||
--slider-rail-background-color-hover: @border-color-base;
|
||||
--slider-dot-border-color: @border-color-split;
|
||||
--slider-dot-border-color-active: @primary-4;
|
||||
|
||||
// Tree
|
||||
--tree-bg: transparent;
|
||||
|
||||
// Skeleton
|
||||
--skeleton-to-color: fade(@white, 16%);
|
||||
|
||||
// Transfer
|
||||
--transfer-item-hover-bg: #262626;
|
||||
|
||||
// Message
|
||||
--message-notice-content-bg: @popover-background;
|
||||
|
||||
// List
|
||||
--list-customize-card-bg: transparent;
|
||||
|
||||
// Drawer
|
||||
--drawer-bg: @popover-background;
|
||||
|
||||
// Timeline
|
||||
--timeline-color: @border-color-split;
|
||||
--timeline-dot-color: @primary-color;
|
||||
|
||||
// Steps
|
||||
--steps-nav-arrow-color: fade(@white, 20%);
|
||||
--steps-background: transparent;
|
||||
|
||||
// Notification
|
||||
--notification-bg: @popover-background;
|
||||
|
||||
// 侧边栏
|
||||
--sidebar-light-shadow: 0 4px 4px rgba(0, 0, 0, 0.6);
|
||||
--sidebar-dark-shadow: 0 4px 4px rgba(0, 0, 0, 0.6);
|
||||
|
||||
// 顶栏
|
||||
--header-light-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
||||
--header-dark-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
||||
--header-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-dark-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-color-split: rgba(255, 255, 255, 0.15);
|
||||
|
||||
// logo
|
||||
--logo-light-shadow: 0 3px 4px rgba(0, 0, 0, 0.6);
|
||||
--logo-dark-shadow: 0 3px 4px rgba(0, 0, 0, 0.6);
|
||||
|
||||
//
|
||||
--gradient-min: fade(#303030, 20%);
|
||||
--gradient-max: fade(#303030, 40%);
|
||||
|
||||
//
|
||||
--primary-fade-20: var(--primary-2);
|
||||
|
||||
--black--fade--85: rgba(255, 255, 255, 0.85);
|
||||
--switch-shadow-color: 0 2px 4px rgb(0 35 11 / 20%);
|
||||
|
||||
// workfolw design
|
||||
--node-wrap-box-color: #303030;
|
||||
--node-wrap-box-before-color: rgba(255, 255, 255, 0.09); // 箭头旁边
|
||||
--node-wrap-box-before-borde-color: rgba(255, 255, 255, 0.09); // 箭头
|
||||
--auto-judge-before-color: @component-background; // 箭头背景
|
||||
}
|
||||
|
||||
// 表单设计器主题覆盖
|
||||
.snowy-theme-dark{
|
||||
--hint-color: #888;
|
||||
|
||||
.form-designer-container-9136076486841527{
|
||||
--form-designer-primary-color: var(--primary-6);
|
||||
--primary-background-color: @component-background;
|
||||
--layout-background-color: fade(#9867f7, 12%);
|
||||
--layout-hover-bg-color: fade(#9867f7, 24%);
|
||||
|
||||
--title-text-color: fade(@black, 85%);
|
||||
--border-color: var(--border-color-split);
|
||||
|
||||
--component-background: #141414;
|
||||
|
||||
}
|
||||
--blue-1: #111d2c;
|
||||
--blue-2: #112a45;
|
||||
--blue-3: #15395b;
|
||||
--blue-4: #164c7e;
|
||||
--blue-5: #1765ad;
|
||||
--blue-6: #177ddc;
|
||||
--blue-7: #3c9ae8;
|
||||
--blue-8: #65b7f3;
|
||||
--blue-9: #8dcff8;
|
||||
--blue-10: #b7e3fa;
|
||||
|
||||
--green-1: #162312;
|
||||
--green-2: #1d3712;
|
||||
--green-3: #274916;
|
||||
--green-4: #306317;
|
||||
--green-5: #3c8618;
|
||||
--green-6: #49aa19;
|
||||
--green-7: #6abe39;
|
||||
--green-8: #8fd460;
|
||||
--green-9: #b2e58b;
|
||||
--green-10: #d5f2bb;
|
||||
|
||||
--red-1: #2a1215;
|
||||
--red-2: #431418;
|
||||
--red-3: #58181c;
|
||||
--red-4: #791a1f;
|
||||
--red-5: #a61d24;
|
||||
--red-6: #f5222d;
|
||||
--red-7: #e84749;
|
||||
--red-8: #f37370;
|
||||
--red-9: #f89f9a;
|
||||
--red-10: #fac8c3;
|
||||
|
||||
--gold-1: #2b2111;
|
||||
--gold-2: #443111;
|
||||
--gold-3: #594214;
|
||||
--gold-4: #7c5914;
|
||||
--gold-5: #aa7714;
|
||||
--gold-6: #d89614;
|
||||
--gold-7: #e8b339;
|
||||
--gold-8: #f3cc62;
|
||||
--gold-9: #f8df8b;
|
||||
--gold-10: #faedb5;
|
||||
|
||||
--purple-1: #1a1325;
|
||||
--purple-2: #24163a;
|
||||
--purple-3: #301c4d;
|
||||
--purple-4: #3e2069;
|
||||
--purple-5: #51258f;
|
||||
--purple-6: #642ab5;
|
||||
--purple-7: #854eca;
|
||||
--purple-8: #ab7ae0;
|
||||
--purple-9: #cda8f0;
|
||||
--purple-10: #ebd7fa;
|
||||
|
||||
--cyan-1: #112123;
|
||||
--cyan-2: #113536;
|
||||
--cyan-3: #144848;
|
||||
--cyan-4: #146262;
|
||||
--cyan-5: #138585;
|
||||
--cyan-6: #13a8a8;
|
||||
--cyan-7: #33bcb7;
|
||||
--cyan-8: #58d1c9;
|
||||
--cyan-9: #84e2d8;
|
||||
--cyan-10: #b2f1e8;
|
||||
|
||||
--pink-1: #291321;
|
||||
--pink-2: #40162f;
|
||||
--pink-3: #551c3b;
|
||||
--pink-4: #75204f;
|
||||
--pink-5: #a02669;
|
||||
--pink-6: #cb2b83;
|
||||
--pink-7: #e0529c;
|
||||
--pink-8: #f37fb7;
|
||||
--pink-9: #f8a8cc;
|
||||
--pink-10: #fad2e3;
|
||||
|
||||
--orange-1: #2b1d11;
|
||||
--orange-2: #442a11;
|
||||
--orange-3: #593815;
|
||||
--orange-4: #7c4a15;
|
||||
--orange-5: #aa6215;
|
||||
--orange-6: #d87a16;
|
||||
--orange-7: #e89a3c;
|
||||
--orange-8: #f3b765;
|
||||
--orange-9: #f8cf8d;
|
||||
--orange-10: #fae3b7;
|
||||
|
||||
--primary-radius: #141414;
|
||||
--primary-1: var(--blue-1);
|
||||
--primary-2: var(--blue-2);
|
||||
--primary-3: var(--blue-3);
|
||||
--primary-4: var(--blue-4);
|
||||
--primary-5: var(--blue-5);
|
||||
--primary-6: var(--blue-6);
|
||||
--primary-7: var(--blue-7);
|
||||
--primary-8: var(--blue-8);
|
||||
--primary-9: var(--blue-9);
|
||||
--primary-10: var(--blue-10);
|
||||
|
||||
--primary-color: var(--primary-6);
|
||||
--primary-color-hover: var(--primary-5);
|
||||
--primary-color-active: var(--primary-7);
|
||||
--primary-color-outline: var(--primary-2);
|
||||
|
||||
--info-color: var(--primary-color);
|
||||
--success-color: var(--green-6);
|
||||
--processing-color: var(--blue-6);
|
||||
--highlight-color: var(--red-5);
|
||||
|
||||
--warning-color: var(--gold-6);
|
||||
--warning-color-hover: var(--gold-5);
|
||||
--warning-color-active: var(--gold-7);
|
||||
--warning-color-outline: var(--gold-2);
|
||||
|
||||
--error-color: var(--red-5);
|
||||
--error-color-hover: var(--red-4);
|
||||
--error-color-active: var(--red-7);
|
||||
--error-color-outline: var(--red-2);
|
||||
|
||||
--body-background: @black;
|
||||
--component-background: #141414;
|
||||
--popover-background: #1f1f1f;
|
||||
--popover-customize-border-color: #3a3a3a;
|
||||
|
||||
--text-color: fade(@white, 85%);
|
||||
--text-color-secondary: fade(@white, 45%);
|
||||
--text-color-inverse: @white;
|
||||
--icon-color-hover: fade(@white, 75%);
|
||||
--heading-color: fade(@white, 85%);
|
||||
|
||||
--item-hover-bg: fade(@white, 8%);
|
||||
|
||||
// Border color
|
||||
--border-color-base: #434343;
|
||||
--border-color-split: #303030;
|
||||
//--border-color-inverse: @black;
|
||||
|
||||
//
|
||||
--background-color-light: fade(@white, 4%);
|
||||
--background-color-base: fade(@white, 8%);
|
||||
|
||||
// Disabled states
|
||||
--disabled-color: fade(@white, 30%);
|
||||
--disabled-bg: @background-color-base;
|
||||
--disabled-color-dark: fade(@white, 30%);
|
||||
|
||||
// Shadow
|
||||
--shadow-color: rgba(0, 0, 0, 0.45);
|
||||
--shadow-color-inverse: @component-background;
|
||||
--box-shadow-base: @shadow-2;
|
||||
--shadow-1-up: 0 -6px 16px -8px rgba(0, 0, 0, 0.32),
|
||||
0 -9px 28px 0 rgba(0, 0, 0, 0.2), 0 -12px 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-1-down: 0 6px 16px -8px rgba(0, 0, 0, 0.32),
|
||||
0 9px 28px 0 rgba(0, 0, 0, 0.2), 0 12px 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-1-right: 6px 0 16px -8px rgba(0, 0, 0, 0.32),
|
||||
9px 0 28px 0 rgba(0, 0, 0, 0.2), 12px 0 48px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-2: 0 3px 6px -4px rgba(0, 0, 0, 0.48),
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 9px 28px 8px rgba(0, 0, 0, 0.2);
|
||||
|
||||
// Buttons
|
||||
--btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
|
||||
--btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
--btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
--btn-default-bg: transparent;
|
||||
|
||||
--btn-default-ghost-color: @text-color;
|
||||
--btn-default-ghost-border: fade(@white, 25%);
|
||||
|
||||
--btn-text-hover-bg: rgba(255, 255, 255, 0.03);
|
||||
--btn-text-active-bg: rgba(255, 255, 255, 0.04);
|
||||
|
||||
// Checkbox
|
||||
--checkbox-check-bg: transparent;
|
||||
|
||||
// Descriptions
|
||||
--descriptions-bg: @background-color-light;
|
||||
|
||||
// Divider
|
||||
--divider-color: rgba(255, 255, 255, 12%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-submenu-disabled-bg: transparent;
|
||||
|
||||
// Radio
|
||||
--radio-dot-disabled-color: fade(@white, 20%);
|
||||
--radio-solid-checked-color: @white;
|
||||
|
||||
// Radio buttons
|
||||
--radio-disabled-button-checked-bg: fade(@white, 20%);
|
||||
--radio-disabled-button-checked-color: @disabled-color;
|
||||
|
||||
// Layout
|
||||
--layout-body-background: @body-background;
|
||||
--layout-header-background: @popover-background;
|
||||
--layout-trigger-background: #262626;
|
||||
//--layout-sider-background-1: tint(#1f1f1f, 10%);
|
||||
|
||||
// Dropdown 有两个
|
||||
--dropdown-menu-bg: @popover-background;
|
||||
|
||||
// Input
|
||||
--input-placeholder-color: fade(@white, 30%);
|
||||
--input-icon-color: fade(@white, 30%);
|
||||
--input-bg: transparent;
|
||||
--input-number-handler-active-bg: @item-hover-bg;
|
||||
--input-icon-hover-color: fade(@white, 85%);
|
||||
|
||||
// Mentions
|
||||
--mentions-dropdown-bg: @popover-background;
|
||||
|
||||
// Select
|
||||
--select-dropdown-bg: @popover-background;
|
||||
--select-background: transparent;
|
||||
--select-clear-background: @component-background;
|
||||
--select-selection-item-bg: fade(@white, 8);
|
||||
--select-selection-item-border-color: @border-color-split;
|
||||
--select-multiple-disabled-background: @component-background;
|
||||
--select-multiple-item-disabled-color: #595959;
|
||||
--select-multiple-item-disabled-border-color: @popover-background;
|
||||
|
||||
// Cascader
|
||||
--cascader-bg: transparent;
|
||||
--cascader-menu-bg: @popover-background;
|
||||
--cascader-menu-border-color-split: @border-color-split;
|
||||
|
||||
// Tooltip
|
||||
--tooltip-bg: #434343;
|
||||
|
||||
// Popover
|
||||
--popover-bg: @popover-background;
|
||||
|
||||
// Modal
|
||||
--modal-header-bg: @popover-background;
|
||||
--modal-header-border-color-split: @border-color-split;
|
||||
--modal-content-bg: @popover-background;
|
||||
--modal-footer-border-color-split: @border-color-split;
|
||||
|
||||
// Progress
|
||||
--progress-steps-item-bg: fade(@white, 8%);
|
||||
|
||||
// Menu
|
||||
--menu-popup-bg: @popover-background;
|
||||
--menu-dark-bg: @popover-background;
|
||||
--menu-dark-inline-submenu-bg: @component-background;
|
||||
|
||||
// Table
|
||||
--table-header-bg: #1d1d1d;
|
||||
--table-header-sort-bg: #262626;
|
||||
--table-body-sort-bg: fade(@white, 1%);
|
||||
--table-row-hover-bg: #262626;
|
||||
--table-expanded-row-bg: @table-header-bg;
|
||||
--table-header-cell-split-color: fade(@white, 8%);
|
||||
--table-header-sort-active-bg: #303030;
|
||||
--table-header-filter-active-bg: #434343;
|
||||
--table-filter-btns-bg: @popover-background;
|
||||
--table-filter-dropdown-bg: @popover-background;
|
||||
--table-expand-icon-bg: transparent;
|
||||
|
||||
// TimePicker
|
||||
--picker-bg: transparent;
|
||||
--picker-basic-cell-disabled-bg: #303030;
|
||||
--picker-border-color: @border-color-split;
|
||||
|
||||
// Calendar
|
||||
--calendar-bg: @popover-background;
|
||||
--calendar-input-bg: @calendar-bg;
|
||||
--calendar-border-color: transparent;
|
||||
--calendar-full-bg: @component-background;
|
||||
|
||||
// Badge
|
||||
--badge-text-color: @white;
|
||||
|
||||
// Rate
|
||||
--rate-star-bg: fade(@white, 12%);
|
||||
|
||||
// Card
|
||||
--card-actions-background: @component-background;
|
||||
--card-skeleton-bg: #303030;
|
||||
--card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.64),
|
||||
0 3px 6px 0 rgba(0, 0, 0, 0.48), 0 5px 12px 4px rgba(0, 0, 0, 0.36);
|
||||
|
||||
// Comment
|
||||
--comment-bg: transparent;
|
||||
--comment-author-time-color: fade(@white, 30%);
|
||||
--comment-action-hover-color: fade(@white, 65%);
|
||||
|
||||
// BackTop
|
||||
--back-top-bg: var(--tooltip-bg);
|
||||
--back-top-hover-bg: var(--border-color-split);
|
||||
|
||||
// Avatar
|
||||
--avatar-bg: fade(@white, 30%);
|
||||
|
||||
// Switch
|
||||
--switch-bg: @white;
|
||||
|
||||
// Pagination
|
||||
--pagination-item-bg: transparent;
|
||||
--pagination-item-bg-active: transparent;
|
||||
--pagination-item-link-bg: transparent;
|
||||
--pagination-item-disabled-color-active: @black;
|
||||
--pagination-item-disabled-bg-active: fade(@white, 25%);
|
||||
--pagination-item-input-bg: @pagination-item-bg;
|
||||
|
||||
// PageHeader
|
||||
--page-header-back-color: @icon-color;
|
||||
--page-header-ghost-bg: transparent;
|
||||
|
||||
// Slider
|
||||
--slider-rail-background-color: #262626;
|
||||
--slider-rail-background-color-hover: @border-color-base;
|
||||
--slider-dot-border-color: @border-color-split;
|
||||
--slider-dot-border-color-active: @primary-4;
|
||||
|
||||
// Tree
|
||||
--tree-bg: transparent;
|
||||
|
||||
// Skeleton
|
||||
--skeleton-to-color: fade(@white, 16%);
|
||||
|
||||
// Transfer
|
||||
--transfer-item-hover-bg: #262626;
|
||||
|
||||
// Message
|
||||
--message-notice-content-bg: @popover-background;
|
||||
|
||||
// List
|
||||
--list-customize-card-bg: transparent;
|
||||
|
||||
// Drawer
|
||||
--drawer-bg: @popover-background;
|
||||
|
||||
// Timeline
|
||||
--timeline-color: @border-color-split;
|
||||
--timeline-dot-color: @primary-color;
|
||||
|
||||
// Steps
|
||||
--steps-nav-arrow-color: fade(@white, 20%);
|
||||
--steps-background: transparent;
|
||||
|
||||
// Notification
|
||||
--notification-bg: @popover-background;
|
||||
|
||||
// 侧边栏
|
||||
--sidebar-light-shadow: 0 4px 4px rgba(0, 0, 0, 0.6);
|
||||
--sidebar-dark-shadow: 0 4px 4px rgba(0, 0, 0, 0.6);
|
||||
|
||||
// 顶栏
|
||||
--header-light-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
||||
--header-dark-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
|
||||
--header-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-dark-tool-hover-bg: rgba(255, 255, 255, 0.05);
|
||||
--header-color-split: rgba(255, 255, 255, 0.15);
|
||||
|
||||
// logo
|
||||
--logo-light-shadow: 0 3px 4px rgba(0, 0, 0, 0.6);
|
||||
--logo-dark-shadow: 0 3px 4px rgba(0, 0, 0, 0.6);
|
||||
|
||||
//
|
||||
--gradient-min: fade(#303030, 20%);
|
||||
--gradient-max: fade(#303030, 40%);
|
||||
|
||||
// font
|
||||
--font-color: #FFFFFF;
|
||||
// header-bottom
|
||||
--header-bottom: rgba(54, 54, 54, 0.6);
|
||||
// breadcrumb-background
|
||||
--breadcrumb-background: rgba(54, 54, 54, 0.6);
|
||||
// background-color
|
||||
--snowy-background-color: #141414;
|
||||
// tag-background
|
||||
--tag-background: rgba(56, 56, 56);
|
||||
//
|
||||
--primary-fade-20: var(--primary-2);
|
||||
|
||||
--black--fade--85: rgba(255, 255, 255, 0.85);
|
||||
--switch-shadow-color: 0 2px 4px rgb(0 35 11 / 20%);
|
||||
--card-above-color: #303030;
|
||||
--card-above-border-color: #484848;
|
||||
|
||||
// workfolw design
|
||||
--node-wrap-box-color: #303030;
|
||||
--node-wrap-box-before-color: rgba(255, 255, 255, 0.09); // 箭头旁边
|
||||
--node-wrap-box-before-borde-color: rgba(255, 255, 255, 0.09); // 箭头
|
||||
--auto-judge-before-color: #141414; // 箭头背景
|
||||
--cover-line-before-color: #141414;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import { generate } from '@ant-design/colors'
|
||||
import tool from '../utils/tool'
|
||||
import config from '../config'
|
||||
import { ThemeModeEnum } from './enum'
|
||||
import { themeEnum } from '@/layout/enum/themeEnum'
|
||||
|
||||
const changeColor = (newPrimaryColor, theme, darkClass = 'snowy-theme-dark') => {
|
||||
return new Promise((resolve) => {
|
||||
|
@ -20,7 +20,7 @@ const changeColor = (newPrimaryColor, theme, darkClass = 'snowy-theme-dark') =>
|
|||
if (themeEle && themeEle.parentNode) {
|
||||
themeEle.parentNode.removeChild(themeEle)
|
||||
}
|
||||
const isRealDark = theme === ThemeModeEnum.REAL_DARK
|
||||
const isRealDark = theme === themeEnum.REAL_DARK
|
||||
if (newPrimaryColor) {
|
||||
const colors = generate(newPrimaryColor, isRealDark ? { theme: 'dark' } : {})
|
||||
const rootClass = isRealDark ? `.${darkClass}` : ':root'
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
/*
|
||||
/**
|
||||
* @Descripttion: 工具集
|
||||
* @version: 1.1
|
||||
* @LastEditors: yubaoshan
|
||||
|
@ -20,10 +20,18 @@ const tool = {}
|
|||
tool.data = {
|
||||
set(table, settings) {
|
||||
const _set = JSON.stringify(settings)
|
||||
return localStorage.setItem(table, _set)
|
||||
const SNOWYSTRING = table.slice(0, 6) === 'SNOWY_' && table !== 'SNOWY_SYS_BASE_CONFIG'
|
||||
if (SNOWYSTRING) {
|
||||
let localSetting = JSON.parse(localStorage.getItem('SNOWY_SETTING')) || {}
|
||||
let newSetting = {}
|
||||
newSetting[table] = _set
|
||||
return localStorage.setItem('SNOWY_SETTING', JSON.stringify(Object.assign(localSetting, newSetting)))
|
||||
} else return localStorage.setItem(table, _set)
|
||||
},
|
||||
get(table) {
|
||||
let data = localStorage.getItem(table)
|
||||
const SNOWYSTRING = table.slice(0, 6) === 'SNOWY_' && table !== 'SNOWY_SYS_BASE_CONFIG'
|
||||
const SNOWY_SETTING = JSON.parse(localStorage.getItem('SNOWY_SETTING')) || {}
|
||||
let data = SNOWYSTRING ? SNOWY_SETTING[table] : localStorage.getItem(table)
|
||||
try {
|
||||
data = JSON.parse(data)
|
||||
} catch (err) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<a-form-item name="email">
|
||||
<a-input v-model:value="emailFormData.email" :placeholder="$t('login.emailPlaceholder')" size="large">
|
||||
<template #prefix>
|
||||
<mail-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<mail-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
@ -16,12 +16,12 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<mail-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<mail-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<a-button size="large" style="width: 100%" @click="getEmailValidCode" :disabled="state.smsSendBtn">{{
|
||||
<a-button size="large" class="xn-wd" @click="getEmailValidCode" :disabled="state.smsSendBtn">{{
|
||||
(!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s'
|
||||
}}</a-button>
|
||||
</a-col>
|
||||
|
@ -35,7 +35,7 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<LockOutlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
@ -43,10 +43,10 @@
|
|||
<a-form-item>
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="7">
|
||||
<a-button style="width: 100%" round size="large" href="/login">{{ $t('login.backLogin') }}</a-button>
|
||||
<a-button class="xn-wd" round size="large" href="/login">{{ $t('login.backLogin') }}</a-button>
|
||||
</a-col>
|
||||
<a-col :span="17">
|
||||
<a-button type="primary" style="width: 100%" :loading="islogin" round size="large" @click="submitReset">{{
|
||||
<a-button type="primary" class="xn-wd" :loading="islogin" round size="large" @click="submitReset">{{
|
||||
$t('login.restPassword')
|
||||
}}</a-button>
|
||||
</a-col>
|
||||
|
@ -54,7 +54,7 @@
|
|||
</a-form-item>
|
||||
</a-form>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
:width="400"
|
||||
:title="$t('login.machineValidation')"
|
||||
@cancel="handleCancel"
|
||||
|
@ -70,16 +70,12 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<verified-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<img
|
||||
:src="validCodeBase64"
|
||||
style="border: 1px solid var(--border-color-split); cursor: pointer; width: 100%; height: 40px"
|
||||
@click="getPhonePicCaptcha"
|
||||
/>
|
||||
<img :src="validCodeBase64" class="xn-findform-line" @click="getPhonePicCaptcha" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
|
@ -121,23 +117,26 @@
|
|||
formRules.value.emailValidCode = [required(), rules.number]
|
||||
formRules.value.newPassword = [required()]
|
||||
|
||||
emailResetFormRef.value.validate().then(() => {
|
||||
emailFormData.value.validCode = emailFormData.value.emailValidCode
|
||||
emailFormData.value.validCodeReqNo = emailValidCodeReqNo.value
|
||||
emailFormData.value.newPassword = smCrypto.doSm2Encrypt(emailFormData.value.newPassword)
|
||||
islogin.value = true
|
||||
userCenterApi
|
||||
.userFindPasswordByEmail(emailFormData.value)
|
||||
.then(() => {
|
||||
router.replace({
|
||||
path: '/'
|
||||
emailResetFormRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
emailFormData.value.validCode = emailFormData.value.emailValidCode
|
||||
emailFormData.value.validCodeReqNo = emailValidCodeReqNo.value
|
||||
emailFormData.value.newPassword = smCrypto.doSm2Encrypt(emailFormData.value.newPassword)
|
||||
islogin.value = true
|
||||
userCenterApi
|
||||
.userFindPasswordByEmail(emailFormData.value)
|
||||
.then(() => {
|
||||
router.replace({
|
||||
path: '/'
|
||||
})
|
||||
message.success('找回成功')
|
||||
})
|
||||
message.success('找回成功')
|
||||
})
|
||||
.finally(() => {
|
||||
islogin.value = false
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
islogin.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 弹框的
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<a-form-item name="phone">
|
||||
<a-input v-model:value="phoneFormData.phone" :placeholder="$t('login.phonePlaceholder')" size="large">
|
||||
<template #prefix>
|
||||
<mobile-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<mobile-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
@ -16,12 +16,12 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<mail-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<mail-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">{{
|
||||
<a-button size="large" class="xn-wd" @click="getPhoneValidCode" :disabled="state.smsSendBtn">{{
|
||||
(!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s'
|
||||
}}</a-button>
|
||||
</a-col>
|
||||
|
@ -35,7 +35,7 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<LockOutlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
@ -43,10 +43,10 @@
|
|||
<a-form-item>
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="7">
|
||||
<a-button style="width: 100%" round size="large" href="/login">{{ $t('login.backLogin') }}</a-button>
|
||||
<a-button class="xn-wd" round size="large" href="/login">{{ $t('login.backLogin') }}</a-button>
|
||||
</a-col>
|
||||
<a-col :span="17">
|
||||
<a-button type="primary" style="width: 100%" :loading="islogin" round size="large" @click="submitReset">{{
|
||||
<a-button type="primary" class="xn-wd" :loading="islogin" round size="large" @click="submitReset">{{
|
||||
$t('login.restPassword')
|
||||
}}</a-button>
|
||||
</a-col>
|
||||
|
@ -54,7 +54,7 @@
|
|||
</a-form-item>
|
||||
</a-form>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
:width="400"
|
||||
:title="$t('login.machineValidation')"
|
||||
@cancel="handleCancel"
|
||||
|
@ -70,16 +70,12 @@
|
|||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" />
|
||||
<verified-outlined class="xn-color-00025" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<img
|
||||
:src="validCodeBase64"
|
||||
style="border: 1px solid var(--border-color-split); cursor: pointer; width: 100%; height: 40px"
|
||||
@click="getPhonePicCaptcha"
|
||||
/>
|
||||
<img :src="validCodeBase64" class="xn-findform-line" @click="getPhonePicCaptcha" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
|
@ -122,23 +118,26 @@
|
|||
formRules.value.phoneValidCode = [required(), rules.number]
|
||||
formRules.value.newPassword = [required()]
|
||||
|
||||
phoneLoginFormRef.value.validate().then(() => {
|
||||
phoneFormData.value.validCode = phoneFormData.value.phoneValidCode
|
||||
phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value
|
||||
phoneFormData.value.newPassword = smCrypto.doSm2Encrypt(phoneFormData.value.newPassword)
|
||||
islogin.value = true
|
||||
userCenterApi
|
||||
.userFindPasswordByPhone(phoneFormData.value)
|
||||
.then(() => {
|
||||
router.replace({
|
||||
path: '/'
|
||||
phoneLoginFormRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
phoneFormData.value.validCode = phoneFormData.value.phoneValidCode
|
||||
phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value
|
||||
phoneFormData.value.newPassword = smCrypto.doSm2Encrypt(phoneFormData.value.newPassword)
|
||||
islogin.value = true
|
||||
userCenterApi
|
||||
.userFindPasswordByPhone(phoneFormData.value)
|
||||
.then(() => {
|
||||
router.replace({
|
||||
path: '/'
|
||||
})
|
||||
message.success('找回成功')
|
||||
})
|
||||
message.success('找回成功')
|
||||
})
|
||||
.finally(() => {
|
||||
islogin.value = false
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
islogin.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 弹框的
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}?</a>
|
||||
<a href="/findpwd" class="xn-color-0d84ff">{{ $t('login.forgetPassword') }}?</a>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
|
||||
|
@ -213,24 +213,36 @@
|
|||
//登陆
|
||||
const loginForm = ref()
|
||||
const login = async () => {
|
||||
loginForm.value.validate().then(async () => {
|
||||
loading.value = true
|
||||
const loginData = {
|
||||
account: ruleForm.account,
|
||||
// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
|
||||
password: smCrypto.doSm2Encrypt(ruleForm.password),
|
||||
validCode: ruleForm.validCode,
|
||||
validCodeReqNo: ruleForm.validCodeReqNo
|
||||
}
|
||||
// 获取token
|
||||
try {
|
||||
const loginToken = await loginApi.login(loginData)
|
||||
afterLogin(loginToken)
|
||||
} catch (err) {
|
||||
loading.value = false
|
||||
loginCaptcha()
|
||||
}
|
||||
})
|
||||
loginForm.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
loading.value = true
|
||||
const loginData = {
|
||||
account: ruleForm.account,
|
||||
// 密码进行SM2加密,传输过程中看到的只有密文,后端存储使用hash
|
||||
password: smCrypto.doSm2Encrypt(ruleForm.password),
|
||||
validCode: ruleForm.validCode,
|
||||
validCodeReqNo: ruleForm.validCodeReqNo
|
||||
}
|
||||
|
||||
// 获取token
|
||||
// loginApi.login(loginData).then((loginToken) => {
|
||||
// afterLogin(loginToken)
|
||||
// }).catch(() => {
|
||||
// loading.value = false
|
||||
// loginCaptcha()
|
||||
// })
|
||||
|
||||
// 获取token
|
||||
try {
|
||||
const loginToken = await loginApi.login(loginData)
|
||||
const loginAfter = afterLogin(loginToken)
|
||||
} catch (err) {
|
||||
loading.value = false
|
||||
loginCaptcha()
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const configLang = (key) => {
|
||||
config.value.lang = key
|
||||
|
@ -238,4 +250,7 @@
|
|||
</script>
|
||||
<style lang="less">
|
||||
@import 'login';
|
||||
.xn-color-0d84ff {
|
||||
color: #0d84ff;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -21,20 +21,20 @@
|
|||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="7">
|
||||
<a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">
|
||||
<a-button size="large" class="xn-wd" @click="getPhoneValidCode" :disabled="state.smsSendBtn">
|
||||
{{ (!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s' }}
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" style="width: 100%" :loading="loading" round size="large" @click="submitLogin">
|
||||
<a-button type="primary" class="xn-wd" :loading="loading" round size="large" @click="submitLogin">
|
||||
{{ $t('login.signIn') }}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
v-model:open="visible"
|
||||
:width="400"
|
||||
:title="$t('login.machineValidation')"
|
||||
@cancel="handleCancel"
|
||||
|
@ -57,7 +57,7 @@
|
|||
<a-col :span="7">
|
||||
<img
|
||||
:src="validCodeBase64"
|
||||
style="border: 1px solid var(--border-color-split); cursor: pointer; width: 100%; height: 40px"
|
||||
class="xn-findform-line"
|
||||
@click="getPhonePicCaptcha"
|
||||
/>
|
||||
</a-col>
|
||||
|
@ -94,6 +94,7 @@
|
|||
getPhonePicCaptcha()
|
||||
})
|
||||
}
|
||||
|
||||
// 点击登录按钮
|
||||
const submitLogin = async () => {
|
||||
formRules.value.phone = [required('请输入11位手机号'), rules.phone]
|
||||
|
@ -105,14 +106,12 @@
|
|||
phoneFormData.value.validCode = phoneFormData.value.phoneValidCode
|
||||
// delete phoneFormData.value.phoneValidCode
|
||||
phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const token = await loginApi.loginByPhone(phoneFormData.value)
|
||||
loginApi.loginByPhone(phoneFormData.value).then((token) => {
|
||||
afterLogin(token)
|
||||
} catch (err) {
|
||||
}).catch((err) => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 弹框的
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div style="padding-bottom: 10px">
|
||||
<div class="xn-pb10">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="6">
|
||||
<a-card class="snowy-monitor-card" :bordered="false">
|
||||
|
@ -15,7 +15,7 @@
|
|||
<a-col :span="6">
|
||||
<a-card class="snowy-monitor-card" :bordered="false">
|
||||
<template #cover>
|
||||
<verified-outlined style="color: rgb(255, 156, 110)" class="snowy-monitor-card-icon" />
|
||||
<verified-outlined class="snowy-monitor-card-icon xn-color-ff9c6e" />
|
||||
<div class="snowy-monitor-card-div">
|
||||
<span class="snowy-monitor-card-span">最大签发令牌:</span
|
||||
><span class="snowy-monitor-card-span">{{ analysisObj.maxTokenCount }}</span>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<a-col :span="6">
|
||||
<a-card class="snowy-monitor-card" :bordered="false">
|
||||
<template #cover>
|
||||
<rise-outlined style="color: rgb(255, 133, 192)" class="snowy-monitor-card-icon" />
|
||||
<rise-outlined class="snowy-monitor-card-icon xn-color-ff85c0" />
|
||||
<div class="snowy-monitor-card-div">
|
||||
<span class="snowy-monitor-card-span">1小时内新增:</span
|
||||
><span class="snowy-monitor-card-span">{{ analysisObj.oneHourNewlyAdded }}</span>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<a-col :span="6">
|
||||
<a-card class="snowy-monitor-card" :bordered="false">
|
||||
<template #cover>
|
||||
<pie-chart-outlined style="color: rgb(92, 219, 211)" class="snowy-monitor-card-icon" />
|
||||
<pie-chart-outlined class="snowy-monitor-card-icon xn-color-5cdbd3" />
|
||||
<div class="snowy-monitor-card-div">
|
||||
<span class="snowy-monitor-card-span">B/C端占比:</span
|
||||
><span class="snowy-monitor-card-span">{{ analysisObj.proportionOfBAndC }}</span>
|
||||
|
@ -80,4 +80,13 @@
|
|||
.snowy-monitor-card-span {
|
||||
font-size: 16px;
|
||||
}
|
||||
.xn-color-ff9c6e {
|
||||
color: #ff9c6e;
|
||||
}
|
||||
.xn-color-ff85c0 {
|
||||
color: #ff85c0;
|
||||
}
|
||||
.xn-color-5cdbd3 {
|
||||
color: #5cdbd3;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<s-table ref="tableRef" :columns="columns" :data="loadDataB" :alert="false" bordered :row-key="(record) => record.id">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'avatar'">
|
||||
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
||||
<a-avatar :src="record.avatar" class="xn-wh25" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'tokenNumber'">
|
||||
{{ record.tokenSignList.length }}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<s-table ref="tableRef" :columns="columns" :data="loadDataC" :alert="false" bordered :row-key="(record) => record.id">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'avatar'">
|
||||
<a-avatar :src="record.avatar" style="width: 25px; height: 25px" />
|
||||
<a-avatar :src="record.avatar" class="xn-wh25" />
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'tokenNumber'">
|
||||
{{ record.tokenSignList.length }}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<xn-form-container title="令牌列表" :width="650" :visible="visible" :destroy-on-close="true" @close="onClose">
|
||||
<a-button
|
||||
danger
|
||||
style="margin-bottom: 10px"
|
||||
class="xn-mb10"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
:loading="beatchExitLoading"
|
||||
@click="beachExitTokenValue"
|
||||
|
@ -14,6 +14,7 @@
|
|||
:row-selection="rowSelection"
|
||||
bordered
|
||||
:row-key="(record) => record.tokenValue"
|
||||
size="small"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.dataIndex === 'tokenDevice'">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="8">
|
||||
<a-form-item label="关键字" name="searchKey">
|
||||
<a-form-item label="关键词" name="searchKey">
|
||||
<a-input v-model:value="searchFormState.searchKey" placeholder="请输入用户名或昵称关键词"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
||||
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
||||
<a-button class="xn-mg08" @click="reset">重置</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:disabled="true"
|
||||
v-model:value="formData.parentId"
|
||||
v-model:treeExpandedKeys="defaultExpandedKeys"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择上级字典"
|
||||
allow-clear
|
||||
|
@ -27,11 +27,11 @@
|
|||
<a-input v-model:value="formData.dictValue" placeholder="请输入字典值" allow-clear :disabled="true" />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序:" name="sortCode">
|
||||
<a-input-number style="width: 100%" v-model:value="formData.sortCode" :max="1000" />
|
||||
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="1000" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button class="xn-mr8" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" @click="onSubmit">保存</a-button>
|
||||
</template>
|
||||
</xn-form-container>
|
||||
|
@ -94,12 +94,15 @@
|
|||
})
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
bizDictApi.submitForm(formData.value).then(() => {
|
||||
visible.value = false
|
||||
emit('successful')
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
bizDictApi.submitForm(formData.value).then(() => {
|
||||
visible.value = false
|
||||
emit('successful')
|
||||
})
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
// 调用这个函数将子组件的一些数据和方法暴露出去
|
||||
defineExpose({
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="24" :lg="19" :xl="19">
|
||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||
<a-card :bordered="false" class="xn-mb10">
|
||||
<a-form
|
||||
ref="searchFormRef"
|
||||
name="advanced_search"
|
||||
|
@ -39,7 +39,7 @@
|
|||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||
<a-card :bordered="false" class="xn-mb10">
|
||||
<s-table
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<a-form-item label="上级机构:" name="parentId">
|
||||
<a-tree-select
|
||||
v-model:value="formData.parentId"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择上级机构"
|
||||
allow-clear
|
||||
|
@ -32,33 +32,27 @@
|
|||
<a-select
|
||||
v-model:value="formData.category"
|
||||
:options="orgCategoryOptions"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
placeholder="请选择机构分类"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序:" name="sortCode">
|
||||
<a-input-number style="width: 100%" v-model:value="formData.sortCode" :max="100" />
|
||||
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
|
||||
</a-form-item>
|
||||
<a-form-item label="指定主管:" name="directorId">
|
||||
<a-button type="link" style="padding-left: 0px" @click="openSelector(formData.directorId)">选择</a-button>
|
||||
<a-tag v-if="formData.directorId && formData.directorName" color="orange" closable @close="closeUserTag">{{
|
||||
formData.directorName
|
||||
}}</a-tag>
|
||||
<a-input v-show="false" v-model:value="formData.directorId" />
|
||||
<xn-user-selector
|
||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||
:user-page-api="selectorApiFunction.userPageApi"
|
||||
:user-list-by-id-list-api="selectorApiFunction.checkedUserListApi"
|
||||
:radio-model="true"
|
||||
v-model:value="formData.directorId"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button class="xn-mr8" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit">保存</a-button>
|
||||
</template>
|
||||
<user-selector-plus
|
||||
ref="UserSelectorPlus"
|
||||
:org-tree-api="selectorApiFunction.orgTreeApi"
|
||||
:user-page-api="selectorApiFunction.userPageApi"
|
||||
:checked-user-list-api="selectorApiFunction.checkedUserListApi"
|
||||
:radio-model="true"
|
||||
@onBack="userBack"
|
||||
/>
|
||||
</xn-form-container>
|
||||
</template>
|
||||
|
||||
|
@ -66,14 +60,12 @@
|
|||
import { required } from '@/utils/formRules'
|
||||
import bizOrgApi from '@/api/biz/bizOrgApi'
|
||||
import userCenterApi from '@/api/sys/userCenterApi'
|
||||
import userSelectorPlus from '@/components/Selector/userSelectorPlus.vue'
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
// 定义emit事件
|
||||
const emit = defineEmits({ successful: null })
|
||||
// 默认是关闭状态
|
||||
const visible = ref(false)
|
||||
let UserSelectorPlus = ref()
|
||||
const formRef = ref()
|
||||
// 表单数据,也就是默认给一些数据
|
||||
const formData = ref({})
|
||||
|
@ -116,33 +108,13 @@
|
|||
}
|
||||
// 默认要校验的
|
||||
const formRules = {
|
||||
parentId: [required('请选择上级机构')],
|
||||
name: [required('请输入机构名称')],
|
||||
category: [required('请选择机构分类')],
|
||||
sortCode: [required('请选择排序')]
|
||||
}
|
||||
// 机构分类字典
|
||||
const orgCategoryOptions = tool.dictList('ORG_CATEGORY')
|
||||
// 打开人员选择器,选择主管
|
||||
const openSelector = (id) => {
|
||||
let checkedUserIds = []
|
||||
checkedUserIds.push(id)
|
||||
UserSelectorPlus.value.showUserPlusModal(checkedUserIds)
|
||||
}
|
||||
// 人员选择器回调
|
||||
const userBack = (value) => {
|
||||
if (value.length > 0) {
|
||||
formData.value.directorId = value[0].id
|
||||
formData.value.directorName = value[0].name
|
||||
} else {
|
||||
formData.value.directorId = ''
|
||||
formData.value.directorName = ''
|
||||
}
|
||||
}
|
||||
// 通过小标签删除主管
|
||||
const closeUserTag = () => {
|
||||
formData.value.directorId = ''
|
||||
formData.value.directorName = ''
|
||||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="24" :lg="19" :xl="19">
|
||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||
<a-card :bordered="false" class="xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="8">
|
||||
|
@ -27,7 +27,7 @@
|
|||
<template #icon><SearchOutlined /></template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button class="snowy-buttom-left" @click="reset">
|
||||
<a-button class="snowy-button-left" @click="reset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
重置
|
||||
</a-button>
|
||||
|
@ -213,10 +213,7 @@
|
|||
.ant-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.primaryAdd {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.snowy-buttom-left {
|
||||
.snowy-button-left {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<a-form-item label="所属组织:" name="orgId">
|
||||
<a-tree-select
|
||||
v-model:value="formData.orgId"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
|
@ -32,17 +32,17 @@
|
|||
<a-select
|
||||
v-model:value="formData.category"
|
||||
:options="positionCategoryOptions"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
placeholder="请选择岗位分类"
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序:" name="sortCode">
|
||||
<a-input-number style="width: 100%" v-model:value="formData.sortCode" :max="100" />
|
||||
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button class="xn-mr8" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit">保存</a-button>
|
||||
</template>
|
||||
</xn-form-container>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="24" :lg="19" :xl="19">
|
||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||
<a-card :bordered="false" class="xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="8">
|
||||
|
@ -27,7 +27,7 @@
|
|||
<template #icon><SearchOutlined /></template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button class="snowy-buttom-left" @click="reset">
|
||||
<a-button class="snowy-button-left" @click="reset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
重置
|
||||
</a-button>
|
||||
|
@ -210,10 +210,7 @@
|
|||
.ant-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.primaryAdd {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.snowy-buttom-left {
|
||||
.snowy-button-left {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="出生日期:" name="birthday">
|
||||
<a-date-picker v-model:value="formData.birthday" value-format="YYYY-MM-DD" style="width: 100%" />
|
||||
<a-date-picker v-model:value="formData.birthday" value-format="YYYY-MM-DD" class="xn-wd" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<a-form-item label="选择组织:" name="orgId">
|
||||
<a-tree-select
|
||||
v-model:value="formData.orgId"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择组织"
|
||||
allow-clear
|
||||
|
@ -112,7 +112,7 @@
|
|||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-form-item label="入职日期:" name="entryDate">
|
||||
<a-date-picker v-model:value="formData.entryDate" value-format="YYYY-MM-DD" style="width: 100%" />
|
||||
<a-date-picker v-model:value="formData.entryDate" value-format="YYYY-MM-DD" class="xn-wd" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@ -137,7 +137,7 @@
|
|||
>
|
||||
<a-tree-select
|
||||
v-model:value="positionInfo.orgId"
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="请选择机构"
|
||||
allow-clear
|
||||
|
@ -176,7 +176,7 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="3" style="margin-top: 4px">
|
||||
<a-col :span="3" class="xn-mt4">
|
||||
<a-button size="small" type="primary" danger ghost @click="delDomains(index)">移除</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@ -316,13 +316,13 @@
|
|||
</a-tabs>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button class="xn-mr8" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" :loading="formLoading" @click="onSubmit">保存</a-button>
|
||||
</template>
|
||||
</xn-form-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="bizUser">
|
||||
import bizUserApi from '@/api/biz/bizUserApi'
|
||||
import { required } from '@/utils/formRules'
|
||||
import tool from '@/utils/tool'
|
||||
|
@ -507,25 +507,28 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
// 因为不切断,我下面转换数据格式,影响上面表单会报错
|
||||
let formDatas = JSON.parse(JSON.stringify(formData.value))
|
||||
if (formDatas.positionJson && formDatas.positionJson.length > 0) {
|
||||
formDatas.positionJson = JSON.stringify(formDatas.positionJson)
|
||||
} else {
|
||||
delete formDatas.positionJson
|
||||
}
|
||||
formLoading.value = true
|
||||
bizUserApi
|
||||
.submitForm(formDatas, formDatas.id)
|
||||
.then(() => {
|
||||
onClose()
|
||||
emit('successful')
|
||||
})
|
||||
.finally(() => {
|
||||
formLoading.value = false
|
||||
})
|
||||
})
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
// 因为不切断,我下面转换数据格式,影响上面表单会报错
|
||||
let formDatas = JSON.parse(JSON.stringify(formData.value))
|
||||
if (formDatas.positionJson && formDatas.positionJson.length > 0) {
|
||||
formDatas.positionJson = JSON.stringify(formDatas.positionJson)
|
||||
} else {
|
||||
delete formDatas.positionJson
|
||||
}
|
||||
formLoading.value = true
|
||||
bizUserApi
|
||||
.submitForm(formDatas, formDatas.id)
|
||||
.then(() => {
|
||||
onClose()
|
||||
emit('successful')
|
||||
})
|
||||
.finally(() => {
|
||||
formLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
// 性别
|
||||
const genderOptions = tool.dictList('GENDER')
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</a-card>
|
||||
</a-col>
|
||||
<a-col :xs="24" :sm="24" :md="24" :lg="19" :xl="19">
|
||||
<a-card :bordered="false" style="margin-bottom: 10px">
|
||||
<a-card :bordered="false" class="xn-mb10">
|
||||
<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="8">
|
||||
|
@ -39,7 +39,7 @@
|
|||
<template #icon><SearchOutlined /></template>
|
||||
{{ $t('common.searchButton') }}
|
||||
</a-button>
|
||||
<a-button class="snowy-buttom-left" @click="reset">
|
||||
<a-button class="snowy-button-left" @click="reset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
{{ $t('common.resetButton') }}
|
||||
</a-button>
|
||||
|
@ -418,14 +418,11 @@
|
|||
.ant-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.primaryAdd {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.snowy-table-avatar {
|
||||
margin-top: -10px;
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
.snowy-buttom-left {
|
||||
.snowy-button-left {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -59,22 +59,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -55,22 +55,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -63,22 +63,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -55,22 +55,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -63,22 +63,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -63,22 +63,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-card
|
||||
style="width: 100%"
|
||||
class="xn-wd"
|
||||
:bordered="false"
|
||||
:tab-list="tabListNoTitle"
|
||||
:active-tab-key="noTitleKey"
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
<a-input v-model:value="formData.remark" placeholder="请输入备注" allow-clear />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序:" name="sortCode">
|
||||
<a-input-number style="width: 100%" v-model:value="formData.sortCode" :max="1000" />
|
||||
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="1000" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||
<a-button class="xn-mr8" @click="onClose">关闭</a-button>
|
||||
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
|
||||
</template>
|
||||
</xn-form-container>
|
||||
|
@ -66,18 +66,21 @@
|
|||
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
configApi
|
||||
.submitForm(formData.value, formData.value.id)
|
||||
.then(() => {
|
||||
onClose()
|
||||
emit('successful')
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
configApi
|
||||
.submitForm(formData.value, formData.value.id)
|
||||
.then(() => {
|
||||
onClose()
|
||||
emit('successful')
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
// 调用这个函数将子组件的一些数据和方法暴露出去
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</a-button>
|
||||
<a-input-search
|
||||
v-model:value="searchFormState.searchKey"
|
||||
placeholder="请输入关键字"
|
||||
placeholder="请输入关键词"
|
||||
enter-button
|
||||
allowClear
|
||||
@search="tableRef.refresh(true)"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -63,22 +63,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
<template>
|
||||
<a-tabs v-model:activeKey="activeKey" tab-position="left">
|
||||
<a-tab-pane key="xiaonuoSms" tab="小诺短信">
|
||||
<xiaonuo-sms-form />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="aliyunSms" tab="阿里短信">
|
||||
<aliyunSmsForm />
|
||||
<aliyun-sms-form />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="tencentSms" tab="腾讯短信">
|
||||
<tencentSmsForm />
|
||||
<tencent-sms-form />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
|
||||
<script setup name="smsConfig">
|
||||
import XiaonuoSmsForm from './xiaonuoSmsForm.vue'
|
||||
import AliyunSmsForm from './aliyunSmsForm.vue'
|
||||
import TencentSmsForm from './tencentSmsForm.vue'
|
||||
const activeKey = ref('aliyunSms')
|
||||
const activeKey = ref('xiaonuoSms')
|
||||
</script>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -67,22 +67,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<a-spin :spinning="loadSpinning">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
layout="vertical"
|
||||
:label-col="{ ...layout.labelCol, offset: 0 }"
|
||||
:wrapper-col="{ ...layout.wrapperCol, offset: 0 }"
|
||||
>
|
||||
<a-form-item name="SNOWY_SMS_XIAONUO_ACCESS_KEY_ID">
|
||||
<template #label>
|
||||
<a-tooltip>
|
||||
<template #title> 通过官网申请短信或联系站长! </template>
|
||||
<question-circle-outlined />
|
||||
</a-tooltip>
|
||||
  小诺短信账号:
|
||||
</template>
|
||||
<a-input v-model:value="formData.SNOWY_SMS_XIAONUO_ACCESS_KEY_ID" placeholder="请输入小诺短信账号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="小诺短信秘钥:" name="SNOWY_SMS_XIAONUO_ACCESS_KEY_SECRET">
|
||||
<a-input v-model:value="formData.SNOWY_SMS_XIAONUO_ACCESS_KEY_SECRET" placeholder="请输入小诺短信秘钥" />
|
||||
</a-form-item>
|
||||
<a-form-item label="发送短信URL:" name="SNOWY_SMS_XIAONUO_REQUEST_URL">
|
||||
<a-input v-model:value="formData.SNOWY_SMS_XIAONUO_REQUEST_URL" placeholder="请输入发送短信URL" />
|
||||
</a-form-item>
|
||||
<a-form-item name="SNOWY_SMS_XIAONUO_DEFAULT_SIGN_NAME">
|
||||
<template #label>
|
||||
<a-tooltip>
|
||||
<template #title> 注:若账号跟密钥已绑定签名,则此处配置签名后无效! </template>
|
||||
<question-circle-outlined />
|
||||
</a-tooltip>
|
||||
  短信签名:
|
||||
</template>
|
||||
<a-input v-model:value="formData.SNOWY_SMS_XIAONUO_DEFAULT_SIGN_NAME" placeholder="请输入短信签名" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script setup name="xiaonuoSmsForm">
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import { required } from '@/utils/formRules'
|
||||
import { message } from 'ant-design-vue'
|
||||
import configApi from '@/api/dev/configApi'
|
||||
|
||||
const formRef = ref()
|
||||
const formData = ref({})
|
||||
const submitLoading = ref(false)
|
||||
const loadSpinning = ref(true)
|
||||
|
||||
// 查询此界面的配置项,并转为表单
|
||||
const param = {
|
||||
category: 'SMS_XIAONUO'
|
||||
}
|
||||
configApi.configList(param).then((data) => {
|
||||
loadSpinning.value = false
|
||||
if (data) {
|
||||
data.forEach((item) => {
|
||||
formData.value[item.configKey] = item.configValue
|
||||
})
|
||||
} else {
|
||||
message.warning('表单项不存在,请初始化数据库')
|
||||
}
|
||||
})
|
||||
|
||||
// 默认要校验的
|
||||
const formRules = {
|
||||
SNOWY_SMS_XIAONUO_ACCESS_KEY_ID: [required('请输入小诺短信账号')],
|
||||
SNOWY_SMS_XIAONUO_ACCESS_KEY_SECRET: [required('请输入小诺短信秘钥')],
|
||||
SNOWY_SMS_XIAONUO_REQUEST_URL: [required('请输入发送短信URL')],
|
||||
SNOWY_SMS_XIAONUO_DEFAULT_SIGN_NAME: [required('请输入短信签名')]
|
||||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
span: 4
|
||||
},
|
||||
wrapperCol: {
|
||||
span: 12
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -88,7 +88,7 @@
|
|||
<a-col :span="24">
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="resetForm">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="resetForm">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
@ -100,6 +100,7 @@
|
|||
import { cloneDeep } from 'lodash-es'
|
||||
import { required } from '@/utils/formRules'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { globalStore } from '@/store'
|
||||
import configApi from '@/api/dev/configApi'
|
||||
import tool from '@/utils/tool'
|
||||
import MenuTreeSelect from '@/components/TreeSelect/menuTreeSelect.vue'
|
||||
|
@ -113,6 +114,7 @@
|
|||
const imageUrl = ref('')
|
||||
const menuTreeSelectRef = ref()
|
||||
const loadSpinning = ref(true)
|
||||
const store = globalStore()
|
||||
// 查询此界面的配置项,并转为表单
|
||||
const param = {
|
||||
category: 'SYS_BASE'
|
||||
|
@ -191,6 +193,11 @@
|
|||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
// 创建快捷方式
|
||||
const shortcut = {
|
||||
shortcut: menuTreeSelectRef.value.getSelectData()
|
||||
}
|
||||
submitParam.SNOWY_SYS_DEFAULT_WORKBENCH_DATA = JSON.stringify(shortcut)
|
||||
submitParam.SNOWY_SYS_LOGO = submitParam.SNOWY_SYS_LOGO[0]
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
|
@ -198,17 +205,13 @@
|
|||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
// 创建快捷方式
|
||||
const shortcut = {
|
||||
shortcut: menuTreeSelectRef.value.getSelectData()
|
||||
}
|
||||
param.push({
|
||||
configKey: 'SNOWY_SYS_DEFAULT_WORKBENCH_DATA',
|
||||
configValue: JSON.stringify(shortcut)
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.then(() => {
|
||||
// 执行成功后改变界面使其生效
|
||||
tool.data.set('SNOWY_SYS_BASE_CONFIG', submitParam)
|
||||
store.setSysBaseConfig(submitParam)
|
||||
})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" :loading="submitLoading" @click="onSubmit()">保存</a-button>
|
||||
<a-button style="margin-left: 10px" @click="() => formRef.resetFields()">重置</a-button>
|
||||
<a-button class="xn-ml10" @click="() => formRef.resetFields()">重置</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
|
@ -59,22 +59,25 @@
|
|||
}
|
||||
// 验证并提交数据
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
submitLoading.value = true
|
||||
let submitParam = cloneDeep(formData.value)
|
||||
const param = Object.entries(submitParam).map((item) => {
|
||||
return {
|
||||
configKey: item[0],
|
||||
configValue: item[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
configApi
|
||||
.configEditForm(param)
|
||||
.then(() => {})
|
||||
.finally(() => {
|
||||
submitLoading.value = false
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
const layout = {
|
||||
labelCol: {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue