Initial commit
6
.env
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# 后台接口地址(仅开发/预览环境生效)
|
||||||
|
VITE_PROXY_API=http://localhost/site/site_api/public/admin.php/
|
||||||
|
# 后台图片地址(仅开发/预览环境生效)
|
||||||
|
VITE_PROXY_UPLOADS=http://localhost/site/site_api/public/uploads/
|
||||||
|
# 后台富文本上传地址(仅开发/预览环境生效)
|
||||||
|
VITE_RICHTEXT_GATEWAY=http://localhost:3000/api/
|
10
.env.production
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# 静态资源使用相对路径
|
||||||
|
VITE_BASE=./
|
||||||
|
# 关闭 console.log
|
||||||
|
VITE_DROP_CONSOLE=true
|
||||||
|
# 关闭 debuuger
|
||||||
|
VITE_DROP_DEBUGGER=true
|
||||||
|
|
||||||
|
# 后台 BaseURL
|
||||||
|
VITE_API_GATEWAY=/public/admin.php
|
||||||
|
VITE_RICHTEXT_GATEWAY=/public/admin.php
|
19
.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# lock
|
||||||
|
# yarn.lock
|
||||||
|
# package-lock.json
|
||||||
|
# pnpm-lock.yaml
|
||||||
|
|
||||||
|
*.log
|
||||||
|
|
||||||
|
*.d.ts
|
||||||
|
|
||||||
|
.env.development.local
|
||||||
|
|
||||||
|
.vscode
|
10
.prettierrc.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"eslintIntegration": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
92
README.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# rentalshop-web
|
||||||
|
|
||||||
|
快转铺后台-后台页面
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||||
|
|
||||||
|
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||||
|
|
||||||
|
## Add your files
|
||||||
|
|
||||||
|
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||||
|
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd existing_repo
|
||||||
|
git remote add origin http://172.20.80.175:28000/kongwu/rentalshop-web.git
|
||||||
|
git branch -M main
|
||||||
|
git push -uf origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integrate with your tools
|
||||||
|
|
||||||
|
- [ ] [Set up project integrations](http://172.20.80.175:28000/kongwu/rentalshop-web/-/settings/integrations)
|
||||||
|
|
||||||
|
## Collaborate with your team
|
||||||
|
|
||||||
|
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||||
|
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||||
|
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||||
|
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||||
|
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||||
|
|
||||||
|
## Test and Deploy
|
||||||
|
|
||||||
|
Use the built-in continuous integration in GitLab.
|
||||||
|
|
||||||
|
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||||
|
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||||
|
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||||
|
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||||
|
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
# Editing this README
|
||||||
|
|
||||||
|
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||||
|
|
||||||
|
## Suggestions for a good README
|
||||||
|
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||||
|
|
||||||
|
## Name
|
||||||
|
Choose a self-explaining name for your project.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||||
|
|
||||||
|
## Badges
|
||||||
|
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||||
|
|
||||||
|
## Visuals
|
||||||
|
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
State if you are open to contributions and what your requirements are for accepting them.
|
||||||
|
|
||||||
|
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||||
|
|
||||||
|
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||||
|
|
||||||
|
## Authors and acknowledgment
|
||||||
|
Show your appreciation to those who have contributed to the project.
|
||||||
|
|
||||||
|
## License
|
||||||
|
For open source projects, say how it is licensed.
|
||||||
|
|
||||||
|
## Project status
|
||||||
|
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
129
index.html
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>官方网站模板后台管理系统</title>
|
||||||
|
<!-- element css cdn, if you use custom theme, remove it. -->
|
||||||
|
<!-- <link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/element-plus/dist/index.css"
|
||||||
|
/> -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<style>
|
||||||
|
.first-loading-wrap {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-loading-wrap>h1 {
|
||||||
|
font-size: 128px
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-loading-wrap .loading-wrap {
|
||||||
|
padding: 98px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="first-loading-wrap">
|
||||||
|
<div class="loading-wrap">
|
||||||
|
<span class="dot dot-spin">
|
||||||
|
<i></i>
|
||||||
|
<i></i>
|
||||||
|
<i></i>
|
||||||
|
<i></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
10
jsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2020",
|
||||||
|
"module": "es6",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"]
|
||||||
|
}
|
58
package.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"name": "template",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"production": "vite build --mode production"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"chrome > 70",
|
||||||
|
"last 10 version",
|
||||||
|
"> 1%",
|
||||||
|
"not dead"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||||
|
"@element-plus/icons-vue": "^0.2.7",
|
||||||
|
"@wangeditor/editor": "^5.1.23",
|
||||||
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
|
"audit": "^0.0.6",
|
||||||
|
"axios": "^0.26.1",
|
||||||
|
"echarts": "^5.4.1",
|
||||||
|
"element-plus": "^2.2.30",
|
||||||
|
"highlight.js": "^11.7.0",
|
||||||
|
"hyw-drag": "^1.0.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"pinia": "^2.0.32",
|
||||||
|
"pinia-plugin-persist": "^1.0.0",
|
||||||
|
"sortablejs": "^1.15.0",
|
||||||
|
"vue": "^3.2.47",
|
||||||
|
"vue-demi": "^0.13.11",
|
||||||
|
"vue-router": "^4.1.6",
|
||||||
|
"vuex": "^4.1.0",
|
||||||
|
"wangeditor": "^4.7.15"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^17.0.45",
|
||||||
|
"@vitejs/plugin-legacy": "^1.8.2",
|
||||||
|
"@vitejs/plugin-vue": "^2.3.4",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^1.3.10",
|
||||||
|
"@vue/compiler-sfc": "^3.2.47",
|
||||||
|
"element-theme-chalk": "^2.15.13",
|
||||||
|
"less": "^4.1.3",
|
||||||
|
"less-loader": "^10.2.0",
|
||||||
|
"prettier": "^2.8.4",
|
||||||
|
"sass": "^1.58.2",
|
||||||
|
"unplugin-auto-import": "^0.6.9",
|
||||||
|
"unplugin-element-plus": "^0.3.4",
|
||||||
|
"unplugin-vue-components": "^0.17.21",
|
||||||
|
"vite": "^2.9.15",
|
||||||
|
"vite-plugin-pages": "^0.23.0",
|
||||||
|
"vue-tsc": "^0.31.4"
|
||||||
|
}
|
||||||
|
}
|
BIN
public/document/后台管理平台初始化.pdf
Normal file
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
public/font/clock_word.TTF
Normal file
BIN
public/images/login-background.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
public/images/login-captcha-icon.png
Normal file
After Width: | Height: | Size: 636 B |
BIN
public/images/login-left.png
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
public/images/login-password-icon.png
Normal file
After Width: | Height: | Size: 442 B |
BIN
public/images/login-user-icon.png
Normal file
After Width: | Height: | Size: 493 B |
BIN
public/images/logo_login.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
public/img/home/Ellipse 82.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
public/img/home/Frame.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/img/home/Time icon.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/img/home/group-1-10.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
public/img/home/group-1-11.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
public/img/home/group-1-12.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
public/img/home/group-1-13.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
0
public/img/home/img
Normal file
BIN
public/img/home/上升.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
public/img/home/图标.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
public/img/home/图标(蓝).png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
public/img/home/矩形 2.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
public/logo.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
38
src/App.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<el-config-provider :locale="zh">
|
||||||
|
<router-view></router-view>
|
||||||
|
</el-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import zh from 'element-plus/es/locale/lang/zh-cn' // 中文语言
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-avatar {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
line-height: 100px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-avatar-plus {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
vertical-align: middle;
|
||||||
|
min-width: 100px;
|
||||||
|
min-height: 100px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
13681
src/assets/area.json
Normal file
391
src/assets/iconfont/iconfont.css
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "iconfont"; /* Project id 4017520 */
|
||||||
|
src: url('iconfont.woff2?t=1681548759797') format('woff2'),
|
||||||
|
url('iconfont.woff?t=1681548759797') format('woff'),
|
||||||
|
url('iconfont.ttf?t=1681548759797') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tree-table:before {
|
||||||
|
content: "\e637";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-unlock:before {
|
||||||
|
content: "\e654";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zujian:before {
|
||||||
|
content: "\e655";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-theme:before {
|
||||||
|
content: "\e659";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-swagger:before {
|
||||||
|
content: "\e65c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-star:before {
|
||||||
|
content: "\e661";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-time:before {
|
||||||
|
content: "\e662";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-upload:before {
|
||||||
|
content: "\e663";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-weixin:before {
|
||||||
|
content: "\e664";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-system:before {
|
||||||
|
content: "\e667";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-web:before {
|
||||||
|
content: "\e668";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tree:before {
|
||||||
|
content: "\e669";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-user:before {
|
||||||
|
content: "\e66a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tool:before {
|
||||||
|
content: "\e66b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zip:before {
|
||||||
|
content: "\e66c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-link:before {
|
||||||
|
content: "\e636";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-list:before {
|
||||||
|
content: "\e638";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-international:before {
|
||||||
|
content: "\e639";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-language:before {
|
||||||
|
content: "\e63a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-index:before {
|
||||||
|
content: "\e63b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ipvisits:before {
|
||||||
|
content: "\e63c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-money:before {
|
||||||
|
content: "\e63d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-message:before {
|
||||||
|
content: "\e63e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-login:before {
|
||||||
|
content: "\e63f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-lock:before {
|
||||||
|
content: "\e640";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-menu:before {
|
||||||
|
content: "\e641";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-log:before {
|
||||||
|
content: "\e643";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-logininfor:before {
|
||||||
|
content: "\e644";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-mnt:before {
|
||||||
|
content: "\e645";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-password:before {
|
||||||
|
content: "\e646";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-peoples:before {
|
||||||
|
content: "\e647";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-post:before {
|
||||||
|
content: "\e648";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-permission:before {
|
||||||
|
content: "\e649";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-phone:before {
|
||||||
|
content: "\e64a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-people:before {
|
||||||
|
content: "\e64b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-online:before {
|
||||||
|
content: "\e64d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-pdf:before {
|
||||||
|
content: "\e64f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-redis:before {
|
||||||
|
content: "\e650";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-size:before {
|
||||||
|
content: "\e651";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search:before {
|
||||||
|
content: "\e652";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-server:before {
|
||||||
|
content: "\e653";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-select:before {
|
||||||
|
content: "\e656";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-question:before {
|
||||||
|
content: "\e657";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rate:before {
|
||||||
|
content: "\e658";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-monitor:before {
|
||||||
|
content: "\e65a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-source:before {
|
||||||
|
content: "\e65b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-role:before {
|
||||||
|
content: "\e65d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shopping:before {
|
||||||
|
content: "\e65e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-skill:before {
|
||||||
|
content: "\e65f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-number:before {
|
||||||
|
content: "\e660";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-a-404:before {
|
||||||
|
content: "\e622";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-email:before {
|
||||||
|
content: "\e623";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-example:before {
|
||||||
|
content: "\e624";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-error:before {
|
||||||
|
content: "\e625";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-excel:before {
|
||||||
|
content: "\e626";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-education:before {
|
||||||
|
content: "\e627";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-eye-open:before {
|
||||||
|
content: "\e628";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-eye:before {
|
||||||
|
content: "\e629";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-github:before {
|
||||||
|
content: "\e62b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-guide:before {
|
||||||
|
content: "\e62c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gonggao:before {
|
||||||
|
content: "\e62d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon1:before {
|
||||||
|
content: "\e62e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-fullscreen:before {
|
||||||
|
content: "\e62f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon:before {
|
||||||
|
content: "\e630";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-image:before {
|
||||||
|
content: "\e631";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-form:before {
|
||||||
|
content: "\e632";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-job:before {
|
||||||
|
content: "\e635";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-cascader:before {
|
||||||
|
content: "\e603";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-alipay:before {
|
||||||
|
content: "\e604";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-anq:before {
|
||||||
|
content: "\e605";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-backup:before {
|
||||||
|
content: "\e606";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bug:before {
|
||||||
|
content: "\e607";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button:before {
|
||||||
|
content: "\e609";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chain:before {
|
||||||
|
content: "\e60b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chart:before {
|
||||||
|
content: "\e60c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-checkbox:before {
|
||||||
|
content: "\e60d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-clipboard:before {
|
||||||
|
content: "\e60e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-codeConsole:before {
|
||||||
|
content: "\e60f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-code:before {
|
||||||
|
content: "\e610";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-color:before {
|
||||||
|
content: "\e611";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-database:before {
|
||||||
|
content: "\e612";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-component:before {
|
||||||
|
content: "\e613";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dashboard:before {
|
||||||
|
content: "\e614";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-date:before {
|
||||||
|
content: "\e615";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-deploy:before {
|
||||||
|
content: "\e616";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-develop:before {
|
||||||
|
content: "\e617";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dept:before {
|
||||||
|
content: "\e619";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dictionary:before {
|
||||||
|
content: "\e61a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-documentation:before {
|
||||||
|
content: "\e61b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-doc:before {
|
||||||
|
content: "\e61c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-download:before {
|
||||||
|
content: "\e61d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dict:before {
|
||||||
|
content: "\e61e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-edit:before {
|
||||||
|
content: "\e620";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-app:before {
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
|
1
src/assets/iconfont/iconfont.js
Normal file
667
src/assets/iconfont/iconfont.json
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
{
|
||||||
|
"id": "4017520",
|
||||||
|
"name": "admin",
|
||||||
|
"font_family": "iconfont",
|
||||||
|
"css_prefix_text": "icon-",
|
||||||
|
"description": "",
|
||||||
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "35076965",
|
||||||
|
"name": "tree-table",
|
||||||
|
"font_class": "tree-table",
|
||||||
|
"unicode": "e637",
|
||||||
|
"unicode_decimal": 58935
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076967",
|
||||||
|
"name": "unlock",
|
||||||
|
"font_class": "unlock",
|
||||||
|
"unicode": "e654",
|
||||||
|
"unicode_decimal": 58964
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076968",
|
||||||
|
"name": "zujian",
|
||||||
|
"font_class": "zujian",
|
||||||
|
"unicode": "e655",
|
||||||
|
"unicode_decimal": 58965
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076969",
|
||||||
|
"name": "theme",
|
||||||
|
"font_class": "theme",
|
||||||
|
"unicode": "e659",
|
||||||
|
"unicode_decimal": 58969
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076970",
|
||||||
|
"name": "swagger",
|
||||||
|
"font_class": "swagger",
|
||||||
|
"unicode": "e65c",
|
||||||
|
"unicode_decimal": 58972
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076971",
|
||||||
|
"name": "star",
|
||||||
|
"font_class": "star",
|
||||||
|
"unicode": "e661",
|
||||||
|
"unicode_decimal": 58977
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076972",
|
||||||
|
"name": "time",
|
||||||
|
"font_class": "time",
|
||||||
|
"unicode": "e662",
|
||||||
|
"unicode_decimal": 58978
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076973",
|
||||||
|
"name": "upload",
|
||||||
|
"font_class": "upload",
|
||||||
|
"unicode": "e663",
|
||||||
|
"unicode_decimal": 58979
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076974",
|
||||||
|
"name": "weixin",
|
||||||
|
"font_class": "weixin",
|
||||||
|
"unicode": "e664",
|
||||||
|
"unicode_decimal": 58980
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076977",
|
||||||
|
"name": "system",
|
||||||
|
"font_class": "system",
|
||||||
|
"unicode": "e667",
|
||||||
|
"unicode_decimal": 58983
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076979",
|
||||||
|
"name": "web",
|
||||||
|
"font_class": "web",
|
||||||
|
"unicode": "e668",
|
||||||
|
"unicode_decimal": 58984
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076980",
|
||||||
|
"name": "tree",
|
||||||
|
"font_class": "tree",
|
||||||
|
"unicode": "e669",
|
||||||
|
"unicode_decimal": 58985
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076981",
|
||||||
|
"name": "user",
|
||||||
|
"font_class": "user",
|
||||||
|
"unicode": "e66a",
|
||||||
|
"unicode_decimal": 58986
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076982",
|
||||||
|
"name": "tool",
|
||||||
|
"font_class": "tool",
|
||||||
|
"unicode": "e66b",
|
||||||
|
"unicode_decimal": 58987
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076986",
|
||||||
|
"name": "zip",
|
||||||
|
"font_class": "zip",
|
||||||
|
"unicode": "e66c",
|
||||||
|
"unicode_decimal": 58988
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076492",
|
||||||
|
"name": "link",
|
||||||
|
"font_class": "link",
|
||||||
|
"unicode": "e636",
|
||||||
|
"unicode_decimal": 58934
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076494",
|
||||||
|
"name": "list",
|
||||||
|
"font_class": "list",
|
||||||
|
"unicode": "e638",
|
||||||
|
"unicode_decimal": 58936
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076495",
|
||||||
|
"name": "international",
|
||||||
|
"font_class": "international",
|
||||||
|
"unicode": "e639",
|
||||||
|
"unicode_decimal": 58937
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076496",
|
||||||
|
"name": "language",
|
||||||
|
"font_class": "language",
|
||||||
|
"unicode": "e63a",
|
||||||
|
"unicode_decimal": 58938
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076497",
|
||||||
|
"name": "index",
|
||||||
|
"font_class": "index",
|
||||||
|
"unicode": "e63b",
|
||||||
|
"unicode_decimal": 58939
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076498",
|
||||||
|
"name": "ipvisits",
|
||||||
|
"font_class": "ipvisits",
|
||||||
|
"unicode": "e63c",
|
||||||
|
"unicode_decimal": 58940
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076499",
|
||||||
|
"name": "money",
|
||||||
|
"font_class": "money",
|
||||||
|
"unicode": "e63d",
|
||||||
|
"unicode_decimal": 58941
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076500",
|
||||||
|
"name": "message",
|
||||||
|
"font_class": "message",
|
||||||
|
"unicode": "e63e",
|
||||||
|
"unicode_decimal": 58942
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076501",
|
||||||
|
"name": "login",
|
||||||
|
"font_class": "login",
|
||||||
|
"unicode": "e63f",
|
||||||
|
"unicode_decimal": 58943
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076502",
|
||||||
|
"name": "lock",
|
||||||
|
"font_class": "lock",
|
||||||
|
"unicode": "e640",
|
||||||
|
"unicode_decimal": 58944
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076503",
|
||||||
|
"name": "menu",
|
||||||
|
"font_class": "menu",
|
||||||
|
"unicode": "e641",
|
||||||
|
"unicode_decimal": 58945
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076505",
|
||||||
|
"name": "log",
|
||||||
|
"font_class": "log",
|
||||||
|
"unicode": "e643",
|
||||||
|
"unicode_decimal": 58947
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076506",
|
||||||
|
"name": "logininfor",
|
||||||
|
"font_class": "logininfor",
|
||||||
|
"unicode": "e644",
|
||||||
|
"unicode_decimal": 58948
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076507",
|
||||||
|
"name": "mnt",
|
||||||
|
"font_class": "mnt",
|
||||||
|
"unicode": "e645",
|
||||||
|
"unicode_decimal": 58949
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076509",
|
||||||
|
"name": "password",
|
||||||
|
"font_class": "password",
|
||||||
|
"unicode": "e646",
|
||||||
|
"unicode_decimal": 58950
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076510",
|
||||||
|
"name": "peoples",
|
||||||
|
"font_class": "peoples",
|
||||||
|
"unicode": "e647",
|
||||||
|
"unicode_decimal": 58951
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076511",
|
||||||
|
"name": "post",
|
||||||
|
"font_class": "post",
|
||||||
|
"unicode": "e648",
|
||||||
|
"unicode_decimal": 58952
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076512",
|
||||||
|
"name": "permission",
|
||||||
|
"font_class": "permission",
|
||||||
|
"unicode": "e649",
|
||||||
|
"unicode_decimal": 58953
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076513",
|
||||||
|
"name": "phone",
|
||||||
|
"font_class": "phone",
|
||||||
|
"unicode": "e64a",
|
||||||
|
"unicode_decimal": 58954
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076514",
|
||||||
|
"name": "people",
|
||||||
|
"font_class": "people",
|
||||||
|
"unicode": "e64b",
|
||||||
|
"unicode_decimal": 58955
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076516",
|
||||||
|
"name": "online",
|
||||||
|
"font_class": "online",
|
||||||
|
"unicode": "e64d",
|
||||||
|
"unicode_decimal": 58957
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076518",
|
||||||
|
"name": "pdf",
|
||||||
|
"font_class": "pdf",
|
||||||
|
"unicode": "e64f",
|
||||||
|
"unicode_decimal": 58959
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076519",
|
||||||
|
"name": "redis",
|
||||||
|
"font_class": "redis",
|
||||||
|
"unicode": "e650",
|
||||||
|
"unicode_decimal": 58960
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076520",
|
||||||
|
"name": "size",
|
||||||
|
"font_class": "size",
|
||||||
|
"unicode": "e651",
|
||||||
|
"unicode_decimal": 58961
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076521",
|
||||||
|
"name": "search",
|
||||||
|
"font_class": "search",
|
||||||
|
"unicode": "e652",
|
||||||
|
"unicode_decimal": 58962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076522",
|
||||||
|
"name": "server",
|
||||||
|
"font_class": "server",
|
||||||
|
"unicode": "e653",
|
||||||
|
"unicode_decimal": 58963
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076525",
|
||||||
|
"name": "select",
|
||||||
|
"font_class": "select",
|
||||||
|
"unicode": "e656",
|
||||||
|
"unicode_decimal": 58966
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076526",
|
||||||
|
"name": "question",
|
||||||
|
"font_class": "question",
|
||||||
|
"unicode": "e657",
|
||||||
|
"unicode_decimal": 58967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076527",
|
||||||
|
"name": "rate",
|
||||||
|
"font_class": "rate",
|
||||||
|
"unicode": "e658",
|
||||||
|
"unicode_decimal": 58968
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076529",
|
||||||
|
"name": "monitor",
|
||||||
|
"font_class": "monitor",
|
||||||
|
"unicode": "e65a",
|
||||||
|
"unicode_decimal": 58970
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076530",
|
||||||
|
"name": "source",
|
||||||
|
"font_class": "source",
|
||||||
|
"unicode": "e65b",
|
||||||
|
"unicode_decimal": 58971
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076532",
|
||||||
|
"name": "role",
|
||||||
|
"font_class": "role",
|
||||||
|
"unicode": "e65d",
|
||||||
|
"unicode_decimal": 58973
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076533",
|
||||||
|
"name": "shopping",
|
||||||
|
"font_class": "shopping",
|
||||||
|
"unicode": "e65e",
|
||||||
|
"unicode_decimal": 58974
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076534",
|
||||||
|
"name": "skill",
|
||||||
|
"font_class": "skill",
|
||||||
|
"unicode": "e65f",
|
||||||
|
"unicode_decimal": 58975
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076535",
|
||||||
|
"name": "number",
|
||||||
|
"font_class": "number",
|
||||||
|
"unicode": "e660",
|
||||||
|
"unicode_decimal": 58976
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076366",
|
||||||
|
"name": "404",
|
||||||
|
"font_class": "a-404",
|
||||||
|
"unicode": "e622",
|
||||||
|
"unicode_decimal": 58914
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076470",
|
||||||
|
"name": "email",
|
||||||
|
"font_class": "email",
|
||||||
|
"unicode": "e623",
|
||||||
|
"unicode_decimal": 58915
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076471",
|
||||||
|
"name": "example",
|
||||||
|
"font_class": "example",
|
||||||
|
"unicode": "e624",
|
||||||
|
"unicode_decimal": 58916
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076472",
|
||||||
|
"name": "error",
|
||||||
|
"font_class": "error",
|
||||||
|
"unicode": "e625",
|
||||||
|
"unicode_decimal": 58917
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076473",
|
||||||
|
"name": "excel",
|
||||||
|
"font_class": "excel",
|
||||||
|
"unicode": "e626",
|
||||||
|
"unicode_decimal": 58918
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076474",
|
||||||
|
"name": "education",
|
||||||
|
"font_class": "education",
|
||||||
|
"unicode": "e627",
|
||||||
|
"unicode_decimal": 58919
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076475",
|
||||||
|
"name": "eye-open",
|
||||||
|
"font_class": "eye-open",
|
||||||
|
"unicode": "e628",
|
||||||
|
"unicode_decimal": 58920
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076476",
|
||||||
|
"name": "eye",
|
||||||
|
"font_class": "eye",
|
||||||
|
"unicode": "e629",
|
||||||
|
"unicode_decimal": 58921
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076480",
|
||||||
|
"name": "github",
|
||||||
|
"font_class": "github",
|
||||||
|
"unicode": "e62b",
|
||||||
|
"unicode_decimal": 58923
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076481",
|
||||||
|
"name": "guide",
|
||||||
|
"font_class": "guide",
|
||||||
|
"unicode": "e62c",
|
||||||
|
"unicode_decimal": 58924
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076482",
|
||||||
|
"name": "gonggao",
|
||||||
|
"font_class": "gonggao",
|
||||||
|
"unicode": "e62d",
|
||||||
|
"unicode_decimal": 58925
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076483",
|
||||||
|
"name": "icon1",
|
||||||
|
"font_class": "icon1",
|
||||||
|
"unicode": "e62e",
|
||||||
|
"unicode_decimal": 58926
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076484",
|
||||||
|
"name": "fullscreen",
|
||||||
|
"font_class": "fullscreen",
|
||||||
|
"unicode": "e62f",
|
||||||
|
"unicode_decimal": 58927
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076485",
|
||||||
|
"name": "icon",
|
||||||
|
"font_class": "icon",
|
||||||
|
"unicode": "e630",
|
||||||
|
"unicode_decimal": 58928
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076486",
|
||||||
|
"name": "image",
|
||||||
|
"font_class": "image",
|
||||||
|
"unicode": "e631",
|
||||||
|
"unicode_decimal": 58929
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076487",
|
||||||
|
"name": "form",
|
||||||
|
"font_class": "form",
|
||||||
|
"unicode": "e632",
|
||||||
|
"unicode_decimal": 58930
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076491",
|
||||||
|
"name": "job",
|
||||||
|
"font_class": "job",
|
||||||
|
"unicode": "e635",
|
||||||
|
"unicode_decimal": 58933
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076284",
|
||||||
|
"name": "cascader",
|
||||||
|
"font_class": "cascader",
|
||||||
|
"unicode": "e603",
|
||||||
|
"unicode_decimal": 58883
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076315",
|
||||||
|
"name": "alipay",
|
||||||
|
"font_class": "alipay",
|
||||||
|
"unicode": "e604",
|
||||||
|
"unicode_decimal": 58884
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076316",
|
||||||
|
"name": "anq",
|
||||||
|
"font_class": "anq",
|
||||||
|
"unicode": "e605",
|
||||||
|
"unicode_decimal": 58885
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076317",
|
||||||
|
"name": "backup",
|
||||||
|
"font_class": "backup",
|
||||||
|
"unicode": "e606",
|
||||||
|
"unicode_decimal": 58886
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076318",
|
||||||
|
"name": "bug",
|
||||||
|
"font_class": "bug",
|
||||||
|
"unicode": "e607",
|
||||||
|
"unicode_decimal": 58887
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076321",
|
||||||
|
"name": "button",
|
||||||
|
"font_class": "button",
|
||||||
|
"unicode": "e609",
|
||||||
|
"unicode_decimal": 58889
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076323",
|
||||||
|
"name": "chain",
|
||||||
|
"font_class": "chain",
|
||||||
|
"unicode": "e60b",
|
||||||
|
"unicode_decimal": 58891
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076324",
|
||||||
|
"name": "chart",
|
||||||
|
"font_class": "chart",
|
||||||
|
"unicode": "e60c",
|
||||||
|
"unicode_decimal": 58892
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076325",
|
||||||
|
"name": "checkbox",
|
||||||
|
"font_class": "checkbox",
|
||||||
|
"unicode": "e60d",
|
||||||
|
"unicode_decimal": 58893
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076326",
|
||||||
|
"name": "clipboard",
|
||||||
|
"font_class": "clipboard",
|
||||||
|
"unicode": "e60e",
|
||||||
|
"unicode_decimal": 58894
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076327",
|
||||||
|
"name": "codeConsole",
|
||||||
|
"font_class": "codeConsole",
|
||||||
|
"unicode": "e60f",
|
||||||
|
"unicode_decimal": 58895
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076328",
|
||||||
|
"name": "code",
|
||||||
|
"font_class": "code",
|
||||||
|
"unicode": "e610",
|
||||||
|
"unicode_decimal": 58896
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076329",
|
||||||
|
"name": "color",
|
||||||
|
"font_class": "color",
|
||||||
|
"unicode": "e611",
|
||||||
|
"unicode_decimal": 58897
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076330",
|
||||||
|
"name": "database",
|
||||||
|
"font_class": "database",
|
||||||
|
"unicode": "e612",
|
||||||
|
"unicode_decimal": 58898
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076331",
|
||||||
|
"name": "component",
|
||||||
|
"font_class": "component",
|
||||||
|
"unicode": "e613",
|
||||||
|
"unicode_decimal": 58899
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076332",
|
||||||
|
"name": "dashboard",
|
||||||
|
"font_class": "dashboard",
|
||||||
|
"unicode": "e614",
|
||||||
|
"unicode_decimal": 58900
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076333",
|
||||||
|
"name": "date",
|
||||||
|
"font_class": "date",
|
||||||
|
"unicode": "e615",
|
||||||
|
"unicode_decimal": 58901
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076334",
|
||||||
|
"name": "deploy",
|
||||||
|
"font_class": "deploy",
|
||||||
|
"unicode": "e616",
|
||||||
|
"unicode_decimal": 58902
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076335",
|
||||||
|
"name": "develop",
|
||||||
|
"font_class": "develop",
|
||||||
|
"unicode": "e617",
|
||||||
|
"unicode_decimal": 58903
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076337",
|
||||||
|
"name": "dept",
|
||||||
|
"font_class": "dept",
|
||||||
|
"unicode": "e619",
|
||||||
|
"unicode_decimal": 58905
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076340",
|
||||||
|
"name": "dictionary",
|
||||||
|
"font_class": "dictionary",
|
||||||
|
"unicode": "e61a",
|
||||||
|
"unicode_decimal": 58906
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076341",
|
||||||
|
"name": "documentation",
|
||||||
|
"font_class": "documentation",
|
||||||
|
"unicode": "e61b",
|
||||||
|
"unicode_decimal": 58907
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076342",
|
||||||
|
"name": "doc",
|
||||||
|
"font_class": "doc",
|
||||||
|
"unicode": "e61c",
|
||||||
|
"unicode_decimal": 58908
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076343",
|
||||||
|
"name": "download",
|
||||||
|
"font_class": "download",
|
||||||
|
"unicode": "e61d",
|
||||||
|
"unicode_decimal": 58909
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076344",
|
||||||
|
"name": "dict",
|
||||||
|
"font_class": "dict",
|
||||||
|
"unicode": "e61e",
|
||||||
|
"unicode_decimal": 58910
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35076351",
|
||||||
|
"name": "edit",
|
||||||
|
"font_class": "edit",
|
||||||
|
"unicode": "e620",
|
||||||
|
"unicode_decimal": 58912
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35075963",
|
||||||
|
"name": "app",
|
||||||
|
"font_class": "app",
|
||||||
|
"unicode": "e602",
|
||||||
|
"unicode_decimal": 58882
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
src/assets/iconfont/iconfont.ttf
Normal file
BIN
src/assets/iconfont/iconfont.woff
Normal file
BIN
src/assets/iconfont/iconfont.woff2
Normal file
BIN
src/assets/icons/gitee-fill-round.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
src/assets/icons/github-fill.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
1
src/assets/icons/svg/build.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg>
|
After Width: | Height: | Size: 954 B |
1
src/assets/icons/svg/exit-fullscreen.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
1
src/assets/icons/svg/gitee.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1682510872430" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1825" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M512 1024C229.222 1024 0 794.778 0 512S229.222 0 512 0s512 229.222 512 512-229.222 512-512 512z m259.149-568.883h-290.74a25.293 25.293 0 0 0-25.292 25.293l-0.026 63.206c0 13.952 11.315 25.293 25.267 25.293h177.024c13.978 0 25.293 11.315 25.293 25.267v12.646a75.853 75.853 0 0 1-75.853 75.853h-240.23a25.293 25.293 0 0 1-25.267-25.293V417.203a75.853 75.853 0 0 1 75.827-75.853h353.946a25.293 25.293 0 0 0 25.267-25.292l0.077-63.207a25.293 25.293 0 0 0-25.268-25.293H417.152a189.62 189.62 0 0 0-189.62 189.645V771.15c0 13.977 11.316 25.293 25.294 25.293h372.94a170.65 170.65 0 0 0 170.65-170.65V480.384a25.293 25.293 0 0 0-25.293-25.267z" fill="#C71D23" p-id="1826"></path></svg>
|
After Width: | Height: | Size: 1010 B |
1
src/assets/icons/svg/validCode.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/icons/wechat-fill.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
100
src/assets/images/exception/403.svg
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 456.01 262.12">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1,.cls-2,.cls-20,.cls-22,.cls-23,.cls-3,.cls-4,.cls-5,.cls-6{fill:none;stroke-miterlimit:10;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke-width:2px;}.cls-1{stroke:url(#未命名的渐变_26);}.cls-2{stroke:url(#未命名的渐变_26-2);}.cls-3{stroke:url(#未命名的渐变_26-3);}.cls-4{stroke:url(#未命名的渐变_26-4);}.cls-5{stroke:url(#未命名的渐变_26-5);}.cls-6{stroke:url(#未命名的渐变_26-6);}.cls-10,.cls-11,.cls-12,.cls-7,.cls-9{opacity:0.4;}.cls-7{fill:url(#未命名的渐变_26-7);}.cls-8{opacity:0.7;}.cls-9{fill:url(#未命名的渐变_26-8);}.cls-10{fill:url(#未命名的渐变_26-9);}.cls-11{fill:url(#未命名的渐变_26-10);}.cls-12{fill:url(#未命名的渐变_26-11);}.cls-13{fill:#2c94ee;}.cls-14{fill:#8cd7ff;}.cls-15{fill:#40a8f5;}.cls-16{fill:#fff;}.cls-17{fill:#ffb056;}.cls-18{fill:#398eed;}.cls-19{fill:#ffeed2;}.cls-20{stroke:#000;stroke-width:0.23px;}.cls-21{fill:#ebfcff;}.cls-22{stroke:#e49056;stroke-width:0.26px;}.cls-23{stroke:#4986d9;stroke-width:0.13px;}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="未命名的渐变_26" x1="1" y1="91.35" x2="1" y2="181.12" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#81cfff"/>
|
||||||
|
<stop offset="1" stop-color="#5ecfff" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="未命名的渐变_26-2" x1="455.01" y1="72.11" x2="455.01" y2="161.88" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-3" x1="40.9" y1="143.88" x2="40.9" y2="199.51" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-4" x1="64.97" y1="95.36" x2="64.97" y2="123.17" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-5" x1="397.23" y1="104.2" x2="397.23" y2="132.02" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-6" x1="424.75" y1="133.49" x2="424.75" y2="189.13" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-7" x1="232.75" y1="224.43" x2="232.75" y2="262.12" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-8" x1="349.36" y1="26.68" x2="349.36" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-9" x1="201.45" y1="55.61" x2="201.45" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-10" x1="122.98" y1="26.68" x2="122.98" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-11" x1="273.51" y1="0" x2="273.51" y2="209.54" xlink:href="#未命名的渐变_26"/>
|
||||||
|
</defs>
|
||||||
|
<title>无访问权限</title>
|
||||||
|
<g id="图层_2" data-name="图层 2">
|
||||||
|
<g id="图层_1-2" data-name="图层 1">
|
||||||
|
<line class="cls-1" x1="1" y1="91.35" x2="1" y2="181.12"/>
|
||||||
|
<line class="cls-2" x1="455.01" y1="72.11" x2="455.01" y2="161.88"/>
|
||||||
|
<line class="cls-3" x1="40.9" y1="143.88" x2="40.9" y2="199.51"/>
|
||||||
|
<line class="cls-4" x1="64.97" y1="95.36" x2="64.97" y2="123.17"/>
|
||||||
|
<line class="cls-5" x1="397.23" y1="104.2" x2="397.23" y2="132.02"/>
|
||||||
|
<line class="cls-6" x1="424.75" y1="133.49" x2="424.75" y2="189.13"/>
|
||||||
|
<path class="cls-7" d="M412.28,262.12c-23-23-61-37.69-179.53-37.69S76.24,239.1,53.21,262.12Z"/>
|
||||||
|
<g class="cls-8">
|
||||||
|
<path class="cls-9"
|
||||||
|
d="M380.66,26.68H318.07a2.71,2.71,0,0,0-2.82,2.59V201.44a2.71,2.71,0,0,0,2.82,2.59h62.59a2.72,2.72,0,0,0,2.82-2.59V29.27A2.72,2.72,0,0,0,380.66,26.68ZM328.3,147a.9.9,0,0,1-.95.87h-3.6a.9.9,0,0,1-.95-.87V127.27a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.23a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V97a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V66.8a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V36.56a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87ZM340,147a.9.9,0,0,1-.94.87h-3.61a.91.91,0,0,1-.95-.87V127.27a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V97a.92.92,0,0,1,.95-.87h3.61A.91.91,0,0,1,340,97Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V66.8a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V36.56a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87ZM351.7,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM363.4,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM375.11,147a.91.91,0,0,1-.95.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.23a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Z"/>
|
||||||
|
<path class="cls-10"
|
||||||
|
d="M231.1,55.61H171.8A2.71,2.71,0,0,0,169,58.2V201.44A2.71,2.71,0,0,0,171.8,204h59.3a2.71,2.71,0,0,0,2.82-2.59V58.2A2.71,2.71,0,0,0,231.1,55.61ZM182.47,159.37a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1v-5.22a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V115.5a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V89.73A1.16,1.16,0,0,1,186,88.62h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11V76.85A1.16,1.16,0,0,1,186,75.74h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V64A1.16,1.16,0,0,1,186,62.85h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4A1.16,1.16,0,0,1,202.63,64Zm25.21,90.19a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Z"/>
|
||||||
|
<path class="cls-11"
|
||||||
|
d="M161.13,26.68H84.83A2.71,2.71,0,0,0,82,29.27V201.44A2.71,2.71,0,0,0,84.83,204h76.3a2.71,2.71,0,0,0,2.82-2.59V29.27A2.71,2.71,0,0,0,161.13,26.68ZM154.34,161a1.16,1.16,0,0,1-1.2,1.11H92.83A1.16,1.16,0,0,1,91.62,161v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1v-5.22A1.16,1.16,0,0,1,92.83,140h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V97a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V82.35a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V67.68a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V53a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V38.32a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Z"/>
|
||||||
|
<path class="cls-12"
|
||||||
|
d="M306.21,0H240.82a2.51,2.51,0,0,0-2.42,2.59V206.94a2.51,2.51,0,0,0,2.42,2.6h65.39a2.51,2.51,0,0,0,2.41-2.6V2.59A2.51,2.51,0,0,0,306.21,0Zm-5.82,134.28a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1v-5.22a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11v-5.22a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V99.71a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V85a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V70.35a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V55.68a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V41a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V26.32a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V11.65a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Z"/>
|
||||||
|
</g>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M315.5,74.68a5.32,5.32,0,0,0-3.58-1.38H162.32a6.41,6.41,0,0,0-5.55,3.21h0a3.34,3.34,0,0,1,2.16-.78H310.77a3.42,3.42,0,0,1,3.4,3.4V185.35a3.36,3.36,0,0,1-1.32,2.68,6.93,6.93,0,0,0,4.41-6.46V78.63A5.29,5.29,0,0,0,315.5,74.68Z"/>
|
||||||
|
<polygon class="cls-14"
|
||||||
|
points="293.51 81.67 292.41 81.67 292.41 83.34 294.61 83.34 294.61 82.32 294.61 81.67 293.51 81.67"/>
|
||||||
|
<polygon class="cls-14"
|
||||||
|
points="295.72 80.65 295.72 82.32 294.61 82.32 294.61 81.67 293.51 81.67 293.51 80.65 295.72 80.65"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M307.05,78.94A3.06,3.06,0,1,1,304,82,3.06,3.06,0,0,1,307.05,78.94Zm.71,3.06,1-1-.71-.71-1,1-1-1-.71.71,1,1-1,1,.71.71,1-1,1,1,.71-.71Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M294.13,78.94A3.06,3.06,0,1,1,291.08,82,3.06,3.06,0,0,1,294.13,78.94Zm1.59,3.38V80.65h-2.21v1h-1.1v1.67h2.2v-1Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M281.22,78.94A3.06,3.06,0,1,1,278.16,82,3.05,3.05,0,0,1,281.22,78.94Zm1.51,3.56v-1h-3v1Z"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M314.17,79.14v8.29H155.53V79.14a3.41,3.41,0,0,1,3.4-3.4H310.77a3.42,3.42,0,0,1,3.4,3.4ZM310.11,82a3.06,3.06,0,1,0-3.06,3A3.06,3.06,0,0,0,310.11,82Zm-12.92,0a3.06,3.06,0,1,0-3.06,3A3.06,3.06,0,0,0,297.19,82Zm-12.92,0a3.06,3.06,0,1,0-3,3A3.05,3.05,0,0,0,284.27,82Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M238.61,136.26a3.76,3.76,0,0,1-2.33,3.47V146a.37.37,0,0,1-.37.36h-2.12a.36.36,0,0,1-.36-.36v-6.26a3.76,3.76,0,1,1,5.18-3.47Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M314.17,87.43v97.92a3.42,3.42,0,0,1-3.4,3.4H158.93a3.4,3.4,0,0,1-3.4-3.4V87.43Zm-59,63.87V128a3.55,3.55,0,0,0-3.55-3.55h-1.8v-4.68a14.93,14.93,0,1,0-29.86,0v4.68h-1.8a3.55,3.55,0,0,0-3.55,3.55V151.3a3.56,3.56,0,0,0,3.55,3.56h33.46A3.56,3.56,0,0,0,255.13,151.3Z"/>
|
||||||
|
<polygon class="cls-15"
|
||||||
|
points="308.8 80.96 307.76 82 308.8 83.03 308.09 83.74 307.05 82.7 306.02 83.74 305.31 83.03 306.34 82 305.31 80.96 306.02 80.25 307.05 81.29 308.09 80.25 308.8 80.96"/>
|
||||||
|
<rect class="cls-15" x="279.71" y="81.5" width="3.02" height="1"/>
|
||||||
|
<path class="cls-16"
|
||||||
|
d="M251.58,124.4h-1.8v-4.68a14.93,14.93,0,1,0-29.86,0v4.68h-1.8a3.55,3.55,0,0,0-3.55,3.55V151.3a3.56,3.56,0,0,0,3.55,3.56h33.46a3.56,3.56,0,0,0,3.55-3.56V128A3.55,3.55,0,0,0,251.58,124.4Zm-15.3,15.33V146a.37.37,0,0,1-.37.36h-2.12a.36.36,0,0,1-.36-.36v-6.26a3.76,3.76,0,1,1,2.85,0ZM224.9,124.4v-4.68a9.95,9.95,0,0,1,19.9,0v4.68Z"/>
|
||||||
|
<path class="cls-14" d="M244.8,119.72v4.68H224.9v-4.68a9.95,9.95,0,0,1,19.9,0Z"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M295.87,80.5h-2.51v1h-1.1v2h2.5v-1h1.11Zm-1.41,2.69h-1.9V81.81h1.9Zm1.11-1h-.81v-.65h-1.1v-.73h1.91Z"/>
|
||||||
|
<path d="M203.58,147.25c.06.14.44-.84.44-.84l.09.84.6-.58.26.7.35-.84s.08.15.35.72c.11-.26.8-.22,1.61-.72a3.06,3.06,0,0,0,1-2.59c-.1-.58-.66-1.12-.34-1.48a.67.67,0,0,1,.92-.15c.23.14.49-.17,1.44-.49l.25-.07c1.16-.34,1.06-1.15,1.24-2.29s-1.16-2.56-2.24-3.51a7,7,0,0,0-5.42-1.06c-1.58.49-3.16.9-3.77,4.44a7.67,7.67,0,0,0,1.52,6.37,3.92,3.92,0,0,0,1.18.88A1,1,0,0,1,203.58,147.25Z"/>
|
||||||
|
<path class="cls-17"
|
||||||
|
d="M206.25,232.22c-.33-.73-.59-1.63.55-1.13l.1,0,0-5.25a4.21,4.21,0,0,0-.93.73,31.18,31.18,0,0,0-2.71,2.81c0-.21.05-.39.06-.48,0-.33-.46-.71-.89-.18s-2.71.62-4.06.38a2.8,2.8,0,0,1-.48-.12c-1.18-.39-.84.49-.45,1.18s.44,1.67.57,3.61,2.26,2.4,3.85,2.57c1.4.16,2.37-1.3,4.56-3.27A3.14,3.14,0,0,0,206.25,232.22Z"/>
|
||||||
|
<path class="cls-17"
|
||||||
|
d="M206.47,233.11a24.12,24.12,0,0,1,0,2.76c-.06,1.95,2,2.59,3.59,2.92s2.77-1.47,5.85-3.56,5.51-6,4.48-7c-.94-.63-3.41-.22-5.32,1.25a31.79,31.79,0,0,0-3,2.54h0c0-.21.09-.38.11-.47.06-.33-.39-.75-.88-.26s-3.24.34-4.44-.12l-.1,0c-1.14-.5-.88.4-.55,1.13A3.14,3.14,0,0,1,206.47,233.11Z"/>
|
||||||
|
<path class="cls-18"
|
||||||
|
d="M197.24,182.41l1.23,23.46-.05,23.27c1.35.24,3.67.09,4.06-.38l1.12-21.62,1.08-17a.71.71,0,0,1,.77-.68.8.8,0,0,1,.47.22.72.72,0,0,1,.2.47l1,18.93L207,225.88l0,5.25c1.2.46,4,.59,4.44.12l1.79-23.48.34-23C209.7,185.44,199.19,182.68,197.24,182.41Z"/>
|
||||||
|
<path class="cls-17"
|
||||||
|
d="M188.66,150.58l-.34,7.12,7.18.81s.13,18.8-1.51,23c.89.42,15.71,3.89,19.48,3.27a3.78,3.78,0,0,0,1.09-.3c-.29-1.68,1.18-22.4,1.18-22.4s3.08,2.26,4.81,3.58a4.68,4.68,0,0,0,.79-1.43h0a28.57,28.57,0,0,0,1.07-5.74L216.55,153a3.32,3.32,0,0,0-1.75-.88,39.71,39.71,0,0,1-5.66-1.29c-.81,1-6,1.61-7.16-.22Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M221.35,164.27l2,1.71a1,1,0,0,0,1.46-.22l8.65-13.51s2.82-2.35,2.8-3.82c0-1-1.52-2.37-1.78-2.42s.17-1.35.2-2.8-.49-1.7-1-1.7,0,.48,0,2-1.77,6.11-2.28,7L224,160l-1.58-1.5A28.57,28.57,0,0,1,221.35,164.27Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M208.26,143.94a3.06,3.06,0,0,1-1,2.59c-.81.5-1.5.46-1.61.72-.27-.57-.35-.72-.35-.72l-.35.84-.26-.7-.6.58-.09-.84s-.38,1-.44.84a1,1,0,0,0-.54-.67c.13,1.4.49,3.77-.49,3.92l-.57.08c1.14,1.83,6.35,1.24,7.16.22a2.47,2.47,0,0,1-1.23-.71c-.63-1.08-.82-3,0-3.46a6.31,6.31,0,0,0,1.85-2.33,4.7,4.7,0,0,0,.2-1.41c0-.53.15-.54.29-1.06h0c-.95.32-1.21.63-1.44.49a.67.67,0,0,0-.92.15C207.6,142.82,208.16,143.36,208.26,143.94Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M203,146.58a3.92,3.92,0,0,1-1.18-.88,7.67,7.67,0,0,1-1.52-6.37c.61-3.54,2.19-4,3.77-4.44a7,7,0,0,1,5.42,1.06c1.08,1,2.38,2.4,2.24,3.51s-.08,1.95-1.24,2.29l-.25.07c-.95.32-1.21.63-1.44.49a.67.67,0,0,0-.92.15c-.32.36.24.9.34,1.48a3.06,3.06,0,0,1-1,2.59c-.81.5-1.5.46-1.61.72-.27-.57-.35-.72-.35-.72l-.35.84-.26-.7-.6.58-.09-.84s-.38,1-.44.84A1,1,0,0,0,203,146.58Z"/>
|
||||||
|
<path class="cls-21"
|
||||||
|
d="M201.91,236.38c-1.21-.13-2.74-.42-3.45-1.42-.05.94,0,.9,1.1,1.43s2.77,1.15,3.81.39a33.66,33.66,0,0,0,3.14-3.06h0c0-.22,0-.42,0-.6C204.28,235.08,203.31,236.54,201.91,236.38Z"/>
|
||||||
|
<path class="cls-21"
|
||||||
|
d="M208.69,239a5.08,5.08,0,0,0,3,.08c1.05-.24,3-2.7,4.28-3.43a15.2,15.2,0,0,0,4.39-4.7c1.09-1.81.54-2.25.19-2.48.44,1.36-1.84,4.8-4.67,6.73-3.08,2.09-4.29,3.88-5.85,3.56-1.23-.26-2.78-.71-3.36-1.85C206.42,238.45,207.7,238.67,208.69,239Z"/>
|
||||||
|
<path class="cls-22" d="M206.9,231.13l-.1,0c-1.14-.5-.88.4-.55,1.13a3.14,3.14,0,0,1,.22.89"/>
|
||||||
|
<path class="cls-22" d="M212.64,233.14c-.72.2-.64-.59-.53-1.16"/>
|
||||||
|
<path class="cls-22" d="M203.94,230.52c-.69.27-.69-.52-.63-1.1"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M220.58,228.5h0c.35.23.9.67-.19,2.48a15.2,15.2,0,0,1-4.39,4.7c-1.31.73-3.23,3.19-4.28,3.43a5.08,5.08,0,0,1-3-.08c-1-.36-2.27-.58-2-2.09"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M198.46,235h0c-.05.94,0,.9,1.1,1.43s2.77,1.15,3.81.39a33.66,33.66,0,0,0,3.14-3.06h0"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M202.57,136.72c.21.61.72,2.29-.44,2.73s-2.64,1.42-2.7,1.85-.2,1.06-.67,1.27l-1.31-1.46c.69-1.08,3.37-4.75,3.73-4.77S202.36,136.12,202.57,136.72Z"/>
|
||||||
|
<path class="cls-19" d="M197.45,141.11l1.31,1.46-7.79,8h-2.31l-4.32.11a2.25,2.25,0,0,0-.74.12Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M188.66,150.58l-.23,4.95-4.31-.43a2.21,2.21,0,0,1-1.42-.71,2.17,2.17,0,0,1-.58-1.47,2.22,2.22,0,0,1,1.48-2.11,2.25,2.25,0,0,1,.74-.12Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 20 KiB |
115
src/assets/images/exception/404.svg
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 456.01 262.12">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1,.cls-2,.cls-24,.cls-25,.cls-3,.cls-4,.cls-5,.cls-6{fill:none;stroke-miterlimit:10;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke-width:2px;}.cls-1{stroke:url(#未命名的渐变_26);}.cls-2{stroke:url(#未命名的渐变_26-2);}.cls-3{stroke:url(#未命名的渐变_26-3);}.cls-4{stroke:url(#未命名的渐变_26-4);}.cls-5{stroke:url(#未命名的渐变_26-5);}.cls-6{stroke:url(#未命名的渐变_26-6);}.cls-10,.cls-11,.cls-12,.cls-7,.cls-9{opacity:0.4;}.cls-7{fill:url(#未命名的渐变_26-7);}.cls-8{opacity:0.7;}.cls-9{fill:url(#未命名的渐变_26-8);}.cls-10{fill:url(#未命名的渐变_26-9);}.cls-11{fill:url(#未命名的渐变_26-10);}.cls-12{fill:url(#未命名的渐变_26-11);}.cls-13{fill:#67c8ff;}.cls-14{fill:#8cd7ff;}.cls-15{fill:#b0e7ff;}.cls-16{fill:#728cb9;}.cls-17{fill:#7798b9;}.cls-18{fill:#a4c0d9;}.cls-19{fill:#ebfcff;}.cls-20{fill:#ffb056;}.cls-21{fill:#257fba;}.cls-22{fill:#398eed;}.cls-23{fill:#ffeed2;}.cls-24{stroke:#e49056;stroke-width:0.26px;}.cls-25{stroke:#4986d9;stroke-width:0.1px;}.cls-26{fill:#e55c5c;opacity:0.2;}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="未命名的渐变_26" x1="1" y1="91.35" x2="1" y2="181.12" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#81cfff"/>
|
||||||
|
<stop offset="1" stop-color="#5ecfff" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="未命名的渐变_26-2" x1="455.01" y1="72.11" x2="455.01" y2="161.88" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-3" x1="40.9" y1="143.88" x2="40.9" y2="199.51" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-4" x1="64.97" y1="95.36" x2="64.97" y2="123.17" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-5" x1="397.23" y1="104.2" x2="397.23" y2="132.02" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-6" x1="424.75" y1="133.49" x2="424.75" y2="189.13" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-7" x1="232.75" y1="224.43" x2="232.75" y2="262.12" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-8" x1="349.36" y1="26.68" x2="349.36" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-9" x1="201.45" y1="55.61" x2="201.45" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-10" x1="122.98" y1="26.68" x2="122.98" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-11" x1="273.51" y1="0" x2="273.51" y2="209.54" xlink:href="#未命名的渐变_26"/>
|
||||||
|
</defs>
|
||||||
|
<title>404</title>
|
||||||
|
<g id="图层_2" data-name="图层 2">
|
||||||
|
<g id="图层_1-2" data-name="图层 1">
|
||||||
|
<line class="cls-1" x1="1" y1="91.35" x2="1" y2="181.12"/>
|
||||||
|
<line class="cls-2" x1="455.01" y1="72.11" x2="455.01" y2="161.88"/>
|
||||||
|
<line class="cls-3" x1="40.9" y1="143.88" x2="40.9" y2="199.51"/>
|
||||||
|
<line class="cls-4" x1="64.97" y1="95.36" x2="64.97" y2="123.17"/>
|
||||||
|
<line class="cls-5" x1="397.23" y1="104.2" x2="397.23" y2="132.02"/>
|
||||||
|
<line class="cls-6" x1="424.75" y1="133.49" x2="424.75" y2="189.13"/>
|
||||||
|
<path class="cls-7" d="M412.28,262.12c-23-23-61-37.69-179.53-37.69S76.24,239.1,53.21,262.12Z"/>
|
||||||
|
<g class="cls-8">
|
||||||
|
<path class="cls-9"
|
||||||
|
d="M380.66,26.68H318.07a2.71,2.71,0,0,0-2.82,2.59V201.44a2.71,2.71,0,0,0,2.82,2.59h62.59a2.72,2.72,0,0,0,2.82-2.59V29.27A2.72,2.72,0,0,0,380.66,26.68ZM328.3,147a.9.9,0,0,1-.95.87h-3.6a.9.9,0,0,1-.95-.87V127.27a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.23a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V97a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V66.8a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V36.56a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87ZM340,147a.9.9,0,0,1-.94.87h-3.61a.91.91,0,0,1-.95-.87V127.27a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V97a.92.92,0,0,1,.95-.87h3.61A.91.91,0,0,1,340,97Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V66.8a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V36.56a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87ZM351.7,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM363.4,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM375.11,147a.91.91,0,0,1-.95.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.23a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Z"/>
|
||||||
|
<path class="cls-10"
|
||||||
|
d="M231.1,55.61H171.8A2.71,2.71,0,0,0,169,58.2V201.44A2.71,2.71,0,0,0,171.8,204h59.3a2.71,2.71,0,0,0,2.82-2.59V58.2A2.71,2.71,0,0,0,231.1,55.61ZM182.47,159.37a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1v-5.22a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V115.5a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V89.73A1.16,1.16,0,0,1,186,88.62h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11V76.85A1.16,1.16,0,0,1,186,75.74h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V64A1.16,1.16,0,0,1,186,62.85h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4A1.16,1.16,0,0,1,202.63,64Zm25.21,90.19a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Z"/>
|
||||||
|
<path class="cls-11"
|
||||||
|
d="M161.13,26.68H84.83A2.71,2.71,0,0,0,82,29.27V201.44A2.71,2.71,0,0,0,84.83,204h76.3a2.71,2.71,0,0,0,2.82-2.59V29.27A2.71,2.71,0,0,0,161.13,26.68ZM154.34,161a1.16,1.16,0,0,1-1.2,1.11H92.83A1.16,1.16,0,0,1,91.62,161v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1v-5.22A1.16,1.16,0,0,1,92.83,140h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V97a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V82.35a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V67.68a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V53a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V38.32a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Z"/>
|
||||||
|
<path class="cls-12"
|
||||||
|
d="M306.21,0H240.82a2.51,2.51,0,0,0-2.42,2.59V206.94a2.51,2.51,0,0,0,2.42,2.6h65.39a2.51,2.51,0,0,0,2.41-2.6V2.59A2.51,2.51,0,0,0,306.21,0Zm-5.82,134.28a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1v-5.22a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11v-5.22a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V99.71a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V85a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V70.35a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V55.68a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V41a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V26.32a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V11.65a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Z"/>
|
||||||
|
</g>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M182.43,170.83l.09.09a3.44,3.44,0,0,1,.41.44l.12.15a6,6,0,0,1,.39.59.93.93,0,0,0,.05.1,5.36,5.36,0,0,1,.32.73h0a6.39,6.39,0,0,1,.22.78c0,.06,0,.12,0,.19a8.08,8.08,0,0,1,.14.9V175c0,.31,0,.63,0,1V164.28c0-.28,0-.55,0-.82v-.14h0c0-.26-.06-.51-.11-.75l0-.14c0-.06,0-.13,0-.19L184,162c-.05-.17-.1-.33-.16-.49v0h0c-.06-.16-.12-.31-.19-.46s-.09-.17-.13-.25a.93.93,0,0,0-.05-.1.59.59,0,0,1,0-.08,3.74,3.74,0,0,0-.27-.42l-.08-.1-.12-.15c-.05-.06-.1-.13-.16-.19a3,3,0,0,0-.25-.25l-.09-.09A4.06,4.06,0,0,0,182,159l-.11-.07-.12-.07-.18-.12-.5-.23c-.26-.11-.53-.22-.81-.32a2.46,2.46,0,0,1-.29-.09l-.54-.16h0l-.65-.16-.34-.09c-.32-.06-.65-.13-1-.18h0c-.36-.06-.73-.11-1.12-.15l-.39,0-.8-.07H175l-.74,0-.4,0-1.26,0h-2.95v11.49h2.95c.43,0,.85,0,1.26,0l.4,0,.8,0,.79.07.4,0,1.12.16h0l1,.19.34.08.65.16.58.18.29.09c.28.1.55.2.81.31a6.23,6.23,0,0,1,.68.36l.12.07A4.73,4.73,0,0,1,182.43,170.83Z"/>
|
||||||
|
<rect class="cls-13" x="122.87" y="157.13" width="29.56" height="11.49"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M169.61,106.86q0-.52,0-1c0-.08,0-.15,0-.23s0-.35,0-.52a2.51,2.51,0,0,0,0-.27c0-.25-.06-.49-.1-.73a3.31,3.31,0,0,0,0-.33,1.89,1.89,0,0,1-.05-.23l-.12-.52c0-.11,0-.23-.07-.34a2.41,2.41,0,0,1-.08-.25c0-.14-.08-.27-.13-.4a2,2,0,0,0-.08-.26c0-.12-.09-.23-.14-.35s-.08-.21-.13-.31l0-.15c-.08-.18-.18-.34-.26-.51a1.74,1.74,0,0,1-.1-.19.08.08,0,0,1,0,0c-.14-.25-.3-.49-.46-.72l0,0c-.09-.13-.19-.24-.28-.36s-.2-.25-.3-.36,0,0,0,0l-.45-.43-.26-.24a6.42,6.42,0,0,0-.65-.48l-.13-.1h0l-.46-.27a1.63,1.63,0,0,0-.19-.09l-.52-.25c-.14-.06-.29-.13-.44-.18s-.37-.14-.57-.2l-.31-.1a.58.58,0,0,0-.14,0c-.32-.09-.65-.16-1-.22l-.2,0h-.05c-.4-.06-.83-.11-1.26-.14h0c-.39,0-.79,0-1.2,0H159l-.43,0h-.3c-.21,0-.43,0-.64.09h0l-.13,0a3,3,0,0,0-.43.09.35.35,0,0,0-.11,0,1.41,1.41,0,0,0-.22.06l-.24.06-.2.08-.23.08-.14,0-.27.12-.24.11-.08,0-.24.14-.33.18-.08,0-.14.1-.53.38-.12.09-.27.23a53.11,53.11,0,0,0-5.87,6.55l-36.44,45.8-2.55,3.17c-.68.86-1.34,1.75-2,2.68a12.25,12.25,0,0,0-1.44,2.65,7.17,7.17,0,0,0-.45,1.87c0,.2,0,.41,0,.61h0v11.49a7,7,0,0,1,.48-2.49,12.43,12.43,0,0,1,1.44-2.64c.65-.93,1.31-1.82,2-2.69l2.55-3.16L147.76,116a53.36,53.36,0,0,1,5.87-6.56l.39-.31c.17-.14.35-.26.53-.39a1.64,1.64,0,0,0,.22-.14l.33-.19.32-.17.24-.11.41-.17.23-.09.44-.14.22-.06.54-.11.13,0c.23,0,.47-.07.71-.09h.26c.19,0,.38,0,.57,0,.42,0,.83,0,1.23,0a12.44,12.44,0,0,1,1.26.14l.25,0q.51.09,1,.21l.45.14c.2.06.39.12.57.19l.44.19.52.24c.22.12.44.24.65.37h0l.13.1a6.42,6.42,0,0,1,.65.48c.09.07.17.16.26.24s.31.28.45.43.21.26.32.39.19.23.28.36a7.45,7.45,0,0,1,.5.78l.1.19c.11.21.22.43.31.65s.09.22.13.32a6.32,6.32,0,0,1,.22.61c.05.13.09.26.13.4l.15.59.12.52.09.56c0,.24.08.48.1.73s.06.52.08.79c0,.08,0,.15,0,.23,0,.42,0,.84,0,1.29h0V107.13A2.44,2.44,0,0,0,169.61,106.86Z"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M247,164.23c-1,5.13-2.63,9.07-5,11.83a11.68,11.68,0,0,1-.85.87c-.09.09-.18.16-.27.24a6.66,6.66,0,0,1-.59.49c-.19.14-.37.28-.56.4s-.39.27-.6.39l-.38.21c-.28.15-.57.3-.86.43l-.2.08a10,10,0,0,1-1.13.4l-.29.09c-.32.08-.64.16-1,.22L235,180c-.43.07-.87.14-1.32.18h-.23c-.43,0-.87.05-1.33.05s-.9,0-1.34-.05l-.7-.08-.77-.1-.21,0c-.39-.08-.78-.17-1.16-.27s-.48-.16-.72-.25l-.55-.19c-.24-.1-.46-.21-.7-.33s-.33-.14-.48-.23l-.21-.13a8.63,8.63,0,0,1-.82-.51c-.21-.15-.41-.31-.61-.47l-.43-.34c-.21-.19-.41-.39-.6-.59s-.27-.25-.39-.39a12.06,12.06,0,0,1-.77-.94l-.17-.22c-.23-.32-.47-.66-.69-1a1,1,0,0,0-.1-.17c-.2-.34-.4-.69-.59-1a1.62,1.62,0,0,1-.1-.18c-.2-.39-.39-.8-.58-1.22l-.13-.31c-.17-.4-.34-.81-.49-1.24l-.06-.14c-.17-.47-.33-1-.48-1.47l-.12-.43c-.12-.39-.22-.79-.33-1.2,0-.15-.07-.31-.11-.46-.13-.55-.26-1.11-.37-1.68s-.23-1.25-.33-1.9l0-.14c-.1-.61-.19-1.25-.27-1.9,0-.17,0-.34-.07-.51-.07-.57-.13-1.14-.19-1.73,0-.12,0-.23,0-.35l-.09-1c0-.49-.09-1-.13-1.48s0-.75-.07-1.12-.06-1-.09-1.51,0-.81-.05-1.21,0-1-.07-1.55l0-1.3,0-1.61c0-.85,0-1.7,0-2.57v11.48c0,.75,0,1.49,0,2.21,0,.13,0,.24,0,.36,0,.55,0,1.08,0,1.61s0,.88,0,1.3,0,1,.07,1.56,0,.82.05,1.21l.09,1.5c0,.38,0,.76.07,1.12,0,.51.09,1,.13,1.49,0,.29.05.6.08.89,0,0,0,.09,0,.13s0,.23,0,.35c.06.59.12,1.16.19,1.72,0,.18.05.35.07.52.08.65.17,1.28.27,1.9l0,.14c.06.41.13.82.2,1.21,0,.23.09.46.13.68.11.58.24,1.14.37,1.69,0,.15.07.3.11.46s.09.37.14.55.12.43.19.65l.12.43c.15.48.3,1,.46,1.42,0,0,0,0,0,0l.06.14c.15.43.32.84.49,1.24l.13.31.11.26c.15.33.31.65.47,1a1.62,1.62,0,0,0,.1.18c.09.18.19.36.29.54l.3.5.1.17c.18.28.36.56.54.82l.16.2.16.22c.25.33.5.64.77.94l.06.06c.1.12.22.22.33.33s.39.4.6.58.29.23.43.35.4.32.61.47l.07.06q.38.24.75.45l.21.13h0l.46.22c.23.11.46.23.7.33l.55.19c.24.08.47.17.72.24l0,0c.37.1.74.18,1.12.25l.21,0,.2,0c.18,0,.38,0,.57.06s.46.07.7.08l.15,0c.39,0,.78,0,1.19,0h.26c.36,0,.72,0,1.07-.06h.26c.38,0,.76-.08,1.13-.14l.16,0,.32-.07.52-.1.45-.13.29-.08.18-.05c.31-.1.6-.2.89-.32l.06,0,.2-.09.62-.28c.09,0,.16-.1.24-.14l.38-.21c.1-.07.21-.12.31-.18l.29-.21.56-.4.24-.18.35-.31.27-.24a11.84,11.84,0,0,0,.85-.88c2.39-2.75,4-6.69,5-11.82a113.49,113.49,0,0,0,1.44-20.15V144.08A113.42,113.42,0,0,1,247,164.23Z"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M267.31,143.7c0-.12,0-.23,0-.34,0-.49,0-1,0-1.43s0-.69,0-1c0-.5,0-1-.06-1.46,0-.31,0-.62,0-.92,0-.54-.06-1.08-.1-1.61,0-.23,0-.46,0-.68-.06-.75-.12-1.49-.19-2.22v0c-.06-.63-.13-1.25-.2-1.87,0-.19-.05-.37-.07-.56-.06-.43-.11-.86-.17-1.29,0-.22-.07-.43-.1-.65-.06-.39-.12-.78-.19-1.17,0-.21-.07-.42-.1-.62l-.06-.35c0-.14-.06-.27-.08-.41l-.33-1.63c-.05-.21-.09-.42-.14-.63-.16-.71-.33-1.41-.51-2.08h0c-.16-.6-.33-1.19-.51-1.76l-.18-.56c-.12-.38-.25-.77-.38-1.14,0-.07,0-.14-.07-.21s-.13-.32-.19-.49l-.3-.8c-.09-.23-.19-.46-.29-.69s-.21-.51-.32-.76c0-.08-.07-.17-.11-.25-.13-.29-.27-.58-.4-.86-.34-.68-.7-1.34-1.06-2-.05-.08-.09-.17-.13-.25l-.18-.29c-.2-.34-.4-.68-.6-1s-.23-.38-.35-.56c-.23-.36-.47-.72-.72-1.07-.07-.11-.14-.22-.22-.33l0-.06q-.56-.77-1.14-1.5l-.3-.37c-.3-.36-.61-.72-.92-1.07-.06-.07-.13-.16-.2-.23l-.17-.17c-.44-.49-.9-1-1.37-1.41l-1-.92-.32-.27-.74-.61-.37-.28q-.4-.31-.81-.6l-.29-.21-.1-.07-.42-.27c-.26-.18-.53-.35-.8-.52l-.56-.33-.78-.45-.18-.1-.29-.15c-.42-.21-.83-.42-1.26-.62l-.48-.22c-.57-.25-1.14-.49-1.73-.71s-.91-.33-1.37-.48l-.46-.14-.74-.22-.17,0c-.49-.14-1-.26-1.49-.37l-.24-.06c-.59-.13-1.18-.24-1.79-.34l-.12,0-.57-.08-1-.13-.75-.08-1-.09-.25,0-.79,0-.52,0c-.54,0-1.08,0-1.63,0h-.91c-.35,0-.7,0-1.05,0l-.47,0-1.41.1h-.07c-.45.05-.9.09-1.34.15l-.41.06-.91.13-.13,0-.41.07-.69.13-.55.11-.67.15-.19,0-.37.1-.61.15-.56.16-.59.18-.21.06-.33.12-.59.2-.53.19-.57.22-.24.09-.27.12-.62.26-.48.22-.61.3-.28.13a1.51,1.51,0,0,1-.18.09l-.76.42-.36.19c-.37.21-.73.43-1.09.65l0,0c-.58.36-1.13.75-1.67,1.15-.17.11-.32.24-.48.36s-.45.33-.66.51-.32.28-.48.41l-.55.48c-.37.33-.73.68-1.08,1l-.44.43c-.48.5-1,1-1.4,1.56l-.17.22c-.39.47-.77,1-1.13,1.47-.14.19-.27.39-.4.58-.28.41-.56.82-.82,1.24l-.41.67c-.26.44-.51.89-.76,1.35l-.33.62c-.34.68-.67,1.36-1,2.07A55.46,55.46,0,0,0,198,128.9a127.46,127.46,0,0,0-1.1,17.57V158a127.36,127.36,0,0,1,1.1-17.57A55.34,55.34,0,0,1,201.46,127c.31-.71.64-1.4,1-2.07l.33-.62c.25-.46.5-.91.76-1.35l.41-.67c.26-.42.54-.84.82-1.24.13-.2.26-.4.4-.59.36-.5.74-1,1.13-1.46l.17-.22c.45-.54.92-1.06,1.4-1.56l.44-.44q.52-.53,1.08-1l.55-.48c.37-.32.75-.62,1.14-.92.16-.12.31-.25.48-.37.55-.4,1.12-.8,1.7-1.17.36-.22.72-.44,1.09-.65l.36-.2.76-.41.46-.23.61-.29.48-.22.62-.27.51-.2.57-.22.53-.2.59-.2.54-.17.59-.18.56-.16.61-.15.56-.14.66-.15.56-.11.68-.13.55-.1.91-.13.41-.05c.44-.06.89-.11,1.34-.15h.07c.46,0,.93-.08,1.41-.1l.47,0,1.05,0h.91c.55,0,1.09,0,1.63,0l.52,0,1,.06c.33,0,.65.06,1,.09l.75.07,1,.14.69.1c.61.1,1.2.21,1.79.34l.24,0,1.49.37.91.27.46.14c.46.15.92.31,1.37.48s1.16.46,1.73.71l.48.22c.43.2.84.4,1.26.62l.47.25q.39.21.78.45c.19.11.38.21.56.33s.54.34.8.51l.52.35.29.21c.27.19.55.39.81.6l.36.28c.26.2.5.4.75.61l.32.27c.34.3.68.6,1,.92s.93.92,1.37,1.4l.37.41c.31.35.62.71.92,1.07l.3.37c.39.49.77,1,1.14,1.5l.26.39c.25.35.49.71.72,1.07l.35.55.6,1,.31.54c.36.65.72,1.31,1.06,2l.51,1.11c.11.25.22.5.32.76s.2.45.29.69l.3.8c.09.23.18.46.26.7s.26.75.38,1.14l.18.56c.18.57.35,1.16.51,1.76h0c.18.67.35,1.37.51,2.07.05.21.09.43.14.64.11.53.22,1.08.33,1.63,0,.25.09.5.14.75s.07.42.1.63c.07.39.13.77.19,1.17,0,.21.07.43.1.65.06.42.11.85.17,1.29,0,.19.05.37.07.56.07.62.14,1.25.21,1.9s.13,1.46.19,2.21c0,.23,0,.46,0,.69,0,.53.07,1.07.1,1.61,0,.3,0,.61,0,.91,0,.49.05,1,.06,1.46s0,.68,0,1,0,1,0,1.43c0,.67,0,1.34,0,2h0V145.37C267.32,144.81,267.32,144.25,267.31,143.7Z"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M356.8,170.83l.09.09a3.44,3.44,0,0,1,.41.44l.12.15a6,6,0,0,1,.39.59.93.93,0,0,0,.05.1,5.36,5.36,0,0,1,.32.73h0a5.92,5.92,0,0,1,.22.78,1.06,1.06,0,0,1,0,.19,8.46,8.46,0,0,1,.14.9.49.49,0,0,0,0,.12c0,.31,0,.64,0,1V164.28c0-.29,0-.57,0-.84a.49.49,0,0,1,0-.12h0c0-.25-.06-.5-.1-.74,0,0,0-.1,0-.15a1.29,1.29,0,0,0,0-.19c0-.09,0-.19-.06-.27s-.1-.35-.16-.51h0c-.06-.16-.12-.32-.19-.47s-.09-.17-.13-.25l-.05-.1s0-.05,0-.08-.17-.28-.26-.42l-.09-.1-.12-.15-.16-.2-.25-.24-.09-.09a4.06,4.06,0,0,0-.46-.36l-.11-.07-.12-.07-.19-.12-.49-.23c-.26-.11-.53-.22-.81-.31l-.29-.1-.54-.16h0l-.65-.16-.34-.08-1-.19h-.09c-.36-.06-.74-.11-1.12-.15l-.38,0-.82-.07h-.05l-.73,0-.41,0-1.26,0h-3v11.49h3c.43,0,.85,0,1.26,0l.4,0,.79,0,.82.07.38,0,1.12.16h.09l1,.18.34.08.65.16.58.18.29.09c.28.1.55.2.81.31a6.23,6.23,0,0,1,.68.36l.12.07A4.73,4.73,0,0,1,356.8,170.83Z"/>
|
||||||
|
<rect class="cls-13" x="297.24" y="157.13" width="29.56" height="11.49"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M344,106.86c0-.35,0-.69,0-1,0-.08,0-.15,0-.23s0-.35,0-.52,0-.18,0-.27c0-.25-.06-.49-.1-.73s0-.23-.05-.33a1.89,1.89,0,0,0-.05-.23c0-.18-.07-.35-.11-.52s-.05-.23-.08-.34a1.83,1.83,0,0,0-.08-.25l-.12-.4c0-.09-.05-.18-.08-.26s-.09-.23-.14-.35-.08-.21-.13-.31l-.06-.15c-.08-.18-.17-.34-.26-.51a1.74,1.74,0,0,0-.1-.19.08.08,0,0,0,0,0q-.21-.37-.45-.72l0,0c-.09-.12-.19-.24-.29-.35s-.19-.26-.29-.37l0,0a6.14,6.14,0,0,0-.45-.43l-.25-.24a7.62,7.62,0,0,0-.64-.48l-.14-.1h0l-.46-.27a1.11,1.11,0,0,0-.19-.09c-.16-.09-.34-.17-.51-.25s-.29-.13-.44-.18l-.57-.2-.31-.1-.14,0a9.78,9.78,0,0,0-1-.22l-.2,0h0c-.41-.06-.83-.11-1.27-.14h0c-.38,0-.78,0-1.19,0h-.14l-.43,0h-.3c-.21,0-.43,0-.64.09h0l-.13,0c-.15,0-.29,0-.43.09a.35.35,0,0,0-.11,0,1.41,1.41,0,0,0-.22.06l-.24.06-.2.08-.23.08-.14,0-.27.12-.24.11-.08,0-.24.14-.33.18-.07,0-.14.11a4.7,4.7,0,0,0-.53.38l-.12.08-.28.24a53,53,0,0,0-5.88,6.55l-36.43,45.8c-1,1.25-1.86,2.31-2.54,3.17s-1.36,1.75-2,2.68a12.25,12.25,0,0,0-1.44,2.65,7.17,7.17,0,0,0-.45,1.87c0,.2,0,.41,0,.61h0v11.49a7,7,0,0,1,.48-2.49,12.43,12.43,0,0,1,1.44-2.64c.64-.93,1.31-1.82,2-2.69l2.54-3.16L322.12,116a53.27,53.27,0,0,1,5.88-6.56l.4-.32.53-.38.21-.14.33-.19.32-.17.24-.11.41-.17.23-.09.44-.14.22-.06.54-.11.13,0c.23,0,.47-.07.71-.09H333c.19,0,.37,0,.57,0,.42,0,.83,0,1.22,0a12.65,12.65,0,0,1,1.27.14l.25,0q.51.09,1,.21l.45.14c.19.06.39.12.57.19l.44.19.51.24c.23.12.45.24.65.37h0l.15.1a7.62,7.62,0,0,1,.64.48c.09.07.17.16.26.24s.3.28.44.43a3.89,3.89,0,0,1,.32.39c.1.12.2.23.29.36a6.07,6.07,0,0,1,.49.78,1.14,1.14,0,0,1,.1.19c.11.21.22.43.32.65s.09.21.13.32.15.4.22.61l.12.39c.06.2.11.4.16.6s.08.34.11.52.07.37.1.56.07.48.1.73.06.52.08.79c0,.08,0,.15,0,.23,0,.42,0,.84,0,1.29h0V106.86Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M181.06,170q3.19,1.36,3.2,5.95a6,6,0,0,1-2.61,5.45c-1.74,1.15-4.36,1.72-7.84,1.72h-4.19v12q0,5-2.34,7.39a9.16,9.16,0,0,1-12.48-.07c-1.58-1.65-2.37-4.1-2.37-7.32v-12H117.92q-6.53,0-9.79-2.78a9.36,9.36,0,0,1-3.27-7.56,7,7,0,0,1,.48-2.49,12.43,12.43,0,0,1,1.44-2.64c.65-.93,1.31-1.82,2-2.69l2.55-3.16L147.76,116a53.36,53.36,0,0,1,5.87-6.56,8.12,8.12,0,0,1,5.54-2q10.44,0,10.45,11.25v50h2.95A22.17,22.17,0,0,1,181.06,170Zm-28.63-1.35V131.09l-29.56,37.53h29.56"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M262.1,126.69q5.22,10.67,5.22,30.17A104.74,104.74,0,0,1,266,175.07a40.85,40.85,0,0,1-5.09,13.83,32.76,32.76,0,0,1-12.1,11.76,33.29,33.29,0,0,1-16.5,4.13,32.86,32.86,0,0,1-18.73-5.55,34.11,34.11,0,0,1-12.48-15.38A54.59,54.59,0,0,1,197.92,172a93.33,93.33,0,0,1-1-14,127.36,127.36,0,0,1,1.1-17.57A55.34,55.34,0,0,1,201.46,127a30.81,30.81,0,0,1,11.79-14.18q7.73-4.87,18.46-4.88a36.2,36.2,0,0,1,12.85,2.17,29.45,29.45,0,0,1,10.14,6.33A36.1,36.1,0,0,1,262.1,126.69Zm-15.06,49a113.49,113.49,0,0,0,1.44-20.15A101.2,101.2,0,0,0,247,136.22c-1-5-2.7-8.81-5.08-11.37S236.2,121,232,121q-9.07,0-12.61,8.59t-3.54,26.48a107,107,0,0,0,1.51,19.9q1.51,7.76,5.09,11.73a12.37,12.37,0,0,0,9.69,4q6.33,0,9.9-4.14c2.39-2.75,4-6.69,5-11.82"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M355.43,170q3.19,1.36,3.2,5.95a6,6,0,0,1-2.62,5.45q-2.61,1.73-7.83,1.72H344v12q0,5-2.33,7.39a8.29,8.29,0,0,1-6.26,2.42,8.19,8.19,0,0,1-6.22-2.49c-1.58-1.65-2.37-4.1-2.37-7.32v-12H292.29q-6.54,0-9.8-2.78a9.42,9.42,0,0,1-3.26-7.56,7,7,0,0,1,.48-2.49,12.43,12.43,0,0,1,1.44-2.64c.64-.93,1.31-1.82,2-2.69l2.54-3.16L322.12,116a53.27,53.27,0,0,1,5.88-6.56,8.1,8.1,0,0,1,5.54-2q10.44,0,10.44,11.25v50h3A22.17,22.17,0,0,1,355.43,170Zm-28.63-1.35V131.09l-29.56,37.53H326.8"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M270.46,172.17c.07,1.42-.5,2.61-1.28,2.64s-1.46-1.08-1.53-2.5.5-2.6,1.28-2.64S270.39,170.75,270.46,172.17Z"/>
|
||||||
|
<path class="cls-16"
|
||||||
|
d="M285.58,170.34c.33,0,.62.46.65,1.06s-.21,1.1-.54,1.12l-.88.09c.12-.19.17-.36,0-.48-.38-.34-.75-.34-1-.08s-.17.57-.48.71h0l-3.26.34-.61.07a3.68,3.68,0,0,0,.19-1.45,3.76,3.76,0,0,0-.33-1.42h2c0,.31.1.73.42.83a19.28,19.28,0,0,0,3.06.13c1,0,.41-.65.47-.93h.29Z"/>
|
||||||
|
<path class="cls-17"
|
||||||
|
d="M279.17,171.65a3.49,3.49,0,0,1-1.1,2.61l-8.67,1.23c.89-.21,1.53-1.64,1.44-3.34S270,169.06,269,169l8.79.38A2.92,2.92,0,0,1,279.17,171.65Z"/>
|
||||||
|
<path class="cls-18"
|
||||||
|
d="M279.37,170.3a3.76,3.76,0,0,1,.33,1.42,3.68,3.68,0,0,1-.19,1.45c-.21.6-.57,1-1,1l-.43.06a3.49,3.49,0,0,0,1.1-2.61,2.92,2.92,0,0,0-1.34-2.3l.44,0C278.7,169.35,279.1,169.71,279.37,170.3Z"/>
|
||||||
|
<path class="cls-18"
|
||||||
|
d="M269.18,174.81c.78,0,1.35-1.22,1.28-2.64s-.75-2.54-1.53-2.5-1.35,1.22-1.28,2.64S268.41,174.85,269.18,174.81Zm1.66-2.66c.09,1.7-.55,3.13-1.44,3.34h0l-.17,0c-1,0-1.86-1.38-2-3.19s.64-3.31,1.63-3.36H269C270,169.06,270.76,170.44,270.84,172.15Z"/>
|
||||||
|
<path d="M303,176a1.14,1.14,0,0,0,.33.71,2.75,2.75,0,0,1-.88-.39A4.37,4.37,0,0,0,303,176Z"/>
|
||||||
|
<path d="M298.64,166.65l.12.16A5.6,5.6,0,0,0,297,169a4.63,4.63,0,0,1-2.06-1.52C296.92,168,297.5,166.05,298.64,166.65Z"/>
|
||||||
|
<path d="M306.62,169.68c-.86-3.88-3.84-4.21-3.84-4.21s-3.07-.47-4.14,1.18l.12.16A5.6,5.6,0,0,0,297,169a6.88,6.88,0,0,0,1.35.43c1.8.34,4.18.13,4.85,1.15s.22,2.66-.91,4.16c-.59.8-.28,1.31.16,1.62A4.37,4.37,0,0,0,303,176a.46.46,0,0,1,.28-.48,1.61,1.61,0,0,1,.49-.11,2.5,2.5,0,0,0,1.34-.39C305.68,174.58,307.49,173.56,306.62,169.68Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M320.54,231.08c0,.63.23,3.56-.53,3.84a54,54,0,0,1-7.28,1.17c-1.07,0-.9-.85-.9-.85s7.18-.51,7.81-1.12.32-2.83.06-4.08a23.55,23.55,0,0,1-.41-4.38,16,16,0,0,0,.17-1.74c-.06-.35-1.59-1.62-1.59-1.62.11-.22.39-.31.9-.31s1.4,1.52,1.44,1.87-.38,1.49-.38,2.36S320.49,230.45,320.54,231.08Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M319.7,230c.26,1.25.57,3.47-.06,4.08s-7.81,1.12-7.81,1.12,0-.92,0-1.3,4.06-1.18,4.2-2-.47-2.2-1.23-2.16c-.38,0-.48-.26-.49-.57a7.35,7.35,0,0,1,.07-.78c0-.24.95,1,1.35.77s.86-3.75-.28-4.77a1.05,1.05,0,0,0-.86-.28s-.8-.86-.69-1.18.63-.81,1-.31,1.46-.07,1.88-.22a4.57,4.57,0,0,1,1.13-.14s1.53,1.27,1.59,1.62a16,16,0,0,1-.17,1.74A23.55,23.55,0,0,0,319.7,230Z"/>
|
||||||
|
<path class="cls-21"
|
||||||
|
d="M313.73,229.3l.17,3L295,235.55a3.15,3.15,0,0,1-3.64-2.68l-2.74-20.29,9.2,2.1-.35,12.89,16-3v.18Z"/>
|
||||||
|
<path class="cls-22"
|
||||||
|
d="M288.06,204.33c.51.45,9.48,2.36,15.15,2.31h0l-.77,5.1a3.62,3.62,0,0,1-4.4,3l-.24,0-9.2-2.1-8.66-2,1.86,19-2.31.39-4.45.75-.33.06L272.81,204a2.71,2.71,0,0,1,3.39-2.81Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M305.83,192.12h0a23,23,0,0,0,.05,2.76l-10.67.31c-.63-.74-1.57-1.4-2-1a.6.6,0,0,0,.34,1c.32,0,1.08.71-.34.58s-2.1-.85-2.62-.44-.66,2.48,0,2.65,4.27.33,5.37-.22l10.05.51c.16,3,.39,6.37.53,7.94a11,11,0,0,1-3.37.43c-5.67.05-14.64-1.86-15.15-2.31s1.25-9.1,2.52-15.42a14.92,14.92,0,0,1-2.92,1.4,5.36,5.36,0,0,1-1.91-2.19,6.93,6.93,0,0,1-.7-4.55,2,2,0,0,1,.24-.6c1.44-1.05,5.18-2.8,7.2-4.19a8.25,8.25,0,0,1,4.06-1.22c-.17.32-.75,3,.87,3.44s5-.87,5-3.08a6.18,6.18,0,0,1,3.22.52c1.77,1,4.07,6.39,5.89,11.34-.32,1.08-2.22,1.88-4,2.19A8.16,8.16,0,0,1,305.83,192.12Z"/>
|
||||||
|
<polygon class="cls-23"
|
||||||
|
points="279.49 229.99 279.48 231.93 275.27 232.85 275.04 231.33 275.04 230.74 279.49 229.99"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M314.38,228.43a7.35,7.35,0,0,0-.07.78h0l-.58.09-.27-4.55,2-.32c1.14,1,.61,4.6.28,4.77S314.38,228.19,314.38,228.43Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M314,197.18c-.52-1.65-1.43-4.45-2.51-7.4-.32,1.08-2.22,1.88-4,2.19l1.08,2.83-2.68.08-10.67.31c-.63-.74-1.57-1.4-2-1a.6.6,0,0,0,.34,1c.32,0,1.08.71-.34.58s-2.1-.85-2.62-.44-.66,2.48,0,2.65,4.27.33,5.37-.22l10.05.51,6.84.35A1.11,1.11,0,0,0,314,197.18Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M302.38,177.92c0,2.21-3.34,3.52-5,3.08s-1-3.12-.87-3.44a14.35,14.35,0,0,1,1.51,0c.17-.09.3-.54.3-.91a3.83,3.83,0,0,0,1.12.27,5.52,5.52,0,0,0,3-.59c-.32.56-.81,1.15-.74,1.48C301.73,177.92,302,177.93,302.38,177.92Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M303.19,170.55c.67,1,.22,2.66-.91,4.16-.59.8-.28,1.31.16,1.62a5.52,5.52,0,0,1-3,.59,3.83,3.83,0,0,1-1.12-.27c-1.65-.71-2.29-2.23-2.05-4.86a9.18,9.18,0,0,1,1-2.68,3.91,3.91,0,0,0,1,.29C300.14,169.74,302.52,169.53,303.19,170.55Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M285.29,170.34h0c0-.29-.74-1.21-1.47-1.51a6.8,6.8,0,0,0-2.48,0c-.34,0-.84,1.33-.9,1.48h.9c0,.31.1.73.42.83a19.28,19.28,0,0,0,3.06.13C285.8,171.29,285.23,170.62,285.29,170.34Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M283.87,172.05c.22-.26.59-.26,1,.08.14.12.09.29,0,.48l-1.42.15C283.7,172.62,283.64,172.31,283.87,172.05Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M283.38,172.76h0l1.42-.15c-.21.34-.64.74-.7,1.06-.09.49-1.08.75-1.52,1.35l-.48,10.24,2.94-1.69a6.93,6.93,0,0,0,.7,4.55L279.2,191a1,1,0,0,1-1.41-1.07l2.2-15.22c.12-1,.13-1.61.13-1.61Z"/>
|
||||||
|
<path class="cls-24" d="M303,187.14l1.72,4.81a3.36,3.36,0,0,0,1.11.17"/>
|
||||||
|
<path class="cls-25"
|
||||||
|
d="M317.87,222.3c.11-.22.39-.31.9-.31s1.4,1.52,1.44,1.87-.38,1.49-.38,2.36.66,4.23.71,4.86.23,3.56-.53,3.84a54,54,0,0,1-7.28,1.17c-1.07,0-.9-.85-.9-.85"/>
|
||||||
|
<ellipse class="cls-23" cx="303.14" cy="173.18" rx="1.32" ry="0.91"
|
||||||
|
transform="translate(13 367.35) rotate(-63.53)"/>
|
||||||
|
<ellipse class="cls-26" cx="303.14" cy="173.18" rx="0.77" ry="0.53"
|
||||||
|
transform="translate(13 367.35) rotate(-63.53)"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M262.55,235.72a.72.72,0,0,1-.12-1.21c-.17.18.05.37.48.39a36.08,36.08,0,0,0,11.77-.55c1-.08,3.65.2,5.06.15,1.16-.05,1.62-.47,1.73-.86a1,1,0,0,1,.17,1.64c-.6.61-4.14.52-4.82.51s-7.56,0-8.57.12A26.72,26.72,0,0,1,262.55,235.72Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M280.69,231.61a8.33,8.33,0,0,1,.81,1.8.91.91,0,0,1,0,.23c-.11.39-.57.81-1.73.86-1.41.05-4-.23-5.06-.15a36.08,36.08,0,0,1-11.77.55c-.43,0-.65-.21-.48-.39a33.2,33.2,0,0,1,4.91-1.81,12.78,12.78,0,0,0,6.17-2.66,3.77,3.77,0,0,1,.75,0c.87.08,1.61.44,1.58.78s-.47.82.46.92a3.33,3.33,0,0,0,2.36-.58c.33-.37.34-.67,1-.56.18,0,.33,0,.46,0,.39,0,.58,0,.7.17S280.52,231.25,280.69,231.61Z"/>
|
||||||
|
<path class="cls-25"
|
||||||
|
d="M262.43,234.51a.72.72,0,0,0,.12,1.21,26.72,26.72,0,0,0,5.7.19c1-.17,7.9-.13,8.57-.12s4.22.1,4.82-.51a1,1,0,0,0-.17-1.64h0"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 32 KiB |
111
src/assets/images/exception/500.svg
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 456.01 262.12">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1,.cls-2,.cls-21,.cls-22,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7{fill:none;}.cls-2,.cls-21,.cls-22,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7{stroke-miterlimit:10;}.cls-2,.cls-3,.cls-4,.cls-5,.cls-6,.cls-7{stroke-width:2px;}.cls-2{stroke:url(#未命名的渐变_26);}.cls-3{stroke:url(#未命名的渐变_26-2);}.cls-4{stroke:url(#未命名的渐变_26-3);}.cls-5{stroke:url(#未命名的渐变_26-4);}.cls-6{stroke:url(#未命名的渐变_26-5);}.cls-7{stroke:url(#未命名的渐变_26-6);}.cls-10,.cls-11,.cls-12,.cls-13,.cls-8{opacity:0.4;}.cls-8{fill:url(#未命名的渐变_26-7);}.cls-9{opacity:0.7;}.cls-10{fill:url(#未命名的渐变_26-8);}.cls-11{fill:url(#未命名的渐变_26-9);}.cls-12{fill:url(#未命名的渐变_26-10);}.cls-13{fill:url(#未命名的渐变_26-11);}.cls-14{fill:#67c8ff;}.cls-15{fill:#8cd7ff;}.cls-16{isolation:isolate;}.cls-17{clip-path:url(#clip-path);}.cls-18{fill:#517d94;}.cls-19{fill:#ebfcff;}.cls-20{fill:#ffb056;}.cls-21{stroke:#e49056;stroke-width:0.25px;}.cls-22{stroke:#4986d9;stroke-width:0.13px;}.cls-23{fill:#e49056;}.cls-24{fill:#fae6d2;}.cls-25{fill:#ffeed2;}.cls-26{fill:#d3d3d3;}.cls-27{fill:#fff;}.cls-28{fill:#398eed;}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="未命名的渐变_26" x1="1" y1="91.35" x2="1" y2="181.12" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#81cfff"/>
|
||||||
|
<stop offset="1" stop-color="#5ecfff" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="未命名的渐变_26-2" x1="455.01" y1="72.11" x2="455.01" y2="161.88" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-3" x1="40.9" y1="143.88" x2="40.9" y2="199.51" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-4" x1="64.97" y1="95.36" x2="64.97" y2="123.17" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-5" x1="397.23" y1="104.2" x2="397.23" y2="132.02" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-6" x1="424.75" y1="133.49" x2="424.75" y2="189.13" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-7" x1="232.75" y1="224.43" x2="232.75" y2="262.12" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-8" x1="349.36" y1="26.68" x2="349.36" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-9" x1="201.45" y1="55.61" x2="201.45" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-10" x1="122.98" y1="26.68" x2="122.98" y2="204.03" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<linearGradient id="未命名的渐变_26-11" x1="273.51" y1="0" x2="273.51" y2="209.54" xlink:href="#未命名的渐变_26"/>
|
||||||
|
<clipPath id="clip-path">
|
||||||
|
<path class="cls-1"
|
||||||
|
d="M132.71,143.17v-8.64c1.84-.15,3.62-.2,5.32-.2s3.18,0,4.65.11c7.58.36,16.62,3.36,22.3,8.63s7.84,11.57,7.84,20.58v8.64c0-9-2.17-15.32-7.84-20.58s-14.72-8.27-22.3-8.63c-1.47-.07-3-.12-4.65-.12S134.55,143,132.71,143.17Z"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<title>500</title>
|
||||||
|
<g id="图层_2" data-name="图层 2">
|
||||||
|
<g id="图层_1-2" data-name="图层 1">
|
||||||
|
<line class="cls-2" x1="1" y1="91.35" x2="1" y2="181.12"/>
|
||||||
|
<line class="cls-3" x1="455.01" y1="72.11" x2="455.01" y2="161.88"/>
|
||||||
|
<line class="cls-4" x1="40.9" y1="143.88" x2="40.9" y2="199.51"/>
|
||||||
|
<line class="cls-5" x1="64.97" y1="95.36" x2="64.97" y2="123.17"/>
|
||||||
|
<line class="cls-6" x1="397.23" y1="104.2" x2="397.23" y2="132.02"/>
|
||||||
|
<line class="cls-7" x1="424.75" y1="133.49" x2="424.75" y2="189.13"/>
|
||||||
|
<path class="cls-8" d="M412.28,262.12c-23-23-61-37.69-179.53-37.69S76.24,239.1,53.21,262.12Z"/>
|
||||||
|
<g class="cls-9">
|
||||||
|
<path class="cls-10"
|
||||||
|
d="M380.66,26.68H318.07a2.71,2.71,0,0,0-2.82,2.59V201.44a2.71,2.71,0,0,0,2.82,2.59h62.59a2.72,2.72,0,0,0,2.82-2.59V29.27A2.72,2.72,0,0,0,380.66,26.68ZM328.3,147a.9.9,0,0,1-.95.87h-3.6a.9.9,0,0,1-.95-.87V127.27a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.23a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V97a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V66.8a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87Zm0-30.24a.91.91,0,0,1-.95.87h-3.6a.91.91,0,0,1-.95-.87V36.56a.91.91,0,0,1,.95-.87h3.6a.91.91,0,0,1,.95.87ZM340,147a.9.9,0,0,1-.94.87h-3.61a.91.91,0,0,1-.95-.87V127.27a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V97a.92.92,0,0,1,.95-.87h3.61A.91.91,0,0,1,340,97Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V66.8a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.92.92,0,0,1-.95-.87V36.56a.92.92,0,0,1,.95-.87h3.61a.91.91,0,0,1,.94.87ZM351.7,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM363.4,147a.9.9,0,0,1-.94.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.23a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87Zm0-30.24a.91.91,0,0,1-.94.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.91.91,0,0,1,.94.87ZM375.11,147a.91.91,0,0,1-.95.87h-3.61a.9.9,0,0,1-.94-.87V127.27a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.23a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V97a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V66.8a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Zm0-30.24a.92.92,0,0,1-.95.87h-3.61a.91.91,0,0,1-.94-.87V36.56a.91.91,0,0,1,.94-.87h3.61a.92.92,0,0,1,.95.87Z"/>
|
||||||
|
<path class="cls-11"
|
||||||
|
d="M231.1,55.61H171.8A2.71,2.71,0,0,0,169,58.2V201.44A2.71,2.71,0,0,0,171.8,204h59.3a2.71,2.71,0,0,0,2.82-2.59V58.2A2.71,2.71,0,0,0,231.1,55.61ZM182.47,159.37a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11h-5.4a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1h-5.4a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1v-5.22a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h5.4a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V115.5a1.16,1.16,0,0,1,1.21-1.11h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V89.73A1.16,1.16,0,0,1,186,88.62h5.4a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H186a1.16,1.16,0,0,1-1.21-1.11V76.85A1.16,1.16,0,0,1,186,75.74h5.4a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H186a1.16,1.16,0,0,1-1.21-1.1V64A1.16,1.16,0,0,1,186,62.85h5.4a1.16,1.16,0,0,1,1.2,1.11Zm10.08,90.19a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h5.4a1.16,1.16,0,0,1,1.21,1.1Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.89a1.16,1.16,0,0,1-1.21,1.11H196a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h5.4a1.16,1.16,0,0,1,1.21,1.11Zm0-12.88a1.16,1.16,0,0,1-1.21,1.1H196a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h5.4A1.16,1.16,0,0,1,202.63,64Zm25.21,90.19a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1v-5.22a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.22a1.15,1.15,0,0,1,1.2-1.1h20.54a1.15,1.15,0,0,1,1.2,1.1Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V115.5a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11v-5.21a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V89.73a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Zm0-12.89a1.16,1.16,0,0,1-1.2,1.11H206.1a1.16,1.16,0,0,1-1.2-1.11V76.85a1.15,1.15,0,0,1,1.2-1.11h20.54a1.15,1.15,0,0,1,1.2,1.11Zm0-12.88a1.15,1.15,0,0,1-1.2,1.1H206.1a1.15,1.15,0,0,1-1.2-1.1V64a1.16,1.16,0,0,1,1.2-1.11h20.54a1.16,1.16,0,0,1,1.2,1.11Z"/>
|
||||||
|
<path class="cls-12"
|
||||||
|
d="M161.13,26.68H84.83A2.71,2.71,0,0,0,82,29.27V201.44A2.71,2.71,0,0,0,84.83,204h76.3a2.71,2.71,0,0,0,2.82-2.59V29.27A2.71,2.71,0,0,0,161.13,26.68ZM154.34,161a1.16,1.16,0,0,1-1.2,1.11H92.83A1.16,1.16,0,0,1,91.62,161v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1v-5.22A1.16,1.16,0,0,1,92.83,140h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.22a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11v-5.21a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V97a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V82.35a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V67.68a1.16,1.16,0,0,1,1.21-1.11h60.31a1.15,1.15,0,0,1,1.2,1.11Zm0-14.67a1.15,1.15,0,0,1-1.2,1.1H92.83a1.16,1.16,0,0,1-1.21-1.1V53a1.16,1.16,0,0,1,1.21-1.11h60.31a1.16,1.16,0,0,1,1.2,1.11Zm0-14.68a1.16,1.16,0,0,1-1.2,1.11H92.83a1.16,1.16,0,0,1-1.21-1.11V38.32a1.16,1.16,0,0,1,1.21-1.1h60.31a1.15,1.15,0,0,1,1.2,1.1Z"/>
|
||||||
|
<path class="cls-13"
|
||||||
|
d="M306.21,0H240.82a2.51,2.51,0,0,0-2.42,2.59V206.94a2.51,2.51,0,0,0,2.42,2.6h65.39a2.51,2.51,0,0,0,2.41-2.6V2.59A2.51,2.51,0,0,0,306.21,0Zm-5.82,134.28a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1v-5.22a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11v-5.22a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V99.71a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V85a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V70.35a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V55.68a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.67a1.06,1.06,0,0,1-1,1.1H247.67a1.06,1.06,0,0,1-1-1.1V41a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V26.32a1.06,1.06,0,0,1,1-1.1h51.69a1.06,1.06,0,0,1,1,1.1Zm0-14.68a1.07,1.07,0,0,1-1,1.11H247.67a1.07,1.07,0,0,1-1-1.11V11.65a1.07,1.07,0,0,1,1-1.11h51.69a1.07,1.07,0,0,1,1,1.11Z"/>
|
||||||
|
</g>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M240.54,164.63c-1,5.12-2.63,9.07-5,11.82-.27.31-.56.6-.85.88l-.27.24c-.19.17-.39.33-.6.49l-.55.4-.6.38-.38.22q-.42.23-.87.42l-.19.09c-.37.15-.74.28-1.13.4l-.3.08c-.31.09-.63.16-1,.23l-.32.06q-.64.12-1.32.18H227c-.44,0-.88.06-1.33.06s-.9,0-1.34-.06l-.71-.08-.76-.1-.21,0a10.34,10.34,0,0,1-1.16-.27c-.25-.07-.48-.16-.72-.24l-.55-.19c-.24-.1-.47-.22-.7-.33l-.48-.23-.21-.13c-.28-.16-.56-.33-.82-.51s-.41-.32-.61-.48a5,5,0,0,1-.43-.34c-.21-.18-.41-.39-.61-.59l-.38-.38c-.27-.3-.52-.62-.77-.94l-.17-.22q-.36-.5-.69-1l-.1-.17c-.21-.34-.41-.68-.6-1.05l-.09-.18c-.2-.39-.4-.79-.58-1.21l-.14-.32c-.17-.4-.33-.81-.49-1.23a.78.78,0,0,0-.05-.14c-.17-.48-.33-1-.48-1.48-.05-.14-.08-.28-.13-.42-.11-.4-.22-.79-.32-1.2,0-.16-.08-.31-.11-.47-.13-.54-.26-1.1-.37-1.68s-.23-1.24-.34-1.89c0-.05,0-.1,0-.15-.1-.61-.19-1.25-.27-1.9,0-.16-.05-.34-.07-.51-.07-.56-.13-1.14-.2-1.73l0-.34c0-.33-.06-.69-.09-1-.05-.49-.09-1-.13-1.48s0-.74-.07-1.12-.07-1-.09-1.5l-.06-1.22c0-.51,0-1-.06-1.55s0-.86,0-1.3,0-1.06,0-1.61c0-.84,0-1.69,0-2.57v11.49c0,.75,0,1.48,0,2.21,0,.12,0,.24,0,.36,0,.54,0,1.08,0,1.61l0,1.3c0,.53,0,1,.06,1.55l.06,1.22c0,.51.06,1,.09,1.5s0,.75.07,1.12.08,1,.13,1.48c0,.3,0,.61.07.9,0,0,0,.08,0,.13l0,.34c.07.59.13,1.17.2,1.73,0,.17,0,.34.07.51.08.65.17,1.29.27,1.9,0,0,0,.1,0,.14.07.41.14.82.21,1.21,0,.23.08.46.13.69.11.58.24,1.13.37,1.68,0,.16.07.31.11.46s.09.38.14.56l.18.64c0,.15.08.29.13.43.14.49.3,1,.46,1.42,0,0,0,0,0,.05a.88.88,0,0,1,.05.15c.16.42.32.83.49,1.23,0,.11.09.21.14.31s.07.18.11.26c.15.33.31.65.47,1l.09.18c.1.18.19.37.29.54s.21.34.31.51l.1.17c.18.28.35.55.54.81l.15.2.17.22a12.06,12.06,0,0,0,.77.94l.05.07.34.32c.19.2.39.4.6.59a5,5,0,0,0,.43.34c.2.16.4.33.61.47l.07.06c.24.17.49.31.75.46l.21.12,0,0c.15.08.31.14.46.21a6.36,6.36,0,0,0,.7.33c.18.08.37.13.55.19s.47.18.72.25h0c.36.1.74.19,1.12.26l.21,0,.19,0,.57.07.71.08.14,0q.58,0,1.2,0h.26c.36,0,.71,0,1.07,0h.25c.39,0,.77-.09,1.13-.15l.17,0,.32-.06.52-.11c.15,0,.29-.08.44-.12l.3-.09.18,0a9.44,9.44,0,0,0,.89-.32l.06,0,.19-.09c.21-.09.43-.18.63-.29l.24-.14c.13-.06.25-.14.38-.21s.21-.11.31-.18l.29-.2.55-.4c.08-.07.17-.12.25-.18l.35-.31.27-.25a11.68,11.68,0,0,0,.85-.87q3.57-4.14,5-11.82A112.54,112.54,0,0,0,242,156V144.47A112.54,112.54,0,0,1,240.54,164.63Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M260.82,144.09c0-.11,0-.22,0-.34l0-1.43,0-1c0-.49,0-1-.06-1.46,0-.3,0-.61,0-.91,0-.55-.07-1.08-.1-1.62,0-.22,0-.45-.05-.68-.05-.75-.12-1.49-.19-2.22v0c-.06-.63-.13-1.26-.2-1.87,0-.19-.05-.38-.07-.57l-.18-1.28-.09-.66c-.06-.39-.12-.78-.19-1.16,0-.21-.07-.42-.11-.63s0-.23-.06-.35-.05-.26-.08-.4c-.1-.55-.21-1.1-.33-1.64,0-.21-.09-.42-.13-.63-.17-.71-.33-1.4-.51-2.08h0l-.51-1.77-.18-.56c-.13-.38-.25-.76-.38-1.13a1.72,1.72,0,0,1-.07-.21c-.06-.17-.13-.33-.19-.5l-.3-.79c-.1-.24-.19-.47-.29-.7l-.32-.75-.11-.26c-.13-.29-.27-.57-.41-.85-.34-.69-.69-1.35-1-2l-.14-.25c0-.1-.11-.19-.17-.29l-.6-1-.35-.55c-.23-.37-.48-.72-.72-1.08-.07-.1-.14-.22-.22-.32l0-.06c-.36-.52-.74-1-1.13-1.5l-.3-.37c-.3-.37-.61-.72-.92-1.07l-.2-.24-.17-.17c-.45-.48-.9-1-1.37-1.4s-.67-.62-1-.92l-.32-.27-.75-.61-.36-.29-.81-.6-.29-.21-.1-.06-.42-.28c-.27-.17-.53-.35-.8-.51s-.37-.23-.56-.34l-.78-.45-.18-.1-.3-.14c-.41-.22-.83-.42-1.25-.62l-.49-.23c-.56-.25-1.13-.49-1.72-.71s-.91-.32-1.38-.47l-.45-.14c-.25-.08-.49-.16-.74-.22l-.18,0c-.48-.13-1-.26-1.48-.37l-.25-.06c-.58-.12-1.18-.23-1.78-.33l-.12,0-.58-.07-1-.14-.75-.07c-.32,0-.65-.07-1-.09l-.24,0-.8,0-.51,0c-.54,0-1.08,0-1.63,0h-.91l-1.05,0-.48,0c-.47,0-.94,0-1.4.09h-.07l-1.34.14-.41.06-.91.13-.13,0-.41.08-.7.12-.55.12-.66.14-.2,0-.37.09-.6.16-.56.16-.59.17-.21.07-.33.11-.59.2-.53.2-.58.21a1.57,1.57,0,0,1-.23.09l-.27.12-.62.27-.49.22-.6.29-.29.14-.17.09-.77.41-.35.2c-.37.21-.73.42-1.09.65l0,0c-.57.36-1.12.75-1.67,1.15l-.48.37-.66.5-.47.42-.56.48c-.36.33-.72.67-1.07,1l-.44.43c-.48.51-1,1-1.4,1.56l-.17.22c-.39.48-.77,1-1.13,1.47-.14.19-.27.39-.41.59-.28.4-.55.81-.81,1.24-.14.22-.28.44-.41.66-.26.45-.51.9-.76,1.36l-.33.62c-.34.67-.67,1.36-1,2.07a54.8,54.8,0,0,0-3.44,13.43,125.91,125.91,0,0,0-1.1,17.57v11.49a125.91,125.91,0,0,1,1.1-17.57A54.8,54.8,0,0,1,195,127.35c.31-.72.64-1.4,1-2.07l.33-.63c.25-.46.5-.91.76-1.35.13-.22.27-.44.41-.66.26-.43.53-.84.81-1.25l.41-.58c.36-.51.74-1,1.13-1.47l.17-.22c.45-.54.92-1.06,1.4-1.56.14-.15.29-.29.44-.43.35-.35.71-.69,1.07-1l.56-.49,1.13-.92.48-.36c.56-.41,1.12-.8,1.71-1.17.36-.23.72-.45,1.09-.66l.35-.19.77-.41c.15-.08.3-.16.46-.23l.6-.29.49-.22c.2-.1.41-.18.62-.27l.5-.21.58-.22.53-.19.59-.2.54-.18.59-.17.56-.16.6-.16.57-.14.66-.14.56-.12.68-.13.55-.09.9-.13.42-.06,1.34-.14h.07l1.4-.1.48,0,1.05,0h.91c.55,0,1.09,0,1.63,0l.51,0,1,.06,1,.09.75.08,1,.13.7.1c.6.1,1.2.21,1.78.34l.25.06c.5.11,1,.23,1.48.37l.92.26.45.14q.7.23,1.38.48c.59.22,1.16.46,1.72.71l.49.23c.42.19.84.4,1.25.61l.48.25.78.45.56.33.8.52.52.34.29.21.81.6.36.28.75.61.32.28c.34.29.68.6,1,.91s.92.92,1.37,1.41l.37.4c.31.35.62.71.92,1.07l.3.37c.39.49.77,1,1.13,1.5l.27.39c.24.35.49.71.72,1.08l.35.55.6,1c.1.18.2.36.31.54.36.65.71,1.31,1,2,.18.36.35.74.52,1.11s.21.51.32.76l.29.69.3.8c.09.23.17.47.26.71s.25.75.38,1.13l.18.56c.17.57.34,1.16.5,1.76h0c.18.67.34,1.37.51,2.08,0,.21.09.42.13.63.12.54.23,1.08.33,1.64.05.25.1.49.14.75s.08.42.11.63c.07.38.13.77.19,1.16l.09.65.18,1.29c0,.19,0,.38.07.57.07.62.14,1.25.2,1.89s.14,1.47.19,2.22c0,.22,0,.45.05.68,0,.53.07,1.07.1,1.62,0,.3,0,.6,0,.91,0,.48.05,1,.06,1.46l0,1,0,1.43c0,.66,0,1.33,0,2h0V145.77C260.83,145.2,260.82,144.65,260.82,144.09Z"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M255.6,127.08q5.23,10.67,5.23,30.18a103.75,103.75,0,0,1-1.38,18.21,40.8,40.8,0,0,1-5.09,13.83,32.63,32.63,0,0,1-12.09,11.75,33.35,33.35,0,0,1-16.5,4.14A32.93,32.93,0,0,1,207,199.63a34.21,34.21,0,0,1-12.48-15.37,54.27,54.27,0,0,1-3.12-11.86,92,92,0,0,1-1-14.05,125.91,125.91,0,0,1,1.1-17.57A54.8,54.8,0,0,1,195,127.35a30.64,30.64,0,0,1,11.79-14.18q7.73-4.87,18.46-4.88a36.47,36.47,0,0,1,12.85,2.16,29.6,29.6,0,0,1,10.14,6.33A36.27,36.27,0,0,1,255.6,127.08Zm-15.06,49A112.54,112.54,0,0,0,242,156a101,101,0,0,0-1.51-19.34q-1.51-7.53-5.09-11.38c-2.39-2.56-5.68-3.84-9.9-3.84q-9.08,0-12.61,8.59t-3.54,26.49a107,107,0,0,0,1.51,19.9q1.52,7.74,5.09,11.72a12.37,12.37,0,0,0,9.69,4q6.31,0,9.9-4.13t5-11.82"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M323.79,164.63c-1,5.12-2.63,9.07-5,11.82-.27.31-.56.6-.85.88l-.27.24c-.19.17-.39.33-.6.49l-.55.4-.6.38-.38.22q-.42.23-.87.42l-.19.09c-.37.15-.74.28-1.13.4l-.3.08c-.31.09-.63.16-1,.23l-.32.06q-.64.12-1.32.18h-.23c-.44,0-.88.06-1.33.06s-.9,0-1.34-.06l-.71-.08-.76-.1-.21,0a10.34,10.34,0,0,1-1.16-.27c-.25-.07-.48-.16-.72-.24l-.55-.19c-.24-.1-.47-.22-.7-.33l-.48-.23-.21-.13c-.28-.16-.56-.33-.82-.51s-.41-.32-.61-.48a5,5,0,0,1-.43-.34c-.21-.18-.41-.39-.61-.59l-.38-.38c-.27-.3-.52-.62-.77-.94l-.17-.22q-.36-.5-.69-1l-.1-.17c-.21-.34-.41-.68-.6-1.05l-.09-.18c-.2-.39-.4-.79-.58-1.21l-.14-.32q-.26-.6-.48-1.23l-.06-.14c-.17-.48-.33-1-.48-1.48,0-.14-.08-.28-.13-.42-.11-.4-.22-.79-.32-1.2,0-.16-.08-.31-.11-.47-.13-.54-.26-1.1-.37-1.68s-.23-1.24-.34-1.89a.77.77,0,0,0,0-.15c-.1-.61-.19-1.25-.27-1.9,0-.16-.05-.34-.07-.51-.07-.56-.13-1.14-.19-1.73,0-.11,0-.23,0-.34,0-.33-.06-.69-.09-1-.05-.49-.09-1-.13-1.48s-.05-.74-.07-1.12-.07-1-.09-1.5l-.06-1.22c0-.51,0-1-.06-1.55s0-.86,0-1.3,0-1.06,0-1.61c0-.84,0-1.69,0-2.57v11.49c0,.75,0,1.48,0,2.21,0,.12,0,.24,0,.36,0,.54,0,1.08,0,1.61l0,1.3c0,.53,0,1,.06,1.55l.06,1.22c0,.51.06,1,.09,1.5s.05.75.07,1.12.08,1,.13,1.48c0,.3.05.61.07.9,0,0,0,.08,0,.13s0,.22,0,.34c.06.59.12,1.17.19,1.73,0,.17,0,.34.07.51.08.65.17,1.29.27,1.9a.78.78,0,0,1,0,.14c.07.41.14.82.21,1.21,0,.23.08.46.13.69.11.58.24,1.13.37,1.68,0,.16.07.31.11.46s.09.38.14.56l.18.64c.05.15.09.29.13.43.15.49.3,1,.46,1.42l0,.05.06.15q.23.63.48,1.23c.05.11.09.21.14.31s.07.18.11.26c.15.33.31.65.47,1l.09.18c.1.18.2.37.3.54s.2.34.3.51l.1.17.54.81.15.2.17.22a12.06,12.06,0,0,0,.77.94l.06.07c.1.11.22.21.33.32s.39.4.6.59l.43.34c.2.16.4.33.61.47l.07.06c.24.17.5.31.75.46l.21.12,0,0c.15.08.31.14.46.21a6.36,6.36,0,0,0,.7.33c.18.08.37.13.55.19s.47.18.72.25h0c.37.1.74.19,1.12.26l.21,0,.19,0,.57.07.71.08.14,0q.58,0,1.2,0h.26c.36,0,.72,0,1.07,0h.25c.39,0,.77-.09,1.13-.15l.17,0,.32-.06.52-.11c.15,0,.3-.08.44-.12l.3-.09.18,0a9.44,9.44,0,0,0,.89-.32l.06,0,.19-.09c.21-.09.43-.18.63-.29l.24-.14c.13-.06.25-.14.38-.21s.21-.11.31-.18l.29-.2.55-.4c.08-.07.17-.12.25-.18l.35-.31.27-.25a11.68,11.68,0,0,0,.85-.87q3.57-4.14,5-11.82A112.54,112.54,0,0,0,325.24,156V144.47A112.54,112.54,0,0,1,323.79,164.63Z"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M344.07,144.09c0-.11,0-.22,0-.34l0-1.43,0-1c0-.49,0-1-.06-1.46,0-.3,0-.61,0-.91,0-.55-.06-1.08-.1-1.62,0-.22,0-.45-.05-.68-.05-.75-.11-1.49-.19-2.22v0c-.06-.63-.13-1.26-.2-1.87,0-.19-.05-.38-.07-.57l-.18-1.28L343,130c-.06-.39-.12-.78-.19-1.16,0-.21-.07-.42-.11-.63s0-.23-.05-.35l-.09-.4c-.1-.55-.21-1.1-.33-1.64,0-.21-.09-.42-.13-.63-.16-.71-.33-1.4-.51-2.08h0c-.16-.6-.34-1.19-.51-1.77l-.18-.56c-.13-.38-.25-.76-.38-1.13a1.72,1.72,0,0,1-.07-.21c-.06-.17-.13-.33-.19-.5l-.3-.79c-.1-.24-.19-.47-.29-.7s-.21-.5-.32-.75l-.11-.26c-.13-.29-.27-.57-.41-.85-.34-.69-.69-1.35-1.05-2l-.14-.25c-.05-.1-.11-.19-.17-.29l-.6-1-.35-.55c-.23-.37-.47-.72-.72-1.08-.07-.1-.14-.22-.22-.32l-.05-.06c-.36-.52-.74-1-1.13-1.5l-.3-.37c-.3-.37-.61-.72-.92-1.07l-.2-.24-.17-.17c-.45-.48-.9-1-1.37-1.4s-.67-.62-1-.92l-.32-.27-.75-.61-.36-.29-.81-.6-.29-.21-.1-.06-.42-.28c-.27-.17-.53-.35-.8-.51s-.37-.23-.56-.34l-.78-.45-.18-.1-.3-.14c-.41-.22-.82-.42-1.25-.62l-.49-.23c-.56-.25-1.13-.49-1.72-.71s-.91-.32-1.37-.47l-.46-.14c-.25-.08-.49-.16-.74-.22l-.17,0c-.49-.13-1-.26-1.49-.37l-.25-.06c-.58-.12-1.18-.23-1.78-.33l-.12,0-.57-.07-1-.14-.75-.07c-.32,0-.65-.07-1-.09l-.24,0-.8,0-.51,0c-.54,0-1.08,0-1.63,0h-.91l-1.05,0-.48,0c-.47,0-.94,0-1.4.09h-.07l-1.34.14-.41.06-.91.13-.13,0-.41.08-.69.12-.56.12-.66.14-.2,0-.37.09-.6.16-.56.16-.59.17-.21.07-.33.11-.59.2-.53.2-.58.21a1.57,1.57,0,0,1-.23.09l-.27.12-.62.27-.49.22-.6.29-.29.14-.17.09-.77.41-.35.2c-.37.21-.73.42-1.09.65l0,0c-.58.36-1.13.75-1.68,1.15-.16.12-.32.24-.47.37s-.45.33-.66.5l-.48.42c-.19.16-.37.31-.55.48q-.56.5-1.08,1l-.44.43c-.48.51-.95,1-1.4,1.56l-.17.22c-.39.48-.77,1-1.13,1.47-.14.19-.27.39-.41.59-.28.4-.55.81-.81,1.24-.14.22-.28.44-.41.66-.26.45-.51.9-.76,1.36l-.33.62c-.34.67-.67,1.36-1,2.07a54.8,54.8,0,0,0-3.44,13.43,125.91,125.91,0,0,0-1.1,17.57v11.49a125.91,125.91,0,0,1,1.1-17.57,54.8,54.8,0,0,1,3.44-13.43c.31-.72.64-1.4,1-2.07l.33-.63c.25-.46.5-.91.76-1.35.13-.22.27-.44.41-.66.26-.43.53-.84.81-1.25l.41-.58c.36-.51.74-1,1.13-1.47l.17-.22c.45-.54.92-1.06,1.4-1.56.14-.15.29-.29.44-.43q.53-.52,1.08-1l.55-.49c.37-.31.75-.62,1.14-.92l.47-.36c.56-.41,1.12-.8,1.71-1.17.36-.23.72-.45,1.09-.66l.35-.19.77-.41c.15-.08.3-.16.46-.23l.6-.29.49-.22c.2-.1.41-.18.62-.27l.5-.21.58-.22.53-.19.59-.2.54-.18.59-.17.56-.16.6-.16.57-.14.66-.14.56-.12.68-.13.55-.09.9-.13.42-.06,1.34-.14h.07l1.4-.1.48,0,1.05,0h.91c.55,0,1.09,0,1.63,0l.51,0,1,.06,1,.09.75.08,1,.13.69.1c.6.1,1.2.21,1.78.34l.25.06c.5.11,1,.23,1.49.37l.91.26.46.14c.46.15.92.31,1.37.48s1.16.46,1.72.71l.49.23c.43.19.84.4,1.25.61l.48.25.78.45.56.33.8.52.52.34.29.21.81.6.36.28.75.61.32.28c.34.29.68.6,1,.91s.92.92,1.37,1.41c.13.13.25.27.37.4.31.35.62.71.92,1.07l.3.37c.39.49.77,1,1.13,1.5l.27.39q.38.52.72,1.08l.35.55.6,1c.1.18.2.36.31.54.36.65.71,1.31,1.05,2,.18.36.35.74.52,1.11s.22.51.32.76l.29.69.3.8c.09.23.17.47.26.71s.25.75.38,1.13l.18.56c.17.57.34,1.16.51,1.76h0c.18.67.35,1.37.51,2.08,0,.21.09.42.13.63.12.54.23,1.08.33,1.64.05.25.1.49.14.75s.08.42.11.63c.07.38.13.77.19,1.16l.09.65.18,1.29c0,.19,0,.38.07.57.07.62.14,1.25.2,1.89s.14,1.47.19,2.22c0,.22,0,.45.05.68,0,.53.07,1.07.1,1.62,0,.3,0,.6,0,.91,0,.48.05,1,.06,1.46l0,1,0,1.43c0,.66,0,1.33,0,2h0V145.77C344.08,145.2,344.07,144.65,344.07,144.09Z"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M338.85,127.08q5.23,10.67,5.23,30.18a103.75,103.75,0,0,1-1.38,18.21,40.59,40.59,0,0,1-5.09,13.83,32.63,32.63,0,0,1-12.09,11.75,33.33,33.33,0,0,1-16.5,4.14,32.93,32.93,0,0,1-18.74-5.56,34.12,34.12,0,0,1-12.47-15.37,53.71,53.71,0,0,1-3.13-11.86,92,92,0,0,1-1-14.05,125.91,125.91,0,0,1,1.1-17.57,54.8,54.8,0,0,1,3.44-13.43A30.64,30.64,0,0,1,290,113.17q7.73-4.87,18.46-4.88a36.47,36.47,0,0,1,12.85,2.16,29.6,29.6,0,0,1,10.14,6.33A36.27,36.27,0,0,1,338.85,127.08Zm-15.06,49A112.54,112.54,0,0,0,325.24,156a101,101,0,0,0-1.51-19.34q-1.51-7.53-5.09-11.38t-9.9-3.84q-9.08,0-12.61,8.59t-3.54,26.49a107,107,0,0,0,1.51,19.9q1.51,7.74,5.09,11.72a12.37,12.37,0,0,0,9.69,4q6.31,0,9.9-4.13t5-11.82"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M148,177.15c-.37.32-.77.62-1.18.91l-.38.25c-.31.2-.64.4-1,.59l-.35.19c-.45.24-.91.46-1.39.66l-.14.06c-.44.18-.9.34-1.37.49l-.33.11c-.51.15-1,.29-1.56.41l-.31.06c-.46.1-.94.18-1.43.25l-.44.07c-.57.07-1.17.13-1.78.17s-1.48.08-2.25.08l-1.5,0c-.71,0-1.41-.08-2.1-.13l-.47,0q-1-.1-2-.24l-.26-.05c-.77-.11-1.55-.25-2.31-.41l-.14,0c-.77-.16-1.54-.35-2.3-.56l-.63-.17-.09,0a7.67,7.67,0,0,0-1.06-.22h-.13a5.39,5.39,0,0,0-.79-.07H120l-.58,0h-.11l-.48.06-.26,0h-.08l-.59.14-.19,0h0a7.55,7.55,0,0,0-.84.29l-.05,0-.11.06a5.75,5.75,0,0,0-.82.42l-.13.06-.08.06a7.11,7.11,0,0,0-.72.5h0c-.23.18-.45.39-.67.6l-.18.19c-.15.16-.29.32-.43.49l-.18.23q-.21.28-.39.57a1.86,1.86,0,0,0-.11.19,7.68,7.68,0,0,0-.41.81c0,.06,0,.13-.08.2-.08.22-.16.44-.23.67s-.05.2-.08.3-.1.44-.13.66a2.93,2.93,0,0,0,0,.29,7.82,7.82,0,0,0-.06,1V196a7.77,7.77,0,0,1,.06-1,2.5,2.5,0,0,1,0-.29,6.42,6.42,0,0,1,.13-.66c0-.1,0-.2.08-.3s.15-.46.23-.68c0-.06.05-.13.08-.19a9,9,0,0,1,.41-.82,1.74,1.74,0,0,1,.11-.18,5.72,5.72,0,0,1,.39-.57l.18-.24c.14-.16.28-.33.43-.48l.18-.2c.22-.21.44-.41.67-.59l0,0c.23-.18.47-.34.72-.5l.21-.11a5.75,5.75,0,0,1,.82-.42l.16-.08q.41-.16.84-.3l.22-.05.6-.14.33-.05c.16,0,.32-.05.48-.06l.69,0a9.77,9.77,0,0,1,1.07.07h.11a9.77,9.77,0,0,1,1.17.25l.41.12.22.06c.76.2,1.53.4,2.3.56l.14,0c.76.16,1.54.29,2.31.41l.18,0H128q1,.15,2,.24l.47,0c.69.06,1.39.11,2.1.13h0q.75,0,1.5,0c.77,0,1.52,0,2.25-.08h.1q.86-.06,1.68-.18l.44-.06.7-.1.73-.15.31-.06c.45-.1.89-.21,1.32-.34l.24-.07.33-.11c.47-.15.93-.31,1.37-.5l.14-.05.06,0c.46-.2.9-.41,1.33-.64l.35-.19.48-.27.49-.33.38-.25a11.57,11.57,0,0,0,1.18-.91,14.07,14.07,0,0,0,5-9.84c0-.58.08-1.18.08-1.79h0v-8.63A14.53,14.53,0,0,1,148,177.15Z"/>
|
||||||
|
<g class="cls-16">
|
||||||
|
<g class="cls-17">
|
||||||
|
<g class="cls-16">
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M172.52,158.33A33.35,33.35,0,0,0,172,155a26.4,26.4,0,0,0-.82-2.78,22.25,22.25,0,0,0-1.16-2.69,21.93,21.93,0,0,0-2-3.24,25.52,25.52,0,0,0-3-3.25,29.16,29.16,0,0,0-7.34-4.85,40.29,40.29,0,0,0-6.32-2.35,42.23,42.23,0,0,0-5.08-1.08c-1.21-.17-2.4-.29-3.56-.35l-1.53-.06c-1,0-2.05,0-3.12,0-1.5,0-3.06,0-4.68.15l-.64.05v8.64l.64,0C135,143,136.53,143,138,143q1.6,0,3.12.06l1.53.06c1.16.06,2.35.17,3.56.35a42.23,42.23,0,0,1,5.08,1.08,39.31,39.31,0,0,1,6.32,2.35,29.16,29.16,0,0,1,7.34,4.85,24.86,24.86,0,0,1,3,3.25,21.84,21.84,0,0,1,2,3.23,22.39,22.39,0,0,1,1.16,2.7,26.4,26.4,0,0,1,.82,2.78,32.36,32.36,0,0,1,.57,3.3,43.27,43.27,0,0,1,.3,4.55v-8.64A43.27,43.27,0,0,0,172.52,158.33Z"/>
|
||||||
|
<path class="cls-18" d="M172.82,171.52v0"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<polygon class="cls-14" points="113.49 159.94 113.49 151.3 117.24 96.8 117.24 105.44 113.49 159.94"/>
|
||||||
|
<path class="cls-14"
|
||||||
|
d="M163.16,105.56l.71.16.31.07.29.1.46.17.3.12.37.18c.2.1.39.21.58.32l.25.15a8.15,8.15,0,0,1,.76.55l0,0c.23.19.44.39.65.6l.2.22a6.4,6.4,0,0,1,.42.49l.24.31.18.27c.09.13.17.26.25.39l.16.29c0,.09.09.19.14.29s.2.43.28.65l.12.31a4.77,4.77,0,0,1,.15.54c0,.11.07.22.09.33s.06.33.09.5l.06.37c0,.16,0,.33,0,.5s0,.29,0,.44v-8.76c0-.1,0-.21,0-.32s0-.34,0-.5a.19.19,0,0,1,0-.08,2.93,2.93,0,0,0-.05-.29c0-.17,0-.33-.09-.49s0-.07,0-.1a2.25,2.25,0,0,0-.08-.24,5.44,5.44,0,0,0-.15-.54.57.57,0,0,1,0-.14l-.08-.16c-.08-.23-.18-.44-.28-.66,0,0-.05-.12-.08-.17l-.06-.12c-.05-.1-.11-.19-.16-.28a3.73,3.73,0,0,0-.25-.39l-.18-.28-.13-.18a.69.69,0,0,1-.11-.13,6.4,6.4,0,0,0-.42-.49l-.2-.22a7.21,7.21,0,0,0-.65-.59l0,0a8.15,8.15,0,0,0-.76-.55l-.25-.15c-.19-.11-.38-.22-.58-.32l-.14-.08-.23-.09-.3-.13-.46-.17-.29-.09-.11,0-.2,0c-.23-.06-.47-.11-.71-.15l-.17,0h-.18a5.11,5.11,0,0,0-.55,0l-.25,0H117.24v8.63H161.7c.19,0,.38,0,.56,0l.55.05Z"/>
|
||||||
|
<path class="cls-15"
|
||||||
|
d="M161.7,105.43a8.48,8.48,0,1,1,0,17H134.13l-1.42,20.78c1.84-.15,3.62-.21,5.32-.21s3.18,0,4.65.12c7.58.36,16.62,3.36,22.3,8.63s7.84,11.57,7.84,20.58c0,9.94-2.36,16.89-9.22,23.21s-15.9,9.69-27.68,9.69c-6.9,0-12.87,0-18.22-1.53A7.93,7.93,0,0,1,120,188.1a8.4,8.4,0,0,1,2.35.34,42,42,0,0,0,11.75,1.65q8.88,0,13.88-4.31t5-11.63q0-15.36-21.36-15.36a165,165,0,0,0-18.19,1.15l3.75-54.51Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M309.61,253.46a4.84,4.84,0,0,1-2.85.39c-1-.12-3.07-2.25-4.39-2.8a14.58,14.58,0,0,1-4.61-4c-1.21-1.6-.74-2.07-.43-2.32-.28,1.32,2.22,4.34,5.08,5.86,3.12,1.66,4.45,3.22,5.88,2.76,1.14-.36,2.55-1,3-2.08C311.7,252.68,310.51,253,309.61,253.46Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M311.11,247.65a22.22,22.22,0,0,0,.27,2.61c.25,1.83-1.65,2.65-3.09,3.11s-2.76-1.1-5.88-2.76-5.8-5.1-4.93-6.18c.82-.68,3.19-.55,5.14.64a29.2,29.2,0,0,1,3.05,2.09h0c-.06-.19-.12-.35-.14-.43-.09-.3.29-.74.8-.33s3.09,0,4.17-.57l.09-.05c1-.58.87.29.64,1A2.84,2.84,0,0,0,311.11,247.65Z"/>
|
||||||
|
<path class="cls-21" d="M310.5,245.83l.09-.05c1-.58.87.29.64,1a2.84,2.84,0,0,0-.12.86"/>
|
||||||
|
<path class="cls-21" d="M305.3,248.31c.69.11.54-.62.37-1.14"/>
|
||||||
|
<path class="cls-22"
|
||||||
|
d="M297.34,244.74h0c-.31.25-.78.72.43,2.32a14.58,14.58,0,0,0,4.61,4c1.32.55,3.38,2.68,4.39,2.8a4.84,4.84,0,0,0,2.85-.39c.9-.44,2.09-.78,1.66-2.17"/>
|
||||||
|
<path d="M305.76,168.75c-.06.15-.45.76-.45.76l-.15.14-.47-.18-.45.3-.4-.22s-.06-.5-.36.1c-.12-.28-.86-.23-1.74-.76a3.15,3.15,0,0,1-1.06-2.71c.11-.61.69-.93.34-1.31s-.48-.24-.75-.08-.6-.32-1.62-.65c-.09,0-1.12-2.63-.77-3.79a4.24,4.24,0,0,1,2.16-3,7,7,0,0,1,5.12-.66c1.72.52,3.43.94,4.08,4.66a6.34,6.34,0,0,1-1.61,6,3.79,3.79,0,0,1-1.07.88C306.25,168.51,306,168.2,305.76,168.75Z"/>
|
||||||
|
<path class="cls-23"
|
||||||
|
d="M316.53,186.52a3.29,3.29,0,0,1-1.34,1,4.82,4.82,0,0,1-3.3.2c.15-3.54.27-6.22.27-6.22l1-7.75a1.23,1.23,0,0,1,.27.52C314.07,176.7,315.88,183.71,316.53,186.52Z"/>
|
||||||
|
<path class="cls-24"
|
||||||
|
d="M315.34,191.29v0a1.5,1.5,0,0,1-1.84,1.57l-2.69-1.24c.06-1.78,1-2.38,1.08-4a4.82,4.82,0,0,0,3.3-.2Z"/>
|
||||||
|
<path class="cls-25"
|
||||||
|
d="M300.82,166.25a2.91,2.91,0,0,0,.92,2.45c.77.47,1.43.43,1.53.68l.33-.68.33.79.25-.66.57.55.08-.8s.37.94.43.8c.19-.49.23-.43.5-.63-.12,1.32-.46,3.57.47,3.71l.54.08c-1.08,1.73-6,1.17-6.78.2a2.38,2.38,0,0,0,1.16-.67c.59-1,.86-3,0-3.27a2.47,2.47,0,0,1-1.88-2.11c-.11-.51-.23-1.65-.33-2.45h0c.89.29,1.14.59,1.36.46a.62.62,0,0,1,.87.14C301.44,165.18,300.91,165.69,300.82,166.25Z"/>
|
||||||
|
<path class="cls-26"
|
||||||
|
d="M294.81,182.83a.83.83,0,0,1-.41,1.1L285,188.22a.83.83,0,0,1-1.1-.41l-6.05-13.32a.83.83,0,0,1,.41-1.1l9.45-4.29a.83.83,0,0,1,1.1.41Z"/>
|
||||||
|
<path class="cls-27"
|
||||||
|
d="M288.29,170.34l5.14,11.31a.72.72,0,0,1-.36,1l-8.24,3.75a.73.73,0,0,1-1-.36l-5.14-11.31a.72.72,0,0,1,.36-1l8.24-3.75A.73.73,0,0,1,288.29,170.34Z"/>
|
||||||
|
<circle class="cls-27" cx="289.29" cy="185.23" r="0.5" transform="translate(57.59 438.83) rotate(-80.22)"/>
|
||||||
|
<path class="cls-25"
|
||||||
|
d="M285.93,190.32s-1.4-1.52-2-2.13-1.86-2.34-2-2.46-1.82-5.36-2.18-5.62.5-.8,1.14.51,1.86,3,2.43,3,.31-1.59.72-1.85.35,0,.5.15-.34,2,.09,2.65.34,1.79.66,2.29l1.84,2.88Z"/>
|
||||||
|
<path class="cls-25"
|
||||||
|
d="M284.63,188.92s3.61,4.34,7,6c.17.08,1.22.48,1.51-.1a24.27,24.27,0,0,0,1-4.75c.07-.34.25-4,.25-4L290.88,185l-.28,5.53a.06.06,0,0,1-.09.05l-4.73-2.84Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M313.16,173.71l-1,7.75s-.12,2.68-.27,6.22c-.07,1.59-.14,3.35-.2,5.13-.19,5.23-.33,10.58-.15,11.9l-.28,0c-1.85.25-11.81.82-15.38.24a3.6,3.6,0,0,1-1-.29c.28-1.59.43-20.67.43-20.67s-.35,2.07-.51,3.67c-1.63.6-2.42.32-4.63-.63.18-1.38,1.93-9.68,3.19-12.13a2.78,2.78,0,0,1,2.15-1.29h0a26.47,26.47,0,0,0,4.5-.92c.76,1,5.7,1.53,6.78-.2,1.28.18,4.1.53,5.54.71A1.31,1.31,0,0,1,313.16,173.71Z"/>
|
||||||
|
<path class="cls-28"
|
||||||
|
d="M311.26,204.76,310.1,225l0,21c-.53.24-3,.89-3.86.38l-1-20.22-1-16.14a.67.67,0,0,0-.73-.63.65.65,0,0,0-.44.2.71.71,0,0,0-.19.44l-2.76,16.56L299.6,243v.05l-.27,4.33c-1.13.44-3.76.56-4.21.12l-.74-22.18,1.5-20.36C299.45,205.58,309.41,205,311.26,204.76Z"/>
|
||||||
|
<path class="cls-19"
|
||||||
|
d="M300.08,252.26a4.88,4.88,0,0,1-2.65,1.13c-1,.15-3.56-1.37-5-1.55a14.41,14.41,0,0,1-5.5-2.63c-1.59-1.22-1.25-1.8-1-2.12.07,1.34,3.28,3.6,6.44,4.32,3.44.78,5.13,1.94,6.4,1.11,1-.65,2.21-1.59,2.33-2.79C301.88,251,300.83,251.6,300.08,252.26Z"/>
|
||||||
|
<path class="cls-20"
|
||||||
|
d="M300,246.27a22.16,22.16,0,0,0,.95,2.44c.72,1.7-.89,3-2.16,3.81s-3-.33-6.4-1.11-6.94-3.39-6.39-4.66c.62-.88,2.94-1.37,5.13-.74a30.64,30.64,0,0,1,3.5,1.21h0l-.26-.38c-.16-.26.09-.79.69-.53s3-.82,3.87-1.64l.08-.07c.83-.84.91.05.88.81A3.07,3.07,0,0,0,300,246.27Z"/>
|
||||||
|
<path class="cls-21" d="M298.92,244.67l.08-.07c.83-.84.78.06.88.81a18.24,18.24,0,0,0,1.23,4.32"/>
|
||||||
|
<path class="cls-21" d="M294.56,248.43c.69-.07.36-.75.06-1.2"/>
|
||||||
|
<path class="cls-22"
|
||||||
|
d="M285.94,247.08h0c-.23.32-.57.9,1,2.12a14.41,14.41,0,0,0,5.5,2.63c1.41.18,4,1.7,5,1.55a4.88,4.88,0,0,0,2.65-1.13c.75-.66,1.8-1.3,1-2.53"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/images/login-icon.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/images/login-left.png
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
src/assets/logo.png
Normal file
After Width: | Height: | Size: 59 KiB |
169
src/components/DataTable copy.jsx
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
h,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
onMounted,
|
||||||
|
toRefs
|
||||||
|
} from 'vue';
|
||||||
|
import { ElTable, ElTableColumn, ElPagination, ElLoading } from 'element-plus';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup(props, { attrs, slots, expose }) {
|
||||||
|
console.log(props,'_this');
|
||||||
|
const {
|
||||||
|
request = () => { },
|
||||||
|
pagination: _pagination = {},
|
||||||
|
column = [],
|
||||||
|
params = {},
|
||||||
|
loading = {},
|
||||||
|
debug = false,
|
||||||
|
border = true,
|
||||||
|
_tableRef = {},
|
||||||
|
...attr
|
||||||
|
} = attrs;
|
||||||
|
|
||||||
|
const pagination = {
|
||||||
|
page: 1,
|
||||||
|
background: true,
|
||||||
|
layout: 'prev,pager,next,jumper,total,sizes',
|
||||||
|
..._pagination
|
||||||
|
};
|
||||||
|
|
||||||
|
const log = (type, ...msg) => {
|
||||||
|
debug && console.log(`[ DataTable ] ${type} => `, ...msg);
|
||||||
|
};
|
||||||
|
log('setup', {
|
||||||
|
props,
|
||||||
|
attrs,
|
||||||
|
slots
|
||||||
|
});
|
||||||
|
|
||||||
|
const tableRef = ref(null);
|
||||||
|
|
||||||
|
const tableData = ref({
|
||||||
|
msg: '加载中...',
|
||||||
|
data: [],
|
||||||
|
count: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const _params = reactive({
|
||||||
|
...toRefs(params),
|
||||||
|
page: 1,
|
||||||
|
limit: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求数据
|
||||||
|
const fetchData = debounce(async v => {
|
||||||
|
const _loading = ElLoading.service({
|
||||||
|
target: tableRef.value,
|
||||||
|
...loading
|
||||||
|
});
|
||||||
|
// setTimeout(async () => {
|
||||||
|
log('fetchData', _params, params);
|
||||||
|
try {
|
||||||
|
const { code, data, count, msg } = await request(_params);
|
||||||
|
|
||||||
|
if (code == 0) {
|
||||||
|
tableData.value.data = data;
|
||||||
|
tableData.value.count = count;
|
||||||
|
if (count === 0) {
|
||||||
|
tableData.value.msg = '暂无数据';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tableData.value.msg = msg;
|
||||||
|
tableData.value.data.length = 0;
|
||||||
|
tableData.value.count = 0;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
tableData.value.msg = error.message || '服务器返回异常';
|
||||||
|
} finally {
|
||||||
|
_loading.close();
|
||||||
|
}
|
||||||
|
// });
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
expose({
|
||||||
|
reload: fetchData
|
||||||
|
});
|
||||||
|
|
||||||
|
// watch(attrs.params, (v) => {
|
||||||
|
// log("watch attr.params", v);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// watch(params, (v) => {
|
||||||
|
// log("watch params", v);
|
||||||
|
// fetchData();
|
||||||
|
// });
|
||||||
|
watch(_params, v => {
|
||||||
|
log('watch _params', v);
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
|
// watch(
|
||||||
|
// params,
|
||||||
|
// (v) => {
|
||||||
|
// log("watch deep params", v);
|
||||||
|
// fetchData();
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// deep: true,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// watch(
|
||||||
|
// _params,
|
||||||
|
// (v) => {
|
||||||
|
// log("watch deep _params", v);
|
||||||
|
// fetchData();
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// deep: true,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// onActivated(() => {
|
||||||
|
// log("onActivated");
|
||||||
|
// });
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
log('onMounted');
|
||||||
|
fetchData();
|
||||||
|
console.log(attrs,'this');
|
||||||
|
});
|
||||||
|
return () => (
|
||||||
|
<div ref={tableRef}>
|
||||||
|
<ElTable
|
||||||
|
{...attr}
|
||||||
|
border={border}
|
||||||
|
data={tableData.value.data}
|
||||||
|
emptyText={tableData.value.msg}
|
||||||
|
ref={attrs._tableRef}
|
||||||
|
>
|
||||||
|
{column.map(v => {
|
||||||
|
const { prop } = v;
|
||||||
|
const slotsProp = slots[prop];
|
||||||
|
let temp = null;
|
||||||
|
if (slotsProp) {
|
||||||
|
temp = {
|
||||||
|
default: slotsProp
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return h(ElTableColumn, v, temp);
|
||||||
|
})}
|
||||||
|
</ElTable>
|
||||||
|
{_pagination === false ? (
|
||||||
|
''
|
||||||
|
) : (
|
||||||
|
<ElPagination
|
||||||
|
{...pagination}
|
||||||
|
onCurrentChange={val => (_params.page = val)}
|
||||||
|
onSizeChange={val => (_params.limit = val)}
|
||||||
|
total={tableData.value.count}
|
||||||
|
pageSize={_params.limit}
|
||||||
|
></ElPagination>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
165
src/components/DataTable.jsx
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
h,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
onMounted,
|
||||||
|
toRefs
|
||||||
|
} from 'vue';
|
||||||
|
import { ElTable, ElTableColumn, ElPagination, ElLoading } from 'element-plus';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup(props, { attrs, slots, expose }) {
|
||||||
|
const {
|
||||||
|
request = () => { },
|
||||||
|
pagination: _pagination = {},
|
||||||
|
column = [],
|
||||||
|
params = {},
|
||||||
|
loading = {},
|
||||||
|
debug = false,
|
||||||
|
border = false,
|
||||||
|
...attr
|
||||||
|
} = attrs;
|
||||||
|
|
||||||
|
const pagination = {
|
||||||
|
page: 1,
|
||||||
|
background: true,
|
||||||
|
layout: 'prev,pager,next,jumper,total,sizes',
|
||||||
|
..._pagination
|
||||||
|
};
|
||||||
|
|
||||||
|
const log = (type, ...msg) => {
|
||||||
|
debug && console.log(`[ DataTable ] ${type} => `, ...msg);
|
||||||
|
};
|
||||||
|
log('setup', {
|
||||||
|
props,
|
||||||
|
attrs,
|
||||||
|
slots
|
||||||
|
});
|
||||||
|
|
||||||
|
const tableRef = ref(null);
|
||||||
|
|
||||||
|
const tableData = ref({
|
||||||
|
msg: '加载中...',
|
||||||
|
data: [],
|
||||||
|
count: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const _params = reactive({
|
||||||
|
...toRefs(params),
|
||||||
|
page: 1,
|
||||||
|
limit: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求数据
|
||||||
|
const fetchData = debounce(async v => {
|
||||||
|
const _loading = ElLoading.service({
|
||||||
|
target: tableRef.value,
|
||||||
|
...loading
|
||||||
|
});
|
||||||
|
// setTimeout(async () => {
|
||||||
|
log('fetchData', _params, params);
|
||||||
|
try {
|
||||||
|
const { code, data, count, msg } = await request(_params);
|
||||||
|
|
||||||
|
if (code == 0) {
|
||||||
|
tableData.value.data = data;
|
||||||
|
tableData.value.count = count;
|
||||||
|
if (count === 0) {
|
||||||
|
tableData.value.msg = '暂无数据';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tableData.value.msg = msg;
|
||||||
|
tableData.value.data.length = 0;
|
||||||
|
tableData.value.count = 0;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
tableData.value.msg = error.message || '服务器返回异常';
|
||||||
|
} finally {
|
||||||
|
_loading.close();
|
||||||
|
}
|
||||||
|
// });
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
expose({
|
||||||
|
reload: fetchData
|
||||||
|
});
|
||||||
|
|
||||||
|
// watch(attrs.params, (v) => {
|
||||||
|
// log("watch attr.params", v);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// watch(params, (v) => {
|
||||||
|
// log("watch params", v);
|
||||||
|
// fetchData();
|
||||||
|
// });
|
||||||
|
watch(_params, v => {
|
||||||
|
log('watch _params', v);
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
|
// watch(
|
||||||
|
// params,
|
||||||
|
// (v) => {
|
||||||
|
// log("watch deep params", v);
|
||||||
|
// fetchData();
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// deep: true,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// watch(
|
||||||
|
// _params,
|
||||||
|
// (v) => {
|
||||||
|
// log("watch deep _params", v);
|
||||||
|
// fetchData();
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// deep: true,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
// onActivated(() => {
|
||||||
|
// log("onActivated");
|
||||||
|
// });
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
log('onMounted');
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
|
return () => (
|
||||||
|
<div ref={tableRef}>
|
||||||
|
<ElTable
|
||||||
|
{...attr}
|
||||||
|
border={border}
|
||||||
|
data={tableData.value.data}
|
||||||
|
emptyText={tableData.value.msg}
|
||||||
|
>
|
||||||
|
{column.map(v => {
|
||||||
|
const { prop } = v;
|
||||||
|
const slotsProp = slots[prop];
|
||||||
|
let temp = null;
|
||||||
|
if (slotsProp) {
|
||||||
|
temp = {
|
||||||
|
default: slotsProp
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return h(ElTableColumn, v, temp);
|
||||||
|
})}
|
||||||
|
</ElTable>
|
||||||
|
{_pagination === false ? (
|
||||||
|
''
|
||||||
|
) : (
|
||||||
|
<ElPagination
|
||||||
|
{...pagination}
|
||||||
|
onCurrentChange={val => (_params.page = val)}
|
||||||
|
onSizeChange={val => (_params.limit = val)}
|
||||||
|
total={tableData.value.count}
|
||||||
|
pageSize={_params.limit}
|
||||||
|
></ElPagination>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
77
src/components/DepartmentTreeDialog.vue
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
title="请选择部门"
|
||||||
|
v-model="dialogVisible"
|
||||||
|
@closed="closeDialog"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<el-alert
|
||||||
|
:title="`当前选中节点:` + currentNode.department_name"
|
||||||
|
type="success"
|
||||||
|
/>
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="treeData"
|
||||||
|
default-expand-all
|
||||||
|
node-key="id"
|
||||||
|
highlight-current
|
||||||
|
accordion
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
>
|
||||||
|
</el-tree>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="handleCommitClick">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from 'vue';
|
||||||
|
import { getUserDepartmentTree } from '~/service/user';
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const treeRef = ref();
|
||||||
|
const treeData = ref([]);
|
||||||
|
|
||||||
|
const currentNode = reactive({
|
||||||
|
department_guid: '',
|
||||||
|
department_name: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function
|
||||||
|
});
|
||||||
|
|
||||||
|
getUserDepartmentTree().then(({ code, data }) => {
|
||||||
|
if (code === 0) {
|
||||||
|
treeData.value = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(v) => {
|
||||||
|
dialogVisible.value = v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits('update:modelValue', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNodeClick = (value) => {
|
||||||
|
currentNode.department_guid = value.id;
|
||||||
|
currentNode.department_name = value.label;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCommitClick = async () => {
|
||||||
|
props.done(currentNode);
|
||||||
|
closeDialog();
|
||||||
|
};
|
||||||
|
</script>
|
162
src/components/DialogForm.jsx
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import { defineComponent, ref, watch, computed, h } from 'vue';
|
||||||
|
import { ElForm, ElDialog, ElButton, ElIcon } from 'element-plus';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
emits: ['update:visible'],
|
||||||
|
setup(props, { attrs, slots, expose, emit }) {
|
||||||
|
const {
|
||||||
|
debug = false,
|
||||||
|
title = '',
|
||||||
|
visible = false,
|
||||||
|
model = {},
|
||||||
|
rules = [],
|
||||||
|
onClosed = () => {},
|
||||||
|
dialogProps = {},
|
||||||
|
formProps = {},
|
||||||
|
disabled = false,
|
||||||
|
...attr
|
||||||
|
} = attrs;
|
||||||
|
|
||||||
|
const log = (type, ...msg) => {
|
||||||
|
debug && console.log(`[ DialogForm ] ${type} => `, ...msg);
|
||||||
|
};
|
||||||
|
log('setup', {
|
||||||
|
props,
|
||||||
|
attrs,
|
||||||
|
slots,
|
||||||
|
emit
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref(null);
|
||||||
|
const _visible = ref(!!visible);
|
||||||
|
const _model = ref(model);
|
||||||
|
|
||||||
|
log('_visible', _visible.value);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => attrs.model,
|
||||||
|
v => {
|
||||||
|
log('watch model', v);
|
||||||
|
_model.value = v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => attrs.visible,
|
||||||
|
v => {
|
||||||
|
log('watch visible', v);
|
||||||
|
_visible.value = v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// // 验证表单
|
||||||
|
// const validate = computed(() => formRef.value?.validate);
|
||||||
|
// // 重置表单
|
||||||
|
// const resetFields = computed(() => formRef.value?.resetFields);
|
||||||
|
// 验证表单
|
||||||
|
const validate = () => {
|
||||||
|
return formRef.value && formRef.value.validate();
|
||||||
|
};
|
||||||
|
// 重置表单
|
||||||
|
const resetFields = () => {
|
||||||
|
return formRef.value && formRef.value.resetFields();
|
||||||
|
};
|
||||||
|
// 打开弹窗
|
||||||
|
const _onOpen = () => {
|
||||||
|
log('_onOpen', _visible.value);
|
||||||
|
_visible.value = true;
|
||||||
|
emit('update:visible', true);
|
||||||
|
};
|
||||||
|
// 关闭弹窗
|
||||||
|
const _onClose = () => {
|
||||||
|
log('_onClose', _visible.value);
|
||||||
|
_visible.value = false;
|
||||||
|
emit('update:visible', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
expose({
|
||||||
|
form: formRef,
|
||||||
|
open: _onOpen,
|
||||||
|
close: _onClose,
|
||||||
|
resetFields,
|
||||||
|
validate
|
||||||
|
});
|
||||||
|
// 关闭弹出
|
||||||
|
const _onClosed = () => {
|
||||||
|
resetFields();
|
||||||
|
_onClose();
|
||||||
|
onClosed();
|
||||||
|
};
|
||||||
|
|
||||||
|
let openButton = '';
|
||||||
|
if (slots.openButton) {
|
||||||
|
openButton = slots.openButton(_onOpen);
|
||||||
|
} else {
|
||||||
|
switch (typeof attrs.openButton) {
|
||||||
|
case 'function':
|
||||||
|
openButton = attrs.openButton(_onOpen);
|
||||||
|
break;
|
||||||
|
case 'object':
|
||||||
|
const { text, icon, ...temp } = attrs.openButton;
|
||||||
|
openButton = (
|
||||||
|
<ElButton type="primary" {...temp} onClick={_onOpen}>
|
||||||
|
{text}
|
||||||
|
{icon ? h(ElIcon, null, { default: () => h(icon) }) : ''}
|
||||||
|
</ElButton>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
openButton = (
|
||||||
|
<ElButton type="primary" onClick={_onOpen}>
|
||||||
|
{attrs.openButton}
|
||||||
|
</ElButton>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
if (attrs.openButton) {
|
||||||
|
openButton = (
|
||||||
|
<ElButton type="primary" onClick={_onOpen}>
|
||||||
|
打开
|
||||||
|
</ElButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
openButton = (
|
||||||
|
<ElButton type="primary" onClick={_onOpen}>
|
||||||
|
打开
|
||||||
|
</ElButton>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div
|
||||||
|
class="addButton"
|
||||||
|
style={{
|
||||||
|
display: 'inline-block'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{openButton}
|
||||||
|
<ElDialog
|
||||||
|
{...dialogProps}
|
||||||
|
modelValue={_visible.value}
|
||||||
|
title={title}
|
||||||
|
onClosed={_onClosed}
|
||||||
|
// 去掉会影响数据表格
|
||||||
|
destroyOnClose={true}
|
||||||
|
v-slots={{ title: slots.title, footer: slots.footer }}
|
||||||
|
>
|
||||||
|
<ElForm
|
||||||
|
{...formProps}
|
||||||
|
disabled={disabled}
|
||||||
|
ref={formRef}
|
||||||
|
model={_model}
|
||||||
|
rules={rules}
|
||||||
|
v-slots={{ default: slots.default }}
|
||||||
|
></ElForm>
|
||||||
|
</ElDialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
47
src/components/DictTag.vue
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<template v-for="(item, index) in props.options" :key="item.dictionary_guid">
|
||||||
|
<template v-if="values.includes(item.dictionary_value)">
|
||||||
|
<span v-if="item.dictionary_list_class == 'default' || item.dictionary_list_class == ''" :key="item.dictionary_value" :index="index" :class="item.cssClass">
|
||||||
|
{{ item.dictionary_name }} <i v-if="showValue">#{{ item.dictionary_value }}</i>
|
||||||
|
</span>
|
||||||
|
<el-tag
|
||||||
|
v-else
|
||||||
|
:disable-transitions="true"
|
||||||
|
:index="index"
|
||||||
|
:type="item.dictionary_list_class == 'primary' ? '' : item.dictionary_list_class"
|
||||||
|
:class="item.cssClass">
|
||||||
|
{{ item.dictionary_name }}
|
||||||
|
<i v-if="showValue">#{{ item.dictionary_value }}</i>
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {computed} from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 数据
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
// 当前的值
|
||||||
|
value: [Number, String, Array, Boolean],
|
||||||
|
showValue: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const values = computed(() => {
|
||||||
|
if (props.value !== null && typeof props.value !== 'undefined') {
|
||||||
|
return Array.isArray(props.value) ? props.value : [String(props.value)]
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-tag + .el-tag {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
317
src/components/Echarts/CountBox.vue
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<template>
|
||||||
|
<div class="top_box_pos">
|
||||||
|
|
||||||
|
<div class="top_content_box">
|
||||||
|
<div class="top_content_left_box">
|
||||||
|
<div class="top_content_left_title_box">
|
||||||
|
<div class="top_content_left_title_img_box">
|
||||||
|
<img :src=props.img alt="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="top_content_left_title_text_box">
|
||||||
|
<div class="top_content_left_title_text_sub_title">{{ props.text }}</div>
|
||||||
|
<div class="top_content_left_title_text_title">{{ props.count }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="top_content_right_box">
|
||||||
|
<div class="top_content_right_num_box">
|
||||||
|
<img v-if="props.percentage > 0" src="/img/home/上升.png" alt="">
|
||||||
|
<div class="top_content_right_num">{{ props.percentage }}%</div>
|
||||||
|
</div>
|
||||||
|
<div class="top_content_right_price">同昨日对比</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="top_line_box">
|
||||||
|
<div class="mainBox" :id="'mainBox' + props.idx"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 数据
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: [
|
||||||
|
['1', 500],
|
||||||
|
['2', 900],
|
||||||
|
['3', 460],
|
||||||
|
['4', 1150],
|
||||||
|
['5', 300],
|
||||||
|
['6', 1000],
|
||||||
|
['7', 400],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
img: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
percentage: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
idx: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(props.data,'this is data');
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await echartsInit()
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
echarts.dispose(document.getElementById('mainBox' + props.idx));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 数据预览 echarts 参数
|
||||||
|
let options = ref({
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
show: false,
|
||||||
|
axisTick: {
|
||||||
|
show: false // 不显示坐标轴刻度线
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false, // 不显示坐标轴线
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false, // 不显示坐标轴上的文字
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false // 不显示网格线
|
||||||
|
},
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
boundaryGap: [0, '30%'],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
visualMap: {
|
||||||
|
type: 'piecewise',
|
||||||
|
show: false,
|
||||||
|
// 淡化效果
|
||||||
|
dimension: 0.1,
|
||||||
|
// 最小值
|
||||||
|
min: 0,
|
||||||
|
seriesIndex: 1,
|
||||||
|
pieces: [
|
||||||
|
{
|
||||||
|
gt: 1,
|
||||||
|
lt: 3,
|
||||||
|
color: 'rgba(0, 0, 180, 0.4)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
gt: 5,
|
||||||
|
lt: 7,
|
||||||
|
color: 'rgba(0, 0, 180, 0.4)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'line',
|
||||||
|
smooth: 0.6,
|
||||||
|
symbol: 'none',
|
||||||
|
showSymbol: true,
|
||||||
|
|
||||||
|
lineStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear', // 线性渐变
|
||||||
|
x: 0.7,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: '#a5b9fe' // 0%处的颜色为淡橙色
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: '#4e70df' // 100%处的颜色为橙色
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear', // 线性渐变
|
||||||
|
x: 0,
|
||||||
|
y: 0.8,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0.4,
|
||||||
|
colorStops: [{
|
||||||
|
offset: 0,
|
||||||
|
color: '#ffffff' // 0%处的颜色为淡橙色
|
||||||
|
}, {
|
||||||
|
offset: 1,
|
||||||
|
color: '#e7f1ff' // 100%处的颜色为橙色
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaStyle: {},
|
||||||
|
data: props.data
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 顶部第一个盒子
|
||||||
|
async function echartsInit() {
|
||||||
|
let myChart = echarts.getInstanceByDom(document.getElementById('mainBox' + props.idx)); //有的话就获取已有echarts实例的DOM节点。
|
||||||
|
|
||||||
|
if (myChart == null) { // 如果不存在,就进行初始化。
|
||||||
|
myChart = echarts.init(document.getElementById('mainBox' + props.idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
options.value && myChart.setOption(options.value);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.mainBox {
|
||||||
|
width: 450px;
|
||||||
|
margin-top: -139px;
|
||||||
|
margin-left: -45px;
|
||||||
|
margin-top: -70px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_box_pos {
|
||||||
|
width: 350px;
|
||||||
|
height: 250px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
box-shadow: 0 0 30px 10px #f8f8fd;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_box {
|
||||||
|
width: 100%;
|
||||||
|
height: 40%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 顶部盒子左边
|
||||||
|
.top_content_left_box {
|
||||||
|
width: 45%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_box {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px 0 0 5px;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_img_box {
|
||||||
|
width: 35%;
|
||||||
|
height: 60%;
|
||||||
|
// overflow: hidden;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_img_box img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_text_box {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_text_title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_left_title_text_sub_title {
|
||||||
|
font-size: 15px;
|
||||||
|
margin-top: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #9aa4ba;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_right_box {
|
||||||
|
width: 45%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 23px 20px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_right_price {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
margin-right: -10px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
color: #9ca1bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Top_content_right_price {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #9ca1bb;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_right_num_box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_content_right_num_box img {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
object-fit: contain;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.top_line_box {
|
||||||
|
width: 100%;
|
||||||
|
height: 60%;
|
||||||
|
}
|
||||||
|
</style>
|
261
src/components/FileUpload.vue
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
<template>
|
||||||
|
<div class="upload-file">
|
||||||
|
<el-upload
|
||||||
|
multiple
|
||||||
|
:action="fileUpload"
|
||||||
|
:before-upload="handleBeforeUpload"
|
||||||
|
:file-list="fileList"
|
||||||
|
:limit="limit"
|
||||||
|
:on-error="handleUploadError"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
:on-success="handleUploadSuccess"
|
||||||
|
:show-file-list="false"
|
||||||
|
:data="data"
|
||||||
|
:drag="drag"
|
||||||
|
:headers="headers"
|
||||||
|
:auto-upload="autoUpload"
|
||||||
|
class="upload-file-uploader"
|
||||||
|
ref="upload"
|
||||||
|
>
|
||||||
|
<!-- 拖拽上传 -->
|
||||||
|
<template v-if="drag">
|
||||||
|
+
|
||||||
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
|
</template>
|
||||||
|
<!-- 上传按钮 -->
|
||||||
|
<el-button type="primary" v-if="!drag">选取文件</el-button>
|
||||||
|
<!-- 上传提示 -->
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip" v-if="showTip">
|
||||||
|
请上传
|
||||||
|
<template v-if="fileSize">
|
||||||
|
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||||
|
</template>
|
||||||
|
<template v-if="fileType">
|
||||||
|
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||||
|
</template>
|
||||||
|
的文件
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<!-- 文件列表 -->
|
||||||
|
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||||
|
<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||||
|
<el-link :href="`${file.url}`" :underline="false" target="_blank">
|
||||||
|
<svg-icon class-name="doc-icon" name="documentation" />
|
||||||
|
{{ file.name }}
|
||||||
|
</el-link>
|
||||||
|
<div class="ele-upload-list__item-content-action" v-if="isDetail == false">
|
||||||
|
<el-link :underline="false" @click="handleDelete(index)" type="danger" style="margin-left: 10px">删除</el-link>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref,reactive,watch,computed } from "vue";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { fileUpload } from "~/service/common";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: [String, Object, Array],
|
||||||
|
// 数量限制
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 大小限制(MB)
|
||||||
|
fileSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
|
fileType: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf'],
|
||||||
|
},
|
||||||
|
// 是否显示提示
|
||||||
|
isShowTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 是否拖拽
|
||||||
|
drag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 自动上传
|
||||||
|
autoUpload: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 是否为详情
|
||||||
|
isDetail: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 上传携带的参数
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const emit = defineEmits()
|
||||||
|
const number = ref(0)
|
||||||
|
const uploadList = ref([])
|
||||||
|
// const baseUrl = import.meta.env.VITE_APP_BASE_API
|
||||||
|
// const uploadFileUrl = ref(baseUrl + import.meta.env.VITE_APP_UPLOAD_URL) // 上传的图片服务器地址
|
||||||
|
// const headers = ref({ Authorization: 'Bearer ' + getToken() })
|
||||||
|
const fileList = ref([])
|
||||||
|
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
let temp = 1
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(val) ? val : props.modelValue.split(',')
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
fileList.value = list.map((item) => {
|
||||||
|
var fileName = item.slice(item.lastIndexOf('/') + 1)
|
||||||
|
if (typeof item === 'string') {
|
||||||
|
item = { name: fileName, url: item }
|
||||||
|
}
|
||||||
|
item.uid = item.uid || new Date().getTime() + temp++
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
// uploadList.value = fileList
|
||||||
|
} else {
|
||||||
|
fileList.value = []
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
// 上传前校检格式和大小
|
||||||
|
function handleBeforeUpload(file) {
|
||||||
|
// 校检文件类型
|
||||||
|
if (props.fileType.length) {
|
||||||
|
let fileExtension = ''
|
||||||
|
if (file.name.lastIndexOf('.') > -1) {
|
||||||
|
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
||||||
|
}
|
||||||
|
const isTypeOk = props.fileType.some((type) => {
|
||||||
|
if (file.type.indexOf(type) > -1) return true
|
||||||
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if (!isTypeOk) {
|
||||||
|
ElMessage.error(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 校检文件大小
|
||||||
|
if (props.fileSize) {
|
||||||
|
const isLt = file.size / 1024 / 1024 < props.fileSize
|
||||||
|
if (!isLt) {
|
||||||
|
ElMessage.error(`上传文件大小不能超过 ${props.fileSize} MB!`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
number.value++
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件个数超出
|
||||||
|
function handleExceed() {
|
||||||
|
ElMessage.error(`上传文件数量不能超过 ${props.limit} 个!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传失败
|
||||||
|
function handleUploadError(err) {
|
||||||
|
ElMessage.error('上传失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传成功回调
|
||||||
|
function handleUploadSuccess(response, uploadFile) {
|
||||||
|
if (response.code != 0) {
|
||||||
|
fileList.value = []
|
||||||
|
ElMessage.error(`上传失败,原因:${response.msg}!`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { fileName, url, fileId } = response.data
|
||||||
|
const tempFile = { name: fileName, url: url }
|
||||||
|
uploadList.value.push(tempFile)
|
||||||
|
if (uploadList.value.length === number.value) {
|
||||||
|
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value)
|
||||||
|
uploadList.value = []
|
||||||
|
number.value = 0
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
emit('success', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除文件
|
||||||
|
function handleDelete(index) {
|
||||||
|
fileList.value.splice(index, 1)
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件名称
|
||||||
|
function getFileName(name) {
|
||||||
|
if (name.lastIndexOf('/') > -1) {
|
||||||
|
return name.slice(name.lastIndexOf('/') + 1).toLowerCase()
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对象转成指定字符串分隔
|
||||||
|
function listToString(list, separator) {
|
||||||
|
let strs = ''
|
||||||
|
separator = separator || ','
|
||||||
|
for (let i in list) {
|
||||||
|
strs += list[i].url + separator
|
||||||
|
}
|
||||||
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
|
}
|
||||||
|
// 手动提交上传
|
||||||
|
function submitUpload() {
|
||||||
|
proxy.$refs.upload.submit()
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
submitUpload,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.upload-file-uploader {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.upload-file-list .el-upload-list__item {
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
line-height: 2;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.upload-file-list .ele-upload-list__item-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
.ele-upload-list__item-content-action .el-link {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
.doc-icon {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
</style>
|
23
src/components/Icon.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<template v-if="iconType === 'ElIcon'">
|
||||||
|
<el-icon>
|
||||||
|
<component :is="name"></component>
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const { name } = defineProps({
|
||||||
|
name: String
|
||||||
|
});
|
||||||
|
const iconType = ref('');
|
||||||
|
switch (true) {
|
||||||
|
case name.startsWith('ElIcon'):
|
||||||
|
iconType.value = 'ElIcon';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
</script>
|
107
src/components/IconSelect/index.vue
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<div class="icon-body">
|
||||||
|
<el-input v-model="iconName" style="position: relative" clearable placeholder="请输入图标名称" @clear="filterIcons"
|
||||||
|
@input="filterIcons">
|
||||||
|
<template #prefix>
|
||||||
|
<el-icon class="el-input__icon">
|
||||||
|
<search />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<template #suffix>
|
||||||
|
<el-icon class="el-input__icon" @click="selectedIcon('')">
|
||||||
|
<delete />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-tabs v-model="activeName">
|
||||||
|
<el-tab-pane label="svg-icon" name="1">
|
||||||
|
<div class="icon-list">
|
||||||
|
<div class="icon-item mb10" v-for="(item, index) in iconList" :key="index"
|
||||||
|
@click="selectedIcon(item.name, '', item.code)">
|
||||||
|
<svg-icon :name="item.name" style="height: 30px; width: 16px" />
|
||||||
|
<div class="name">{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<!-- <el-tab-pane label="Element-UI Icons" name="2">
|
||||||
|
<div class="icon-list">
|
||||||
|
<div class="icon-item mb10" v-for="item of elementIcons" :key="item" @click="selectedIcon(item, 'ele-')">
|
||||||
|
<svg-icon :name="'ele-' + item" style="height: 30px; width: 16px" />
|
||||||
|
<div class="name">{{ item }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane> -->
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import icons from './requireIcons'
|
||||||
|
import * as elIcons from '@element-plus/icons-vue'
|
||||||
|
import { reactive, ref, watch, defineEmits, defineExpose } from "vue";
|
||||||
|
|
||||||
|
const elementIcons = ref([])
|
||||||
|
for (const key in elIcons) {
|
||||||
|
elementIcons.value.push(key)
|
||||||
|
}
|
||||||
|
const iconName = ref('')
|
||||||
|
const iconList = ref(icons)
|
||||||
|
const activeName = ref('1')
|
||||||
|
const emit = defineEmits(['selected'])
|
||||||
|
|
||||||
|
function filterIcons() {
|
||||||
|
iconList.value = icons
|
||||||
|
if (iconName.value) {
|
||||||
|
iconList.value = icons.filter((item) => item.indexOf(iconName.value) !== -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectedIcon(name, prefix, code) {
|
||||||
|
const iconName = prefix != undefined ? prefix + name : name
|
||||||
|
const iconcode = "&#x" + code + ";"
|
||||||
|
console.log(iconcode)
|
||||||
|
emit('selected', iconName, iconcode)
|
||||||
|
document.body.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
iconName.value = ''
|
||||||
|
iconList.value = icons
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
reset,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.icon-body {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.icon-list {
|
||||||
|
overflow-y: scroll;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
height: 200px;
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
// height: 30px;
|
||||||
|
// line-height: 30px;
|
||||||
|
// margin-bottom: -5px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 19%;
|
||||||
|
text-align: center;
|
||||||
|
// float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
// display: inline-block;
|
||||||
|
// vertical-align: -0.15em;
|
||||||
|
// fill: currentColor;
|
||||||
|
// overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
18
src/components/IconSelect/requireIcons.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
let icons = []
|
||||||
|
const modules = import.meta.glob('~/assets/icons/svg/*.svg')
|
||||||
|
for (const path in modules) {
|
||||||
|
const p = path.split('assets/icons/svg/')[1].split('.svg')[0]
|
||||||
|
icons.push(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// iconfont
|
||||||
|
import iconList from '~/assets/iconfont/iconfont.json'
|
||||||
|
|
||||||
|
iconList.glyphs.forEach((element) => {
|
||||||
|
let item = {
|
||||||
|
name : element.name,
|
||||||
|
code : element.unicode,
|
||||||
|
}
|
||||||
|
icons.push(item)
|
||||||
|
})
|
||||||
|
export default icons
|
241
src/components/ImageUpload.vue
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<template>
|
||||||
|
<div class="component-upload-image">
|
||||||
|
<el-upload multiple :action="imageUpload" list-type="picture-card" :on-success="handleUploadSuccess"
|
||||||
|
:before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed"
|
||||||
|
name="file" :drag="true" :data="data" :disabled="isDisabled" :on-remove="handleRemove"
|
||||||
|
:show-file-list="true" :headers="headers" :file-list="fileList" :on-preview="handlePictureCardPreview"
|
||||||
|
:style="style" :class="{ hide: fileList.length >= limit || isDisabled }">
|
||||||
|
<el-icon class="avatar-uploader-icon">
|
||||||
|
+
|
||||||
|
</el-icon>
|
||||||
|
</el-upload>
|
||||||
|
<!-- 上传提示 -->
|
||||||
|
<div class="el-upload__tip" v-if="showTip">
|
||||||
|
请上传
|
||||||
|
<template v-if="fileSize">
|
||||||
|
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||||
|
</template>
|
||||||
|
<template v-if="fileType">
|
||||||
|
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||||
|
</template>
|
||||||
|
的文件
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" title="预览" width="800px" append-to-body>
|
||||||
|
<template v-if="isImage(dialogImageUrl)">
|
||||||
|
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
|
||||||
|
</template>
|
||||||
|
<template v-else-if="isVideo(dialogImageUrl)">
|
||||||
|
<video :src="dialogImageUrl" controls autoplay
|
||||||
|
style="display: block; max-width: 100%; height: 500px; margin: 0 auto"></video>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, watch, computed } from "vue";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { imageUpload } from "~/service/common";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: [String, Object, Array],
|
||||||
|
// 图片数量限制
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 大小限制(MB)
|
||||||
|
fileSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
|
fileType: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ['png', 'jpg', 'jpeg'],
|
||||||
|
},
|
||||||
|
// 是否显示提示
|
||||||
|
isShowTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 是否禁用
|
||||||
|
isDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 上传携带的参数
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits()
|
||||||
|
const number = ref(0)
|
||||||
|
const uploadList = ref([])
|
||||||
|
const dialogImageUrl = ref('')
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const fileList = ref([])
|
||||||
|
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(val) ? val : props.modelValue.split(',')
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
fileList.value = list.map((item) => {
|
||||||
|
if (typeof item === 'string') {
|
||||||
|
// if (item.indexOf(baseUrl) === -1) {
|
||||||
|
// item = { name: baseUrl + item, url: baseUrl + item }
|
||||||
|
// } else {
|
||||||
|
item = { name: item, url: item }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
fileList.value = []
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
// 删除图片
|
||||||
|
function handleRemove(file, files) {
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传成功回调
|
||||||
|
function handleUploadSuccess(res) {
|
||||||
|
if (res.code != 0) {
|
||||||
|
ElMessage.error(`上传失败,原因:${res.msg}!`);
|
||||||
|
fileList.value = fileList.value.slice(0, fileList.value.length - 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uploadList.value.push({ name: res.data.fileName, url: res.data.url })
|
||||||
|
if (uploadList.value.length === number.value) {
|
||||||
|
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value)
|
||||||
|
uploadList.value = []
|
||||||
|
number.value = 0
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
updateVideoDom()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateVideoDom() {
|
||||||
|
setTimeout(() => {
|
||||||
|
Array.prototype.slice.call(document.getElementsByClassName('is-success'))
|
||||||
|
.filter(item => item.className.indexOf('el-upload-list__item') !== -1)
|
||||||
|
.map(item => {
|
||||||
|
let tag = item.getElementsByClassName('el-upload-list__item-thumbnail')[0];
|
||||||
|
if (isVideo(tag.getAttribute('src'))) {
|
||||||
|
let attr = [tag.getAttribute('class'), tag.getAttribute('src')];
|
||||||
|
let videoTag = document.createElement('video');
|
||||||
|
videoTag.setAttribute('class', attr[0]);
|
||||||
|
videoTag.setAttribute('src', attr[1]);
|
||||||
|
item.replaceChild(videoTag, tag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传前loading加载
|
||||||
|
function handleBeforeUpload(file) {
|
||||||
|
let isImg = false
|
||||||
|
if (props.fileType.length) {
|
||||||
|
let fileExtension = ''
|
||||||
|
if (file.name.lastIndexOf('.') > -1) {
|
||||||
|
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
||||||
|
}
|
||||||
|
isImg = props.fileType.some((type) => {
|
||||||
|
if (file.type.indexOf(type) > -1) return true
|
||||||
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
isImg = file.type.indexOf('image') > -1
|
||||||
|
}
|
||||||
|
if (!isImg) {
|
||||||
|
ElMessage.error(`文件格式不正确, 请上传${props.fileType.join('/')}图片格式文件!`);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (props.fileSize) {
|
||||||
|
const isLt = file.size / 1024 / 1024 < props.fileSize
|
||||||
|
if (!isLt) {
|
||||||
|
ElMessage.error(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
number.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件个数超出
|
||||||
|
function handleExceed() {
|
||||||
|
ElMessage.error(`上传文件数量不能超过 ${props.limit} 个!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传失败
|
||||||
|
function handleUploadError() {
|
||||||
|
ElMessage.error('上传图片失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览
|
||||||
|
function handlePictureCardPreview(file) {
|
||||||
|
dialogImageUrl.value = file.url
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对象转成指定字符串分隔
|
||||||
|
function listToString(list, separator) {
|
||||||
|
let strs = ''
|
||||||
|
separator = separator || ','
|
||||||
|
for (let i in list) {
|
||||||
|
if (undefined !== list[i].url && list[i].url.indexOf('blob:') !== 0) {
|
||||||
|
strs += list[i].url + separator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileExtension = (filename) => {
|
||||||
|
return filename.slice(filename.lastIndexOf('.'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const isImage = (value) => {
|
||||||
|
const imageExtensions = ['.png', '.jpg', '.jpeg'];
|
||||||
|
const extension = getFileExtension(value);
|
||||||
|
return imageExtensions.includes(extension.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
const isVideo = (value) => {
|
||||||
|
const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.mpeg', '.3gp', '.webm', '.vob', '.rm', '.rmvb'];
|
||||||
|
const extension = getFileExtension(value);
|
||||||
|
return videoExtensions.includes(extension.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.hide .el-upload--picture-card) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-dragger) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
248
src/components/Map.vue
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<template>
|
||||||
|
<div class="map-wrapper">
|
||||||
|
<div id="mapcontainer"></div>
|
||||||
|
<div class="search-box">
|
||||||
|
<el-autocomplete v-if="props.isSearch" v-model="location.address" :fetch-suggestions="handleSearch"
|
||||||
|
:trigger-on-focus="false" clearable placeholder="输入城市+关键字搜索" @select="handleSelect"
|
||||||
|
style="width: 300px" />
|
||||||
|
<el-input v-if="props.isShowInput" v-model="location.longitude" placeholder="选择经度" maxlength="15" readonly
|
||||||
|
style="width: 150px; margin: 0 10px 0 20px"></el-input>
|
||||||
|
<el-input v-if="props.isShowInput" v-model="location.latitude" placeholder="选择纬度" maxlength="15" readonly
|
||||||
|
style="width: 150px"></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||||
|
import { ref, watch, shallowRef, onMounted } from 'vue'
|
||||||
|
|
||||||
|
window._AMapSecurityConfig = {
|
||||||
|
securityJsCode: '8841f4d260a9f47378242a05ace584ca'
|
||||||
|
};
|
||||||
|
const props = defineProps({
|
||||||
|
// v-model (经纬度)
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default(v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 是否显示搜索
|
||||||
|
isSearch: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否可以点击
|
||||||
|
isClick: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否展示当前经纬度
|
||||||
|
isShowInput: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
mapCb:{
|
||||||
|
type:Function,
|
||||||
|
default:function(){
|
||||||
|
console.log('is default');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
const map = shallowRef(null);
|
||||||
|
const location = ref(props.modelValue);
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initMap();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(location.value, val => {
|
||||||
|
if (val.longitude && val.latitude) {
|
||||||
|
drawMarker();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const keyword = ref('');
|
||||||
|
let placeSearch, AMapObj, marker, geocoder;
|
||||||
|
function initMap() {
|
||||||
|
AMapLoader.load({
|
||||||
|
key: '582deef9a68a17068f3b7e291807045d', // 申请好的Web端Key,首次调用 load 时必填
|
||||||
|
version: '2.0'
|
||||||
|
}).then(AMap => {
|
||||||
|
props.mapCb()
|
||||||
|
AMapObj = AMap;
|
||||||
|
map.value = new AMap.Map('mapcontainer');
|
||||||
|
// 添加点击事件
|
||||||
|
if (props.isClick) {
|
||||||
|
map.value.on('click', onMapClick);
|
||||||
|
}
|
||||||
|
if (location.value.longitude) {
|
||||||
|
drawMarker();
|
||||||
|
}
|
||||||
|
AMap.plugin(
|
||||||
|
[
|
||||||
|
'AMap.ToolBar',
|
||||||
|
'AMap.Scale',
|
||||||
|
'AMap.Geolocation',
|
||||||
|
'AMap.PlaceSearch',
|
||||||
|
'AMap.Geocoder'
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
// 缩放条
|
||||||
|
const toolbar = new AMap.ToolBar();
|
||||||
|
// 比例尺
|
||||||
|
const scale = new AMap.Scale();
|
||||||
|
// 定位
|
||||||
|
const geolocation = new AMap.Geolocation({
|
||||||
|
enableHighAccuracy: true, //是否使用高精度定位,默认:true
|
||||||
|
timeout: 10000, //超过10秒后停止定位,默认:5s
|
||||||
|
position: 'RT', //定位按钮的停靠位置
|
||||||
|
buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
|
||||||
|
zoomToAccuracy: true //定位成功后是否自动调整地图视野到定位点
|
||||||
|
});
|
||||||
|
geocoder = new AMap.Geocoder({
|
||||||
|
city: '全国'
|
||||||
|
});
|
||||||
|
map.value.addControl(geolocation);
|
||||||
|
map.value.addControl(toolbar);
|
||||||
|
map.value.addControl(scale);
|
||||||
|
placeSearch = new AMap.PlaceSearch({
|
||||||
|
map: map.value,
|
||||||
|
city: '',
|
||||||
|
pageSize: 30, // 单页显示结果条数
|
||||||
|
pageIndex: 1, // 页码
|
||||||
|
citylimit: false, // 是否强制限制在设置的城市内搜索
|
||||||
|
autoFitView: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索地图
|
||||||
|
function handleSearch(queryString, cb) {
|
||||||
|
placeSearch.search(queryString, (status, result) => {
|
||||||
|
if (result && typeof result === 'object' && result.poiList) {
|
||||||
|
const list = result.poiList.pois;
|
||||||
|
list.forEach(item => {
|
||||||
|
item.value = item.name;
|
||||||
|
item.label = item.name;
|
||||||
|
});
|
||||||
|
cb(list);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cb([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 点击地图
|
||||||
|
function onMapClick(e) {
|
||||||
|
const { lng, lat } = e.lnglat;
|
||||||
|
// 逆地理编码
|
||||||
|
geocoder.getAddress([lng, lat], (status, result) => {
|
||||||
|
if (status === 'complete' && result.info === 'OK') {
|
||||||
|
const { addressComponent, formattedAddress } = result.regeocode;
|
||||||
|
let { city, province, district } = addressComponent;
|
||||||
|
if (!city) {
|
||||||
|
// 直辖市
|
||||||
|
city = province;
|
||||||
|
}
|
||||||
|
// location.value = {
|
||||||
|
// longitude: lng,
|
||||||
|
// latitude: lat,
|
||||||
|
// address: formattedAddress,
|
||||||
|
// zone: [province, city, district],
|
||||||
|
// };
|
||||||
|
|
||||||
|
location.value.longitude = lng;
|
||||||
|
location.value.latitude = lat;
|
||||||
|
location.value.address = formattedAddress;
|
||||||
|
location.value.zone = [province, city, district];
|
||||||
|
|
||||||
|
// console.log(location.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 点击搜索项
|
||||||
|
function handleSelect(item) {
|
||||||
|
// const { pname, cityname, adname, address, name } = item;
|
||||||
|
const { lng, lat } = item.location;
|
||||||
|
// 逆地理编码
|
||||||
|
geocoder.getAddress([lng, lat], (status, result) => {
|
||||||
|
if (status === 'complete' && result.info === 'OK') {
|
||||||
|
const { addressComponent, formattedAddress } = result.regeocode;
|
||||||
|
let { city, province, district } = addressComponent;
|
||||||
|
if (!city) {
|
||||||
|
// 直辖市
|
||||||
|
city = province;
|
||||||
|
}
|
||||||
|
// location.value = {
|
||||||
|
// longitude: lng,
|
||||||
|
// latitude: lat,
|
||||||
|
// address: formattedAddress,
|
||||||
|
// zone: [province, city, district],
|
||||||
|
// };
|
||||||
|
|
||||||
|
location.value.longitude = lng;
|
||||||
|
location.value.latitude = lat;
|
||||||
|
location.value.address = formattedAddress;
|
||||||
|
location.value.zone = [province, city, district];
|
||||||
|
|
||||||
|
// console.log(location.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// location.value = {
|
||||||
|
// longitude: lng,
|
||||||
|
// latitude: lat,
|
||||||
|
// address,
|
||||||
|
// zone: [pname, cityname, adname],
|
||||||
|
// name
|
||||||
|
// };
|
||||||
|
// location.value.longitude = lng;
|
||||||
|
// location.value.latitude = lat;
|
||||||
|
// location.value.address = address;
|
||||||
|
// location.value.name = name;
|
||||||
|
// location.value.zone = [pname, cityname, adname];
|
||||||
|
map.value.setZoomAndCenter(16, [lng, lat]);
|
||||||
|
}
|
||||||
|
// 绘制地点marker
|
||||||
|
function drawMarker(val) {
|
||||||
|
const { longitude, latitude } = location.value || val;
|
||||||
|
if (marker) {
|
||||||
|
marker.setMap(null);
|
||||||
|
}
|
||||||
|
marker = new AMapObj.Marker({
|
||||||
|
position: new AMapObj.LngLat(longitude, latitude),
|
||||||
|
anchor: 'bottom-center'
|
||||||
|
});
|
||||||
|
map.value.add(marker);
|
||||||
|
map.value.setZoomAndCenter(16, [longitude, latitude]);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.map-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
#mapcontainer {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
112
src/components/Pagination.vue
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="{ hidden: hidden }" class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
large
|
||||||
|
background
|
||||||
|
v-model:current-page="currentPage"
|
||||||
|
v-model:page-size="pageSize"
|
||||||
|
:layout="layout"
|
||||||
|
:page-sizes="pageSizes"
|
||||||
|
:pager-count="pagerCount"
|
||||||
|
:total="total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import { scrollTo } from "@/utils/scroll-to";
|
||||||
|
import { computed } from 'vue'
|
||||||
|
export default {
|
||||||
|
name: 'pagingation',
|
||||||
|
emits: ['update:page', 'update:limit', 'pagination'],
|
||||||
|
props: {
|
||||||
|
total: {
|
||||||
|
required: true,
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 20,
|
||||||
|
},
|
||||||
|
pageSizes: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [10, 20, 30, 50, 100]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 移动端页码按钮的数量端默认值5
|
||||||
|
pagerCount: {
|
||||||
|
type: Number,
|
||||||
|
default: document.body.clientWidth < 992 ? 5 : 7,
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
type: String,
|
||||||
|
default: 'total, sizes, prev, pager, next, jumper',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
autoScroll: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
hidden: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { ctx, emit }) {
|
||||||
|
const currentPage = computed({
|
||||||
|
get() {
|
||||||
|
return props.page
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
emit('update:page', val)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const pageSize = computed({
|
||||||
|
get() {
|
||||||
|
return props.limit
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
emit('update:limit', val)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleSizeChange(val) {
|
||||||
|
emit('pagination', { page: currentPage.value, limit: val })
|
||||||
|
if (props.autoScroll) {
|
||||||
|
// scrollTo(0, 800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleCurrentChange(val) {
|
||||||
|
emit('pagination', { page: val, limit: pageSize.value })
|
||||||
|
if (props.autoScroll) {
|
||||||
|
// scrollTo(0, 800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentPage,
|
||||||
|
pageSize,
|
||||||
|
handleSizeChange,
|
||||||
|
handleCurrentChange,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.pagination-container {
|
||||||
|
/* background: #fff; */
|
||||||
|
padding: 32px 16px;
|
||||||
|
}
|
||||||
|
.pagination-container.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
141
src/components/RichText.vue
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<div style="border: 1px solid #ccc;width: 100%;z-index: 999;" >
|
||||||
|
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
|
||||||
|
<Editor style="height: 500px; overflow-y: hidden" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode"
|
||||||
|
@onCreated="handleCreated" @onChange="handleChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import '@wangeditor/editor/dist/css/style.css' // 引入 css
|
||||||
|
import { onBeforeUnmount, ref, shallowRef,watch } from 'vue'
|
||||||
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Editor, Toolbar },
|
||||||
|
props: {
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: () => '请输入内容',
|
||||||
|
},
|
||||||
|
modelValue: String,
|
||||||
|
editorConfig: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const editorRef = shallowRef()
|
||||||
|
const valueHtml = ref(props.modelValue)
|
||||||
|
const toolbarConfig = {}
|
||||||
|
const editorConfig = {
|
||||||
|
MENU_CONF: {},
|
||||||
|
placeholder: props.placeholder,
|
||||||
|
...props.editorConfig
|
||||||
|
}
|
||||||
|
//上传图片
|
||||||
|
editorConfig.MENU_CONF['uploadImage'] = {
|
||||||
|
server: import.meta.env.VITE_RICHTEXT_GATEWAY + '/common/uploadImg',
|
||||||
|
// form-data fieldName ,默认值 'wangeditor-uploaded-image'
|
||||||
|
fieldName: 'file',
|
||||||
|
// 单个文件的最大体积限制,默认为 2M
|
||||||
|
maxFileSize: 5 * 1024 * 1024, // 5M
|
||||||
|
// 最多可上传几个文件,默认为 100
|
||||||
|
maxNumberOfFiles: 10,
|
||||||
|
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
|
||||||
|
allowedFileTypes: ['image/*'],
|
||||||
|
// 将 meta 拼接到 url 参数中,默认 false
|
||||||
|
metaWithUrl: false,
|
||||||
|
// 自定义增加 http header
|
||||||
|
headers: {
|
||||||
|
token: headers.token // 设置请求头
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
dirName: "RichText"
|
||||||
|
},
|
||||||
|
// 跨域是否传递 cookie ,默认为 false
|
||||||
|
withCredentials: true,
|
||||||
|
// 超时时间,默认为 10 秒
|
||||||
|
timeout: 5 * 1000, // 5 秒
|
||||||
|
// 自定义插入图片
|
||||||
|
customInsert(res, insertFn) {
|
||||||
|
; -(
|
||||||
|
// 从 res 中找到 url alt href ,然后插图图片
|
||||||
|
insertFn(res.data.url)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
//上传视频
|
||||||
|
editorConfig.MENU_CONF['uploadVideo'] = {
|
||||||
|
server: import.meta.env.VITE_PROXY_RICHTEXT + '/common/uploadFile',
|
||||||
|
// form-data fieldName ,默认值 'wangeditor-uploaded-video'
|
||||||
|
fieldName: 'file',
|
||||||
|
|
||||||
|
// 单个文件的最大体积限制,默认为 10M
|
||||||
|
maxFileSize: 100 * 1024 * 1024, // 5M
|
||||||
|
|
||||||
|
// 最多可上传几个文件,默认为 5
|
||||||
|
maxNumberOfFiles: 3,
|
||||||
|
|
||||||
|
// 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []
|
||||||
|
allowedFileTypes: ['video/*'],
|
||||||
|
|
||||||
|
// 将 meta 拼接到 url 参数中,默认 false
|
||||||
|
metaWithUrl: false,
|
||||||
|
|
||||||
|
// 自定义增加 http header
|
||||||
|
headers: {
|
||||||
|
token: headers.token // 设置请求头
|
||||||
|
},
|
||||||
|
|
||||||
|
// 跨域是否传递 cookie ,默认为 false
|
||||||
|
withCredentials: true,
|
||||||
|
// 超时时间,默认为 30 秒
|
||||||
|
timeout: 15 * 1000, // 15 秒
|
||||||
|
// 自定义插入视频
|
||||||
|
customInsert(res, insertFn) {
|
||||||
|
; -(
|
||||||
|
// 从 res 中找到 url alt href ,然后插图图片
|
||||||
|
insertFn(res.data.url)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value
|
||||||
|
if (editor == null) return
|
||||||
|
editor.destroy()
|
||||||
|
})
|
||||||
|
const handleCreated = (editor) => {
|
||||||
|
editorRef.value = editor
|
||||||
|
}
|
||||||
|
const handleChange = (editor) => {
|
||||||
|
emit('update:modelValue', editor.getHtml())
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(value) => {
|
||||||
|
const editor = editorRef.value
|
||||||
|
if (value == undefined) {
|
||||||
|
editor.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
valueHtml.value = value;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
editorRef,
|
||||||
|
valueHtml,
|
||||||
|
mode: 'default',
|
||||||
|
toolbarConfig,
|
||||||
|
editorConfig,
|
||||||
|
handleCreated,
|
||||||
|
handleChange,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
62
src/components/SvgIcon/index.vue
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<script>
|
||||||
|
import { h, resolveComponent,defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
// svg 图标组件名字
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
// svg 颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
if (props.name?.startsWith('ele')) {
|
||||||
|
return () =>
|
||||||
|
h(
|
||||||
|
'i',
|
||||||
|
{
|
||||||
|
class: 'el-icon',
|
||||||
|
},
|
||||||
|
[h(resolveComponent(props.name.replace('ele-', '')))],
|
||||||
|
)
|
||||||
|
} else if (props.name != undefined && props.name != '') {
|
||||||
|
return () =>
|
||||||
|
h(
|
||||||
|
'svg',
|
||||||
|
{
|
||||||
|
name: props.name,
|
||||||
|
'aria-hidden': true,
|
||||||
|
style: `color: ${props.color}`,
|
||||||
|
class: `svg-icon ${props.className}`,
|
||||||
|
},
|
||||||
|
h('use', {
|
||||||
|
'xlink:href': `#icon-${props.name}`,
|
||||||
|
fill: `${props.color}`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return () => h('i')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scope lang="scss">
|
||||||
|
.svg-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
fill: currentColor;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
10
src/components/SvgIcon/svgicon.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import * as components from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install: (app) => {
|
||||||
|
for (const key in components) {
|
||||||
|
const componentConfig = components[key];
|
||||||
|
app.component(componentConfig.name, componentConfig);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
244
src/components/UploadVideo.vue
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<template>
|
||||||
|
<div class="component-upload-image">
|
||||||
|
<el-upload multiple :action="videoUpload" list-type="picture-card" :on-success="handleUploadSuccess"
|
||||||
|
:before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed"
|
||||||
|
name="file" :drag="true" :data="data" :disabled="isDisabled" :on-remove="handleRemove" :show-file-list="true"
|
||||||
|
:headers="headers" :file-list="fileList" :on-preview="handlePictureCardPreview" :style="style"
|
||||||
|
:class="{ hide: fileList.length >= limit || isDisabled }">
|
||||||
|
<el-icon class="avatar-uploader-icon">
|
||||||
|
+
|
||||||
|
</el-icon>
|
||||||
|
</el-upload>
|
||||||
|
<!-- 上传提示 -->
|
||||||
|
<div class="el-upload__tip" v-if="showTip">
|
||||||
|
请上传
|
||||||
|
<template v-if="fileSize">
|
||||||
|
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||||
|
</template>
|
||||||
|
<template v-if="fileType">
|
||||||
|
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
|
||||||
|
</template>
|
||||||
|
的文件
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" title="预览" width="800px" append-to-body>
|
||||||
|
<template v-if="isImage(dialogImageUrl)">
|
||||||
|
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
|
||||||
|
</template>
|
||||||
|
<template v-else-if="isVideo(dialogImageUrl)">
|
||||||
|
<video :src="dialogImageUrl" controls autoplay
|
||||||
|
style="display: block; max-width: 100%; height: 500px; margin: 0 auto"></video>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, watch, computed } from "vue";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { imageUpload } from "~/service/common";
|
||||||
|
import { videoUpload } from "~/service/common";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: [String, Object, Array],
|
||||||
|
// 图片数量限制
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 大小限制(MB)
|
||||||
|
fileSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||||
|
fileType: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ['png', 'jpg', 'jpeg'],
|
||||||
|
},
|
||||||
|
// 是否显示提示
|
||||||
|
isShowTip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
// 是否禁用
|
||||||
|
isDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// 上传携带的参数
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits()
|
||||||
|
const number = ref(0)
|
||||||
|
const uploadList = ref([])
|
||||||
|
const dialogImageUrl = ref('')
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const fileList = ref([])
|
||||||
|
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(val) ? val : props.modelValue.split(',')
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
fileList.value = list.map((item) => {
|
||||||
|
if (typeof item === 'string') {
|
||||||
|
// if (item.indexOf(baseUrl) === -1) {
|
||||||
|
// item = { name: baseUrl + item, url: baseUrl + item }
|
||||||
|
// } else {
|
||||||
|
item = { name: item, url: item }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
fileList.value = []
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
updateVideoDom()
|
||||||
|
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
// 删除图片
|
||||||
|
function handleRemove(file, files) {
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传成功回调
|
||||||
|
function handleUploadSuccess(res) {
|
||||||
|
if (res.code != 0) {
|
||||||
|
ElMessage.error(`上传失败,原因:${res.msg}!`);
|
||||||
|
fileList.value = fileList.value.slice(0, fileList.value.length - 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uploadList.value.push({ name: res.data.fileName, url: res.data.url })
|
||||||
|
if (uploadList.value.length === number.value) {
|
||||||
|
fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value)
|
||||||
|
uploadList.value = []
|
||||||
|
number.value = 0
|
||||||
|
emit('update:modelValue', listToString(fileList.value))
|
||||||
|
}
|
||||||
|
updateVideoDom()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateVideoDom() {
|
||||||
|
setTimeout(() => {
|
||||||
|
Array.prototype.slice.call(document.getElementsByClassName('is-success'))
|
||||||
|
.filter(item => item.className.indexOf('el-upload-list__item') !== -1)
|
||||||
|
.map(item => {
|
||||||
|
let tag = item.getElementsByClassName('el-upload-list__item-thumbnail')[0];
|
||||||
|
if (isVideo(tag.getAttribute('src'))) {
|
||||||
|
let attr = [tag.getAttribute('class'), tag.getAttribute('src')];
|
||||||
|
let videoTag = document.createElement('video');
|
||||||
|
videoTag.setAttribute('class', attr[0]);
|
||||||
|
videoTag.setAttribute('src', attr[1]);
|
||||||
|
item.replaceChild(videoTag, tag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传前loading加载
|
||||||
|
function handleBeforeUpload(file) {
|
||||||
|
let isImg = false
|
||||||
|
if (props.fileType.length) {
|
||||||
|
let fileExtension = ''
|
||||||
|
if (file.name.lastIndexOf('.') > -1) {
|
||||||
|
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
||||||
|
}
|
||||||
|
isImg = props.fileType.some((type) => {
|
||||||
|
if (file.type.indexOf(type) > -1) return true
|
||||||
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
isImg = file.type.indexOf('image') > -1
|
||||||
|
}
|
||||||
|
if (!isImg) {
|
||||||
|
ElMessage.error(`文件格式不正确, 请上传${props.fileType.join('/')}图片格式文件!`);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (props.fileSize) {
|
||||||
|
const isLt = file.size / 1024 / 1024 < props.fileSize
|
||||||
|
if (!isLt) {
|
||||||
|
ElMessage.error(`上传头像图片大小不能超过 ${props.fileSize} MB!`);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
number.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件个数超出
|
||||||
|
function handleExceed() {
|
||||||
|
ElMessage.error(`上传文件数量不能超过 ${props.limit} 个!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传失败
|
||||||
|
function handleUploadError() {
|
||||||
|
ElMessage.error('上传图片失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览
|
||||||
|
function handlePictureCardPreview(file) {
|
||||||
|
dialogImageUrl.value = file.url
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对象转成指定字符串分隔
|
||||||
|
function listToString(list, separator) {
|
||||||
|
let strs = ''
|
||||||
|
separator = separator || ','
|
||||||
|
for (let i in list) {
|
||||||
|
if (undefined !== list[i].url && list[i].url.indexOf('blob:') !== 0) {
|
||||||
|
strs += list[i].url + separator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileExtension = (filename) => {
|
||||||
|
return filename.slice(filename.lastIndexOf('.'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const isImage = (value) => {
|
||||||
|
const imageExtensions = ['.png', '.jpg', '.jpeg'];
|
||||||
|
const extension = getFileExtension(value);
|
||||||
|
return imageExtensions.includes(extension.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
const isVideo = (value) => {
|
||||||
|
const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.mpeg', '.3gp', '.webm', '.vob', '.rm', '.rmvb'];
|
||||||
|
const extension = getFileExtension(value);
|
||||||
|
return videoExtensions.includes(extension.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
:deep(.hide .el-upload--picture-card) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-dragger) {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
203
src/components/UploadVideo1.vue
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<el-upload v-model="props.modelValue"
|
||||||
|
multiple
|
||||||
|
:action="videoUpload"
|
||||||
|
:file-list="uploadVideoArr"
|
||||||
|
:data="props.data"
|
||||||
|
:fileSize="props.fileSize"
|
||||||
|
:headers="headers"
|
||||||
|
@success="handle"
|
||||||
|
@error="handle"
|
||||||
|
@exceed="handleExceed"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:drag="true"
|
||||||
|
@preview="handleVideoPreview"
|
||||||
|
@remove="handleDelete"
|
||||||
|
list-type="picture-card"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="previewVideoMask" v-if="previewIsShow" @click.stop="changPreview">
|
||||||
|
<video :src="previewViewSrc" class="previewVideo" controls></video>
|
||||||
|
</div>
|
||||||
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
|
<div slot="tip" class="el-upload__tip">只能上传视频格式文件(注:需等待全部上传成功再提交)</div>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
import {ref, watch} from "vue";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { videoUpload } from "~/service/common";
|
||||||
|
|
||||||
|
let uploadIdx = ref(0)
|
||||||
|
let previewIsShow = ref(false)
|
||||||
|
let previewViewSrc = ref('')
|
||||||
|
let uploadVideoArr = ref([])
|
||||||
|
let uploadList = ref([])
|
||||||
|
let number = ref(0)
|
||||||
|
|
||||||
|
const emit = defineEmits()
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue : String,
|
||||||
|
data:Object,
|
||||||
|
fileType: {
|
||||||
|
type: Array,
|
||||||
|
default: () => ['mov', 'mp4', 'wmv', 'flv', 'avi','avchd','webm'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const changPreview = function (){
|
||||||
|
previewIsShow.value = !previewIsShow.value
|
||||||
|
}
|
||||||
|
const handleExceed = function (arg){
|
||||||
|
console.log(arg)
|
||||||
|
}
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
let temp = 1
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(val) ? val : props.modelValue.split(',')
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
uploadVideoArr.value = list.map((item) => {
|
||||||
|
if (typeof item === 'string') {
|
||||||
|
item = { url: item }
|
||||||
|
}
|
||||||
|
item.uid = item.uid || new Date().getTime() + temp++
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
// uploadList.value = fileList
|
||||||
|
} else {
|
||||||
|
uploadVideoArr.value = []
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
updateVideoDom()
|
||||||
|
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// 对象转成指定字符串分隔
|
||||||
|
function listToString(list, separator) {
|
||||||
|
let strs = ''
|
||||||
|
separator = separator || ','
|
||||||
|
for (let i in list) {
|
||||||
|
strs += list[i].url + separator
|
||||||
|
}
|
||||||
|
return strs != '' ? strs.substr(0, strs.length - 1) : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handle=function (res){
|
||||||
|
if(res['code'] !== 0){
|
||||||
|
uploadVideoArr.value = []
|
||||||
|
ElMessage.error(res.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { url, } = res?.data
|
||||||
|
const tempFile = { url: url }
|
||||||
|
uploadList.value.push(tempFile)
|
||||||
|
if (uploadList.value.length === number.value) {
|
||||||
|
uploadVideoArr.value.map(item=>{
|
||||||
|
if(item?.response){
|
||||||
|
item.url = item.response.data.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
emit('update:modelValue', listToString(uploadVideoArr.value))
|
||||||
|
emit('success', listToString(uploadVideoArr.value))
|
||||||
|
// console.log(uploadVideoArr.value,'is local')
|
||||||
|
// console.log(props.modelValue,'is props')
|
||||||
|
uploadList.value = []
|
||||||
|
number.value = 0
|
||||||
|
console.log(uploadVideoArr.value,123)
|
||||||
|
ElMessage.success('全部上传成功')
|
||||||
|
|
||||||
|
}
|
||||||
|
updateVideoDom()
|
||||||
|
}
|
||||||
|
function updateVideoDom(){
|
||||||
|
setTimeout(()=>{
|
||||||
|
Array.prototype.slice.call(document.getElementsByClassName('is-success')).filter(item=>item.className.indexOf('el-upload-list__item')!==-1).map((item,idx)=>{
|
||||||
|
let tag = item.getElementsByClassName('el-upload-list__item-thumbnail')[0]
|
||||||
|
let attr = [tag.getAttribute('class'),tag.getAttribute('src')]
|
||||||
|
let videoTag = document.createElement('video')
|
||||||
|
videoTag.setAttribute('class',attr[0])
|
||||||
|
videoTag.setAttribute('src',attr[1])
|
||||||
|
item.replaceChild(videoTag,tag)
|
||||||
|
})
|
||||||
|
|
||||||
|
},)
|
||||||
|
}
|
||||||
|
|
||||||
|
const beforeUpload = function (file){
|
||||||
|
// 校检文件类型
|
||||||
|
if (props.fileType.length) {
|
||||||
|
let fileExtension = ''
|
||||||
|
if (file.name.lastIndexOf('.') > -1) {
|
||||||
|
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
|
||||||
|
}
|
||||||
|
const isTypeOk = props.fileType.some((type) => {
|
||||||
|
if (file.type.indexOf(type) > -1) return true
|
||||||
|
if (fileExtension && fileExtension.indexOf(type) > -1) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if (!isTypeOk) {
|
||||||
|
ElMessage.error(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
number.value+=1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handleDelete=function (f,fl){
|
||||||
|
let index
|
||||||
|
console.log(f,props.modelValue.split(','))
|
||||||
|
props.modelValue.split(',').map((item,idx)=>{
|
||||||
|
if(item===f.url){
|
||||||
|
index = idx
|
||||||
|
}
|
||||||
|
})
|
||||||
|
uploadVideoArr.value.splice(index, 1)
|
||||||
|
emit('update:modelValue', listToString(uploadVideoArr.value))
|
||||||
|
}
|
||||||
|
const handleVideoPreview = function (f){
|
||||||
|
|
||||||
|
changPreview()
|
||||||
|
previewViewSrc.value = f.url
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.previewVideoMask{
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
background: rgba(0,10,10,0.5);
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
.previewVideo{
|
||||||
|
height: 80%;
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-dragger) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
5
src/components/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import DataTable from './DataTable';
|
||||||
|
import DialogForm from './DialogForm';
|
||||||
|
import Icon from './Icon.vue';
|
||||||
|
|
||||||
|
export { DataTable, DialogForm, Icon };
|
93
src/guardian.ts
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import NProgress from 'nprogress';
|
||||||
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
|
import './styles/nprogress/index.css';
|
||||||
|
|
||||||
|
import router from './router';
|
||||||
|
import { useLoginStore, useMenuStore } from '~/store';
|
||||||
|
import { ElMessageBox } from 'element-plus';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否登陆
|
||||||
|
*/
|
||||||
|
const checkLogin = async () => {
|
||||||
|
const login = useLoginStore();
|
||||||
|
const token = login.token;
|
||||||
|
try {
|
||||||
|
if (!token) {
|
||||||
|
throw new Error('请登陆');
|
||||||
|
}
|
||||||
|
const check = !(await login.checkLoginIsExp())
|
||||||
|
if (!check) {
|
||||||
|
throw new Error("登录超时");
|
||||||
|
}
|
||||||
|
return check;
|
||||||
|
} catch (error) {
|
||||||
|
login.logout();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 检查路由
|
||||||
|
*/
|
||||||
|
const checkRouter = (path: string) => {
|
||||||
|
const menu = useMenuStore()
|
||||||
|
const validate = menu.routers.includes(path);
|
||||||
|
if (!validate) {
|
||||||
|
// 开发环境
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
ElMessageBox.alert(
|
||||||
|
`[ ${path} ] 路由未添加到菜单中 请添加后访问`,
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '去添加',
|
||||||
|
showClose: false
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
router.push('/system/menu');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
router.push('/exception/403');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由守护
|
||||||
|
*/
|
||||||
|
export function guardian() {
|
||||||
|
router.beforeEach(async ({ path, meta }) => {
|
||||||
|
const {
|
||||||
|
// 路由检查
|
||||||
|
ignoreRouterCheck = false,
|
||||||
|
// 登陆检查
|
||||||
|
ignoreLoginCheck = false
|
||||||
|
} = meta;
|
||||||
|
// 登录验证
|
||||||
|
if (!ignoreLoginCheck) {
|
||||||
|
await checkLogin()
|
||||||
|
}
|
||||||
|
// 路由检查
|
||||||
|
if (!ignoreRouterCheck) {
|
||||||
|
const check = checkRouter(path);
|
||||||
|
if (!check) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶部进度条
|
||||||
|
*/
|
||||||
|
export function topProgressBar() {
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
NProgress.start();
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
router.afterEach(() => {
|
||||||
|
NProgress.done();
|
||||||
|
});
|
||||||
|
}
|
218
src/layout/Index.vue
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
<template>
|
||||||
|
<el-container id="AppContainer">
|
||||||
|
<el-aside width="200px">
|
||||||
|
<router-link to="/">
|
||||||
|
<div id="logo">
|
||||||
|
<!-- 头部Logo替换 -->
|
||||||
|
<img src="/logo.png" style="margin-top: 5px;margin-left: 5px;" alt="" />
|
||||||
|
<!-- <span>PHP模板</span> -->
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
<AsideMenu :collapse="collapse" />
|
||||||
|
</el-aside>
|
||||||
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<!-- <span @click="collapse = !collapse">
|
||||||
|
<el-icon>
|
||||||
|
<expand v-show="collapse" />
|
||||||
|
<fold v-show="!collapse" />
|
||||||
|
</el-icon>
|
||||||
|
</span> -->
|
||||||
|
<div class="header_right_title">
|
||||||
|
<span>后 台 管 理 系 统</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<el-dropdown>
|
||||||
|
<!-- <el-avatar :size="50" :src="circleUrl" /> -->
|
||||||
|
<span style="color:black">
|
||||||
|
欢迎您,
|
||||||
|
<span style="color: red">{{ useInfo.user_name }}</span>!
|
||||||
|
<Icon name="ElIconArrowDown" class="el-icon--right" />
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="logout">登出</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-card class="box-card main-card">
|
||||||
|
<slot name="default"></slot>
|
||||||
|
</el-card>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { useIntervalFn } from "@vueuse/core";
|
||||||
|
import AsideMenu from "./components/AsideMenu.vue";
|
||||||
|
import useUserStore from "~/store/user";
|
||||||
|
import useLoginStore from "~/store/login";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const login = useLoginStore();
|
||||||
|
const user = useUserStore();
|
||||||
|
|
||||||
|
user.getUserInfo();
|
||||||
|
user.getUserMenu();
|
||||||
|
|
||||||
|
const useInfo = computed(() => user.user);
|
||||||
|
const collapse = ref(false);
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
user.userLogout();
|
||||||
|
};
|
||||||
|
|
||||||
|
useIntervalFn(async () => {
|
||||||
|
if (await login.checkLoginIsExp()) {
|
||||||
|
ElNotification({
|
||||||
|
title: "提示",
|
||||||
|
message: "检测到当前登录状态已超时,请重新登录",
|
||||||
|
type: "warning",
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
login.logout();
|
||||||
|
}
|
||||||
|
}, 1000 * 30);
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#AppContainer {
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addButton {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-breadcrumb {
|
||||||
|
position: fixed;
|
||||||
|
top: 70px;
|
||||||
|
z-index: 99;
|
||||||
|
line-height: 35px !important;
|
||||||
|
background-color: white;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main {
|
||||||
|
padding: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-card {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-card__body {
|
||||||
|
padding-top: 50px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-aside {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑动条 */
|
||||||
|
/* 定义滚动条样式 */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 5px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
|
background: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #cdcdcd;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f6f6f6;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo span {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header_m_box {
|
||||||
|
display: flex;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #85a5c2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_m_content_box {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
/* 头部 */
|
||||||
|
|
||||||
|
.el-aside {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// justify-content: space-around;
|
||||||
|
height: 70px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #FFFFFF; // 头部logo背景色
|
||||||
|
box-shadow: 0px 0px 5px 0px #f1f1f1;
|
||||||
|
// background-color: #2b333e; //默认
|
||||||
|
cursor: pointer;
|
||||||
|
color: white;
|
||||||
|
z-index: 99;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_right_title>span {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-header {
|
||||||
|
font-size: 16px !important;
|
||||||
|
display: flex;
|
||||||
|
box-shadow: 10px 5px 20px 0px #f1f1f1;
|
||||||
|
// border-bottom: rgba(0, 0, 0, 0.1) 1px solid;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
.el-dropdown,
|
||||||
|
.el-dropdown-menu__item {
|
||||||
|
font-size: 16px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
44
src/layout/components/AsideMenu.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<el-menu
|
||||||
|
style="background-color: #2b333e"
|
||||||
|
router
|
||||||
|
:default-openeds="menu.openMenu"
|
||||||
|
@open="v => menu.setOpenMenu(v)"
|
||||||
|
@close="v => menu.setOpenMenu(v)"
|
||||||
|
:collapse="collapse"
|
||||||
|
:unique-opened="true"
|
||||||
|
>
|
||||||
|
<div style="width: 200px; height: 70px"></div>
|
||||||
|
<Menu :menu="menu.menu"></Menu>
|
||||||
|
</el-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
onBeforeMount,
|
||||||
|
reactive,
|
||||||
|
computed,
|
||||||
|
watch,
|
||||||
|
toRefs,
|
||||||
|
unref,
|
||||||
|
nextTick
|
||||||
|
} from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import useMenuStore from '~/store/menu';
|
||||||
|
import Menu from './Menu.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
collapse: Boolean
|
||||||
|
});
|
||||||
|
const menu = useMenuStore();
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.el-menu {
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
83
src/layout/components/Menu.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<template v-for="item in props.menu" :key="item.key">
|
||||||
|
<template v-if="isShow(item)">
|
||||||
|
<!-- 一级菜单 -->
|
||||||
|
<el-menu-item :index="item.url" v-if="!hasChildren(item)">
|
||||||
|
<template #title>
|
||||||
|
<template v-if="props.showIcon && item.icon">
|
||||||
|
<el-icon style="color: white">
|
||||||
|
<component :is="item.icon"></component>
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<span style="color: white">{{ item.name }}</span>
|
||||||
|
</template>
|
||||||
|
</el-menu-item>
|
||||||
|
<!-- 二级菜单 -->
|
||||||
|
<el-sub-menu :index="item.url" v-else>
|
||||||
|
<template #title>
|
||||||
|
<template v-if="item.icon">
|
||||||
|
<el-icon style="color: white">
|
||||||
|
<component :is="item.icon"></component>
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<span style="color: white">{{ item.name }}</span>
|
||||||
|
</template>
|
||||||
|
<Menu :menu="item.children" :showIcon="false"></Menu>
|
||||||
|
</el-sub-menu>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
menu: Object,
|
||||||
|
showIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasChildren = ({ children }) => {
|
||||||
|
return Array.isArray(children) && children.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isShow = ({ show }) => {
|
||||||
|
return show === 1;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 菜单栏背景 */
|
||||||
|
.el-menu-item {
|
||||||
|
background-color: #2b333e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 二级菜单栏背景 */
|
||||||
|
.el-sub-menu {
|
||||||
|
background-color: #2b333e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 一级菜单移入移出 */
|
||||||
|
.el-menu-item:hover {
|
||||||
|
background-color: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 二级菜单移入移出 */
|
||||||
|
.el-sub-menu:hover {
|
||||||
|
background-color: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 二级菜单2移入移出 */
|
||||||
|
.el-sub-menu__title:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选中背景颜色 */
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
background-color: #A72027 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 二级菜单开展箭头图标 */
|
||||||
|
.el-sub-menu__icon-arrow>svg {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
62
src/main.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import { createPinia } from 'pinia';
|
||||||
|
import piniaPersist from 'pinia-plugin-persist';
|
||||||
|
import App from './App.vue';
|
||||||
|
import DataTable from '~/components/DataTable';
|
||||||
|
import DialogForm from '~/components/DialogForm';
|
||||||
|
import Icon from '~/components/Icon.vue';
|
||||||
|
import * as ElIcons from '@element-plus/icons-vue';
|
||||||
|
import DictTag from '~/components/DictTag.vue'
|
||||||
|
import Pagination from '~/components/Pagination.vue'
|
||||||
|
|
||||||
|
// import ElementPlus from "element-plus";
|
||||||
|
// import "element-plus/theme-chalk/src/common/var.scss";
|
||||||
|
|
||||||
|
// svg图标
|
||||||
|
import '~/assets/iconfont/iconfont.js' //iconfont
|
||||||
|
import SvgIcon from '~/components/SvgIcon/index.vue'
|
||||||
|
import elementIcons from '~/components/SvgIcon/svgicon'
|
||||||
|
|
||||||
|
import router from './router';
|
||||||
|
import RichText from '~/components/RichText.vue';
|
||||||
|
import Map from '~/components/Map.vue';
|
||||||
|
import ImageUpload from '~/components/ImageUpload.vue';
|
||||||
|
import FileUpload from '~/components/FileUpload.vue';
|
||||||
|
import UploadVideo from '~/components/UploadVideo.vue';
|
||||||
|
import { guardian, topProgressBar } from './guardian';
|
||||||
|
|
||||||
|
async function bootstrap(): Promise<void> {
|
||||||
|
const app = createApp(App);
|
||||||
|
|
||||||
|
const pinia = createPinia();
|
||||||
|
pinia.use(piniaPersist);
|
||||||
|
|
||||||
|
app.use(router);
|
||||||
|
app.use(pinia);
|
||||||
|
|
||||||
|
app.component('Pagination', Pagination);
|
||||||
|
app.component('DictTag', DictTag);
|
||||||
|
app.component('DataTable', DataTable);
|
||||||
|
app.component('DialogForm', DialogForm);
|
||||||
|
app.component('Icon', Icon);
|
||||||
|
app.component('RichText', RichText);
|
||||||
|
app.component('Map', Map);
|
||||||
|
app.component('UploadImage', ImageUpload);
|
||||||
|
app.component('UploadFile', FileUpload);
|
||||||
|
app.component('UploadVideo', UploadVideo);
|
||||||
|
app.component('svg-icon', SvgIcon)
|
||||||
|
|
||||||
|
Object.keys(ElIcons).forEach((icon: string) => {
|
||||||
|
app.component(`ElIcon${icon}`, ElIcons[icon]);
|
||||||
|
});
|
||||||
|
|
||||||
|
topProgressBar();
|
||||||
|
|
||||||
|
guardian();
|
||||||
|
|
||||||
|
await router.isReady();
|
||||||
|
|
||||||
|
app.mount('#app');
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap();
|
33
src/pages/index.vue
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<Index>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<router-view v-slot="{ Component, route }">
|
||||||
|
|
||||||
|
<transition
|
||||||
|
:name="route.meta.transition || 'el-fade-in-linear'"
|
||||||
|
mode="out-in"
|
||||||
|
appear
|
||||||
|
:duration="550"
|
||||||
|
>
|
||||||
|
<div :key="route.name">
|
||||||
|
<component :is="Component" :key="route.fullPath" />
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</router-view>
|
||||||
|
<!-- <router-view></router-view> -->
|
||||||
|
</Index>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import Index from '~/layout/Index.vue';
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
117
src/pages/index/business/about_us/components/CopyToDialog.vue
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="复制到其他语言" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type_guid">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleConfirmClick(formRef)">确定</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
import { editAboutUs } from "~/service/about_us";
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data.filter(v => v.i18n_lang_type_guid != props.locale)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
locale: String,
|
||||||
|
data: Object,
|
||||||
|
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({
|
||||||
|
i18n_lang_type_guid: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid: [{ required: true, message: "请选择语言类型" }],
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = async () => {
|
||||||
|
await geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirmClick = async (formRef) => {
|
||||||
|
if (!formRef) return;
|
||||||
|
formRef.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 执行复制操作
|
||||||
|
const copy = {
|
||||||
|
about_us_profile: props.data.about_us_profile,
|
||||||
|
about_us_profile_history: props.data.about_us_profile_history,
|
||||||
|
about_us_honor: props.data.about_us_honor,
|
||||||
|
about_us_honor_more: props.data.about_us_honor_more,
|
||||||
|
about_us_factory: props.data.about_us_factory,
|
||||||
|
about_us_exhibition: props.data.about_us_exhibition,
|
||||||
|
i18n_lang_type_guid: formData.i18n_lang_type_guid
|
||||||
|
}
|
||||||
|
// 发起编辑请求
|
||||||
|
const { code } = await editAboutUs(copy);
|
||||||
|
closeDialog();
|
||||||
|
|
||||||
|
// 调用父组件的 done 方法,参数为复制到的语言类型
|
||||||
|
props.done(formData.i18n_lang_type_guid);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.copy-btn-box {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
241
src/pages/index/business/about_us/index.vue
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>关于我们</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/AboutUs'">关于我们</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type_guid">
|
||||||
|
<el-select style="width:150px" v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择"
|
||||||
|
@change="changeI18n">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid" :label="item.i18n_lang_type_code"
|
||||||
|
:value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<el-button class="copy-to" type="primary" @click="handleCopyTo()"
|
||||||
|
:disabled="copyToDisabled">复制到...</el-button>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<h1>公司简介</h1>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width="labelWidth" label="头图" prop="about_us_profile">
|
||||||
|
<UploadImage v-model='formData.about_us_profile' :data=uoloadData :limit='1' :fileSize='5' :drag='true'
|
||||||
|
:isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label-width="labelWidth" label='历史' prop="about_us_profile_history">
|
||||||
|
<UploadImage v-model='formData.about_us_profile_history' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-divider />
|
||||||
|
|
||||||
|
<h1>荣誉资质</h1>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width="labelWidth" label="头图" prop="about_us_honor">
|
||||||
|
<UploadImage v-model='formData.about_us_honor' :data=uoloadData :limit='1' :fileSize='5' :drag='true'
|
||||||
|
:isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label-width="labelWidth" label='更多' prop='about_us_honor_more'>
|
||||||
|
<UploadImage v-model='formData.about_us_honor_more' :data=uoloadData :limit='99' :fileSize='5' :drag='true'
|
||||||
|
:isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-divider />
|
||||||
|
|
||||||
|
<h1>工厂照片</h1>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width="labelWidth" label='工厂照片' prop='about_us_factory'>
|
||||||
|
<UploadImage v-model='formData.about_us_factory' :data=uoloadData :limit='99' :fileSize='5' :drag='true'
|
||||||
|
:isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-divider />
|
||||||
|
|
||||||
|
<h1>展会信息</h1>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width="labelWidth" label='展会信息' prop='about_us_exhibition'>
|
||||||
|
<UploadImage v-model='formData.about_us_exhibition' :data=uoloadData :limit='99' :fileSize='5' :drag='true'
|
||||||
|
:isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-button type="primary" class="sus_button" @click="save(formRef)">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<CopyToDialog v-model="copyToDialogVisible" :locale="formData.i18n_lang_type_guid" :data="formData"
|
||||||
|
:done="CopyToDialogDone" />
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from "vue";
|
||||||
|
import { getAboutUs, editAboutUs } from "~/service/about_us";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
import CopyToDialog from "./components/CopyToDialog.vue";
|
||||||
|
const copyToDialogVisible = ref(false);
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const initFormState = {
|
||||||
|
about_us_profile: "",
|
||||||
|
about_us_profile_history: "",
|
||||||
|
about_us_honor: "",
|
||||||
|
about_us_honor_more: "",
|
||||||
|
about_us_factory: "",
|
||||||
|
about_us_exhibition: "",
|
||||||
|
};
|
||||||
|
let formData = ref({
|
||||||
|
i18n_lang_type_guid: "",
|
||||||
|
...initFormState
|
||||||
|
});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "AboutUs"
|
||||||
|
})
|
||||||
|
|
||||||
|
//验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '语言类型不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_profile: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_profile_history: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_honor: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_honor_more: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_factory: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
about_us_exhibition: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '内容不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const labelWidth = 200;
|
||||||
|
const formRef = ref();
|
||||||
|
|
||||||
|
const changeI18n = async (val) => {
|
||||||
|
getContent(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取
|
||||||
|
const getContent = async (locale) => {
|
||||||
|
const { code, data } = await getAboutUs({ i18n_lang_type_guid: locale });
|
||||||
|
if (code == 0) {
|
||||||
|
if (!data) {
|
||||||
|
formData.value = {
|
||||||
|
i18n_lang_type_guid: formData.value.i18n_lang_type_guid,
|
||||||
|
...initFormState
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formData.value = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//保存
|
||||||
|
const save = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { code } = await editAboutUs(formData.value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const CopyToDialogDone = (i18n_lang_type_guid) => {
|
||||||
|
formData.value.i18n_lang_type_guid = i18n_lang_type_guid;
|
||||||
|
getContent(i18n_lang_type_guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
|
||||||
|
const copyToDisabled = computed(() => {
|
||||||
|
return !formData.value.i18n_lang_type_guid;
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleCopyTo = () => {
|
||||||
|
copyToDialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.sus_button {
|
||||||
|
width: 300px;
|
||||||
|
height: 50px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upLoadEl {
|
||||||
|
:deep(.el-upload-list__item) {
|
||||||
|
height: 200px;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-list__item-thumbnail) {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-to {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加轮播图" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="轮播图位置" prop="banner_location">
|
||||||
|
<el-select v-model="formData.banner_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in banner_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='轮播图' prop='banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="跳转链接" prop="banner_link">
|
||||||
|
<el-input v-model='formData.banner_link' type="text" placeholder='请输入跳转链接'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="banner_order">
|
||||||
|
<el-input-number v-model='formData.banner_order' controls-position='right' :min="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { addBanner, getDictionary } from "~/service/banner";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const banner_location = ref([]);
|
||||||
|
async function get_banner_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'banner_location' }).then((res) => {
|
||||||
|
banner_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({
|
||||||
|
});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Banner"
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
banner_img: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '轮播图图片不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// banner_location: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// message: '轮播图片位置(字典)不能为空'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
get_banner_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
handleResetClick(formRef.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddClick = async (formEl) => {
|
||||||
|
console.log(formData);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code } = await addBanner(formData);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="轮播图详情" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :disabled="true">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="轮播图位置" prop="banner_location">
|
||||||
|
<el-select v-model="formData.banner_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in banner_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='轮播图' prop='banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='false' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="跳转链接" prop="banner_link">
|
||||||
|
<el-input v-model='formData.banner_link' type="text" placeholder='请输入跳转链接'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="banner_order">
|
||||||
|
<el-input-number v-model='formData.banner_order' controls-position='right'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { isEmptyObject } from "~/utils/index";
|
||||||
|
import { getDictionary } from '~/service/banner';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const banner_location = ref([]);
|
||||||
|
async function get_banner_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'banner_location' }).then((res) => {
|
||||||
|
banner_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
get_banner_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,169 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="编辑轮播图" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="轮播图位置" prop="banner_location">
|
||||||
|
<el-select v-model="formData.banner_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in banner_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='轮播图' prop='banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="跳转链接" prop="banner_link">
|
||||||
|
<el-input v-model='formData.banner_link' type="text" placeholder='请输入跳转链接'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="banner_order">
|
||||||
|
<el-input-number v-model='formData.banner_order' controls-position='right' :min="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleEditClick(formRef)">保存</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { editBanner, getDictionary } from "~/service/banner";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const banner_location = ref([]);
|
||||||
|
async function get_banner_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'banner_location' }).then((res) => {
|
||||||
|
banner_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Banner"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
get_banner_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
props.done();
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
// banner_img: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// message: '轮播图图片不能为空'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
banner_location: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '轮播图片位置(字典)不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
banner_order: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '排序不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleEditClick = async (formEl) => {
|
||||||
|
console.log(formData.value);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code } = await editBanner(formData.value);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
238
src/pages/index/business/banners/banner/index.vue
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>轮播图管理</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/banner/list">轮播图列表</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
|
||||||
|
<el-form inline :model="params">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select style="width:150px" v-model="params.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid" :label="item.i18n_lang_type_code"
|
||||||
|
:value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="轮播图位置">
|
||||||
|
<el-select v-model="params.banner_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in banner_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-space style="margin-bottom: 10px;">
|
||||||
|
<!-- 添加轮播图 -->
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="addBannerDialogVisible = true"> 添加 </el-button>
|
||||||
|
</el-col>
|
||||||
|
<!-- 下拉操作 -->
|
||||||
|
<el-dropdown v-if="selectionData.length">
|
||||||
|
<el-button type="primary">
|
||||||
|
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleDelete(selectionData)">
|
||||||
|
批量删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
<!-- 数据表格 -->
|
||||||
|
<DataTable v-loading="loading" ref="tableRef" style="width: 100%" :onSelectionChange="data => (selectionData = data)" :column="column"
|
||||||
|
:params="params" :request="params => getBannerList(params)">
|
||||||
|
<template #i18n_lang_type_code="scope">
|
||||||
|
<el-tag type="primary">{{ scope.row.i18n_lang_type_code }}</el-tag>
|
||||||
|
</template>
|
||||||
|
<!-- 排序 -->
|
||||||
|
<template #banner_order="scope">
|
||||||
|
<el-input-number :disabled="loading" v-model='scope.row.banner_order' controls-position="right"
|
||||||
|
@change="handleEditOrder(scope.row)" :min="1"></el-input-number>
|
||||||
|
</template>
|
||||||
|
<!-- 图片 -->
|
||||||
|
<template #banner_img="scope">
|
||||||
|
<el-image v-if="scope.row.banner_img" :src="scope.row.banner_img.split(',')[0]" lazy
|
||||||
|
:preview-src-list="scope.row.banner_img.split(',')" :preview-teleported="true" :hide-on-click-modal="true"
|
||||||
|
fit="contain" class="el-avatar"></el-image>
|
||||||
|
<template v-else>暂无图片</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #banner_location='scope'>
|
||||||
|
<dict-tag :options='banner_location' :value='scope.row.banner_location' />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #chaoz="scope">
|
||||||
|
<el-space>
|
||||||
|
<el-button size="small" @click="handleUpdate(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="handleCommand">
|
||||||
|
<el-button type="primary" size="small">
|
||||||
|
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
|
||||||
|
详情
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<!-- 添加轮播图 -->
|
||||||
|
<AddBannerDialog v-model="addBannerDialogVisible" :done="() => tableRef.reload()"></AddBannerDialog>
|
||||||
|
<!-- 编辑轮播图 -->
|
||||||
|
<EditBannerDialog v-model="EditBannerDialogVisible" :data="EditBannerDialogRow" :done="() => tableRef.reload()">
|
||||||
|
</EditBannerDialog>
|
||||||
|
<!-- 轮播图详情 -->
|
||||||
|
<DetailBannerDialog v-model="DetailBannerDialogVisible" :data="DetailBannerDialogRow"></DetailBannerDialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue';
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getBannerList, editBanner, deleteBanner, getDictionary } from '~/service/banner';
|
||||||
|
import AddBannerDialog from './components/AddBannerDialog.vue';
|
||||||
|
import EditBannerDialog from './components/EditBannerDialog.vue';
|
||||||
|
import DetailBannerDialog from './components/DetailBannerDialog.vue';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
const tableRef = ref();
|
||||||
|
const selectionData = ref([]);
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const addBannerDialogVisible = ref(false);
|
||||||
|
const EditBannerDialogVisible = ref(false);
|
||||||
|
const EditBannerDialogRow = ref({});
|
||||||
|
const DetailBannerDialogVisible = ref(false);
|
||||||
|
const DetailBannerDialogRow = ref({});
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const params = reactive({
|
||||||
|
banner_location: "",
|
||||||
|
i18n_lang_type_guid: ""
|
||||||
|
});
|
||||||
|
const column = [
|
||||||
|
|
||||||
|
{
|
||||||
|
fixed: true,
|
||||||
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "i18n_lang_type_code",
|
||||||
|
label: '语言类型code',
|
||||||
|
width: "150",},
|
||||||
|
{
|
||||||
|
prop: "banner_location",
|
||||||
|
label: '轮播图位置',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "banner_img",
|
||||||
|
label: '轮播图图片',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "banner_link",
|
||||||
|
label: '跳转链接',
|
||||||
|
width: '250'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "banner_order",
|
||||||
|
label: '排序',
|
||||||
|
width: '200'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
prop: 'chaoz',
|
||||||
|
width: '250',
|
||||||
|
fixed: 'right'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const handleCommand = ({ type, row }) => {
|
||||||
|
switch (type) {
|
||||||
|
case "detail":
|
||||||
|
handleDetail(row);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
handleDelete([row]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const handleDelete = data => {
|
||||||
|
ElMessageBox.confirm(`您确定要删除该轮播图吗?`).then(async () => {
|
||||||
|
const res = await deleteBanner({
|
||||||
|
banner_guid: data.map(v => v.banner_guid).join()
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//排序
|
||||||
|
async function handleEditOrder(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code, msg } = await editBanner(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
} else {
|
||||||
|
ElMessage.error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
function handleUpdate(row) {
|
||||||
|
EditBannerDialogVisible.value = true
|
||||||
|
EditBannerDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
DetailBannerDialogVisible.value = true
|
||||||
|
DetailBannerDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const banner_location = ref([]);
|
||||||
|
async function get_banner_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'banner_location' }).then((res) => {
|
||||||
|
banner_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
get_banner_location()
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
</script>
|
@ -0,0 +1,168 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加海报" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width='labelWidth' label="位置" prop="poster_location">
|
||||||
|
<el-select v-model="formData.poster_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in poster_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='poster_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.poster_img' :data=uoloadData :limit='1' :fileSize='20'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="poster_title">
|
||||||
|
<el-input v-model='formData.poster_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="描述" prop="poster_describe">
|
||||||
|
<el-input v-model='formData.poster_describe' type="text" placeholder='请输入描述'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="poster_sort">
|
||||||
|
<el-input-number v-model='formData.poster_sort' controls-position='right' :min="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { addPoster, getDictionary } from "~/service/poster";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const poster_location = ref([]);
|
||||||
|
async function get_poster_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'poster_location' }).then((res) => {
|
||||||
|
poster_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({
|
||||||
|
// poster_sort: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Poster"
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
poster_location: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '位置不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
poster_img: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '图片不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
get_poster_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
handleResetClick(formRef.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddClick = async (formEl) => {
|
||||||
|
console.log(formData);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code } = await addPoster(formData);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="海报详情" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :disabled="true">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width='labelWidth' label="位置" prop="poster_location">
|
||||||
|
<el-select v-model="formData.poster_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in poster_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='poster_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.poster_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='false' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="poster_title">
|
||||||
|
<el-input v-model='formData.poster_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="描述" prop="poster_describe">
|
||||||
|
<el-input v-model='formData.poster_describe' type="text" placeholder='请输入描述'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="poster_sort">
|
||||||
|
<el-input-number v-model='formData.poster_sort' controls-position='right'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { isEmptyObject } from "~/utils/index";
|
||||||
|
import { getDictionary } from '~/service/poster';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const poster_location = ref([]);
|
||||||
|
async function get_poster_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'poster_location' }).then((res) => {
|
||||||
|
poster_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
get_poster_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,170 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="编辑海报" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width='labelWidth' label="位置" prop="poster_location">
|
||||||
|
<el-select disabled v-model="formData.poster_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in poster_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span='24'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='poster_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.poster_img' :data=uoloadData :limit='1' :fileSize='20'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="poster_title">
|
||||||
|
<el-input v-model='formData.poster_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="描述" prop="poster_describe">
|
||||||
|
<el-input v-model='formData.poster_describe' type="text" placeholder='请输入描述'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="poster_sort">
|
||||||
|
<el-input-number v-model='formData.poster_sort' controls-position='right' :min="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleEditClick(formRef)">保存</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { editPoster, getDictionary } from "~/service/poster";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const poster_location = ref([]);
|
||||||
|
async function get_poster_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'poster_location' }).then((res) => {
|
||||||
|
poster_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Poster"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
get_poster_location()
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
props.done();
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
poster_location: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '位置不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
poster_img: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '图片不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
poster_sort: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '排序不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleEditClick = async (formEl) => {
|
||||||
|
console.log(formData.value);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code } = await editPoster(formData.value);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
248
src/pages/index/business/banners/poster/index.vue
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>海报管理</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/poster/list">海报列表</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<el-form inline :model="params">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select style="width:150px" v-model="params.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid" :label="item.i18n_lang_type_code"
|
||||||
|
:value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label-width='labelWidth' label="位置" prop="poster_location">
|
||||||
|
<el-select v-model="params.poster_location" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in poster_location" :key="item.dictionary_guid" :label="item.dictionary_name"
|
||||||
|
:value="item.dictionary_value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-space style="margin-bottom: 10px;">
|
||||||
|
<!-- 添加海报 -->
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="addPosterDialogVisible = true"> 添加 </el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 下拉操作 -->
|
||||||
|
<el-dropdown v-if="selectionData.length">
|
||||||
|
<el-button type="primary">
|
||||||
|
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleDelete(selectionData)">
|
||||||
|
批量删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
<!-- 数据表格 -->
|
||||||
|
<DataTable ref="tableRef" style="width: 100%" :onSelectionChange="data => (selectionData = data)" :column="column"
|
||||||
|
:params="params" :request="params => getPosterList(params)">
|
||||||
|
<template #i18n_lang_type_code="scope">
|
||||||
|
<el-tag type="primary">{{ scope.row.i18n_lang_type_code }}</el-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #poster_img="scope">
|
||||||
|
<el-image v-if="scope.row.poster_img" :src="scope.row.poster_img.split(',')[0]" lazy
|
||||||
|
:preview-src-list="scope.row.poster_img.split(',')" :preview-teleported="true" :hide-on-click-modal="true"
|
||||||
|
fit="contain" class="el-avatar"></el-image>
|
||||||
|
<template v-else>暂无图片</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 排序 -->
|
||||||
|
<template #poster_sort="scope">
|
||||||
|
<el-input-number :disabled="loading" v-model='scope.row.poster_sort' controls-position="right"
|
||||||
|
@change="handleEditOrder(scope.row)"></el-input-number>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #poster_location='scope'>
|
||||||
|
<dict-tag :options='poster_location' :value='scope.row.poster_location' />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #chaoz="scope">
|
||||||
|
<el-space>
|
||||||
|
<el-button size="small" @click="handleUpdate(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="handleCommand">
|
||||||
|
<el-button type="primary" size="small">
|
||||||
|
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
|
||||||
|
详情
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<!-- 添加海报 -->
|
||||||
|
<AddPosterDialog v-model="addPosterDialogVisible" :done="() => tableRef.reload()"></AddPosterDialog>
|
||||||
|
<!-- 编辑海报 -->
|
||||||
|
<EditPosterDialog v-model="EditPosterDialogVisible" :data="EditPosterDialogRow" :done="() => tableRef.reload()">
|
||||||
|
</EditPosterDialog>
|
||||||
|
<!-- 海报详情 -->
|
||||||
|
<DetailPosterDialog v-model="DetailPosterDialogVisible" :data="DetailPosterDialogRow"></DetailPosterDialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue';
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getPosterList, deletePoster, getDictionary,editPoster } from '~/service/poster';
|
||||||
|
import AddPosterDialog from './components/AddPosterDialog.vue';
|
||||||
|
import EditPosterDialog from './components/EditPosterDialog.vue';
|
||||||
|
import DetailPosterDialog from './components/DetailPosterDialog.vue';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const selectionData = ref([]);
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const addPosterDialogVisible = ref(false);
|
||||||
|
const EditPosterDialogVisible = ref(false);
|
||||||
|
const EditPosterDialogRow = ref({});
|
||||||
|
const DetailPosterDialogVisible = ref(false);
|
||||||
|
const DetailPosterDialogRow = ref({});
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const params = reactive({
|
||||||
|
poster_location: "",
|
||||||
|
i18n_lang_type_guid: ""
|
||||||
|
});
|
||||||
|
const column = [
|
||||||
|
|
||||||
|
{
|
||||||
|
fixed: true,
|
||||||
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "i18n_lang_type_code",
|
||||||
|
label: '语言类型code',
|
||||||
|
width: "150",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "poster_location",
|
||||||
|
label: '位置',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "poster_img",
|
||||||
|
label: '图片',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: "poster_title",
|
||||||
|
// label: '标题',
|
||||||
|
// width: '200'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: "poster_describe",
|
||||||
|
// label: '描述',
|
||||||
|
// width: '250'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: "poster_sort",
|
||||||
|
label: '排序',
|
||||||
|
width: '200'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
prop: 'chaoz',
|
||||||
|
width: '250',
|
||||||
|
fixed: 'right'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const handleCommand = ({ type, row }) => {
|
||||||
|
switch (type) {
|
||||||
|
case "detail":
|
||||||
|
handleDetail(row);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
handleDelete([row]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const handleDelete = data => {
|
||||||
|
ElMessageBox.confirm(`您确定要删除该海报吗?`).then(async () => {
|
||||||
|
const res = await deletePoster({
|
||||||
|
poster_guid: data.map(v => v.poster_guid).join()
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
function handleUpdate(row) {
|
||||||
|
EditPosterDialogVisible.value = true
|
||||||
|
EditPosterDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
DetailPosterDialogVisible.value = true
|
||||||
|
DetailPosterDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
//排序
|
||||||
|
const loading = ref(false)
|
||||||
|
async function handleEditOrder(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code, msg } = await editPoster(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 字典获取
|
||||||
|
const poster_location = ref([]);
|
||||||
|
async function get_poster_location() {
|
||||||
|
await getDictionary({ dictionary_value: 'poster_location' }).then((res) => {
|
||||||
|
poster_location.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
get_poster_location()
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
</script>
|
136
src/pages/index/business/contact_us/index.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>联系我们</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/ContactUs'">联系我们</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="24" style="display: none;">
|
||||||
|
<el-form-item :label-width="labelWidth" label="地址" prop="contact_us_address">
|
||||||
|
<el-input v-model='formData.contact_us_address' type="textarea" :rows="5" placeholder='请输入地址'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="座机电话" prop="contact_us_phone">
|
||||||
|
<el-input v-model='formData.contact_us_phone' type="text" placeholder='请输入座机电话'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="邮箱" prop="contact_us_mail">
|
||||||
|
<el-input v-model='formData.contact_us_mail' type="text" placeholder='请输入邮箱'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="手机号码" prop="contact_us_mobile_phone">
|
||||||
|
<el-input v-model='formData.contact_us_mobile_phone' type="text" placeholder='请输入手机号码'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-button type="primary" class="sus_button" @click="save(formRef)">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from "vue";
|
||||||
|
import { getContactUs, editContactUs } from "~/service/contact_us";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
let formData = ref({
|
||||||
|
contact_us_address: "",
|
||||||
|
contact_us_phone: "",
|
||||||
|
contact_us_mail: "",
|
||||||
|
contact_us_mobile_phone: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "ContactUs"
|
||||||
|
})
|
||||||
|
|
||||||
|
//验证规则
|
||||||
|
const rules = reactive({
|
||||||
|
contact_us_address: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '地址不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
contact_us_phone: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '座机电话不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
contact_us_mail: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '邮箱不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
contact_us_mobile_phone: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '手机号码不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const labelWidth = 200;
|
||||||
|
const formRef = ref();
|
||||||
|
|
||||||
|
//获取
|
||||||
|
const getContent = async () => {
|
||||||
|
const { code, data } = await getContactUs();
|
||||||
|
if (code == 0) {
|
||||||
|
formData.value = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getContent()
|
||||||
|
|
||||||
|
//保存
|
||||||
|
const save = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code } = await editContactUs(formData.value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.sus_button {
|
||||||
|
width: 300px;
|
||||||
|
height: 50px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upLoadEl {
|
||||||
|
:deep(.el-upload-list__item) {
|
||||||
|
height: 200px;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-upload-list__item-thumbnail) {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
154
src/pages/index/business/faq/components/AddFaqDialog.vue
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加常见问题" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type_guid">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="问题" prop="faq_questions">
|
||||||
|
<el-input v-model='formData.faq_questions' type="text" placeholder='请输入问题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item :label-width="labelWidth" label="答案" prop="faq_answer">
|
||||||
|
<el-input v-model='formData.faq_answer' type="textarea" :rows="5" placeholder='请输入答案'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="顺序" prop="faq_sort">
|
||||||
|
<el-input-number v-model='formData.faq_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { addFaq } from "~/service/faq";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Faq"
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid:[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '语言类型不能为空',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
faq_questions: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '问题不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
faq_answer: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '答案不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = async () => {
|
||||||
|
await geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
handleResetClick(formRef.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await addFaq(formData);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = flase;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
92
src/pages/index/business/faq/components/DetailFaqDialog.vue
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="常见问题详情" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :disabled="true">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type_guid">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="问题" prop="faq_questions">
|
||||||
|
<el-input v-model='formData.faq_questions' type="text" placeholder='请输入问题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item :label-width="labelWidth" label="答案" prop="faq_answer">
|
||||||
|
<el-input v-model='formData.faq_answer' type="textarea" :rows="5" placeholder='请输入答案'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="顺序" prop="faq_sort">
|
||||||
|
<el-input-number v-model='formData.faq_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { isEmptyObject } from "~/utils/index";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = async () => {
|
||||||
|
await geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
155
src/pages/index/business/faq/components/EditFaqDialog.vue
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="编辑常见问题" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type_guid">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="问题" prop="faq_questions">
|
||||||
|
<el-input v-model='formData.faq_questions' type="text" placeholder='请输入问题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item :label-width="labelWidth" label="答案" prop="faq_answer">
|
||||||
|
<el-input v-model='formData.faq_answer' type="textarea" :rows="5" placeholder='请输入答案'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="顺序" prop="faq_sort">
|
||||||
|
<el-input-number v-model='formData.faq_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleEditClick(formRef)" :loading="isBtnLod">保存</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { editFaq } from "~/service/faq";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Faq"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = async () => {
|
||||||
|
await geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
props.done();
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '语言类型不能为空',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
faq_questions: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '问题不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
faq_answer: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '答案不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
faq_sort: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '顺序不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleEditClick = async (formEl) => {
|
||||||
|
console.log(formData.value);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await editFaq(formData.value);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
246
src/pages/index/business/faq/index.vue
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>常见问题管理</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/faq/list">常见问题列表</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<el-form inline :model="params">
|
||||||
|
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select style="width:150px" v-model="params.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid" :label="item.i18n_lang_type_code"
|
||||||
|
:value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="问题">
|
||||||
|
<el-input v-model='params.faq_questions' placeholder='请输入问题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-space style="margin-bottom: 10px;">
|
||||||
|
<!-- 添加常见问题 -->
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="addFaqDialogVisible = true"> 添加 </el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 导入 -->
|
||||||
|
<el-upload class="upload-demo" :action="importExcel" :headers="headers" :on-success="handleExcelSuccess"
|
||||||
|
:on-progress="uploadLoading" :on-error="closeUploadLoading" style="margin-left: 10px" :show-file-list="false">
|
||||||
|
<el-button type="primary">导入</el-button>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<!-- 下载导入模板 -->
|
||||||
|
<el-button icon="ElIconDownload" @click="downloadTemplate()">下载导入模板</el-button>
|
||||||
|
|
||||||
|
<!-- 导出 -->
|
||||||
|
<el-button icon="ElIconDocument" @click="exportExcel(params)">导出</el-button>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 下拉操作 -->
|
||||||
|
<el-dropdown v-if="selectionData.length">
|
||||||
|
<el-button type="primary">
|
||||||
|
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleDelete(selectionData)">
|
||||||
|
批量删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
<!-- 数据表格 -->
|
||||||
|
<DataTable ref="tableRef" style="width: 100%" :onSelectionChange="data => (selectionData = data)" :column="column"
|
||||||
|
:params="params" :request="params => getFaqList(params)">
|
||||||
|
|
||||||
|
<template #i18n_lang_type_code="scope">
|
||||||
|
<el-tag type="primary">{{ scope.row.i18n_lang_type_code }}</el-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 排序 -->
|
||||||
|
<template #faq_sort='scope'>
|
||||||
|
<el-input-number :disabled='loading' v-model='scope.row.faq_sort' :min='1' controls-position='right'
|
||||||
|
@change='handleEditOrder(scope.row)'></el-input-number>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<template #chaoz="scope">
|
||||||
|
<el-space>
|
||||||
|
<el-button size="small" @click="handleUpdate(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="handleCommand">
|
||||||
|
<el-button type="primary" size="small">
|
||||||
|
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
|
||||||
|
详情
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<!-- 添加常见问题 -->
|
||||||
|
<AddFaqDialog v-model="addFaqDialogVisible" :done="() => tableRef.reload()"></AddFaqDialog>
|
||||||
|
<!-- 编辑常见问题 -->
|
||||||
|
<EditFaqDialog v-model="EditFaqDialogVisible" :data="EditFaqDialogRow" :done="() => tableRef.reload()">
|
||||||
|
</EditFaqDialog>
|
||||||
|
<!-- 常见问题详情 -->
|
||||||
|
<DetailFaqDialog v-model="DetailFaqDialogVisible" :data="DetailFaqDialogRow"></DetailFaqDialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue';
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getFaqList, editFaq, deleteFaq, downloadTemplate, importExcel, exportExcel } from '~/service/faq';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
import AddFaqDialog from './components/AddFaqDialog.vue';
|
||||||
|
import EditFaqDialog from './components/EditFaqDialog.vue';
|
||||||
|
import DetailFaqDialog from './components/DetailFaqDialog.vue';
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const selectionData = ref([]);
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const addFaqDialogVisible = ref(false);
|
||||||
|
const EditFaqDialogVisible = ref(false);
|
||||||
|
const EditFaqDialogRow = ref({});
|
||||||
|
const DetailFaqDialogVisible = ref(false);
|
||||||
|
const DetailFaqDialogRow = ref({});
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const params = reactive({
|
||||||
|
faq_questions: "",
|
||||||
|
i18n_lang_type_guid: ""
|
||||||
|
});
|
||||||
|
const column = [
|
||||||
|
{
|
||||||
|
fixed: true,
|
||||||
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "i18n_lang_type_code",
|
||||||
|
label: '语言类型code',
|
||||||
|
width: "150",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "faq_questions",
|
||||||
|
label: '问题',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "faq_sort",
|
||||||
|
label: '顺序',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
prop: 'chaoz',
|
||||||
|
width: '250',
|
||||||
|
fixed: 'right'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const handleCommand = ({ type, row }) => {
|
||||||
|
switch (type) {
|
||||||
|
case "detail":
|
||||||
|
handleDetail(row);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
handleDelete([row]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const handleDelete = data => {
|
||||||
|
ElMessageBox.confirm(`您确定要删除该常见问题吗?`).then(async () => {
|
||||||
|
const res = await deleteFaq({
|
||||||
|
faq_guid: data.map(v => v.faq_guid).join()
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
function handleUpdate(row) {
|
||||||
|
EditFaqDialogVisible.value = true
|
||||||
|
EditFaqDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
DetailFaqDialogVisible.value = true
|
||||||
|
DetailFaqDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 导入方法
|
||||||
|
let loadingImoprt = null;
|
||||||
|
const uploadLoading = () => {
|
||||||
|
loadingImoprt = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: "正在导入中...",
|
||||||
|
background: "rgba(255, 255, 255, 0.7)",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const closeUploadLoading = () => loadingImoprt.close();
|
||||||
|
const handleExcelSuccess = (value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
ElMessageBox.alert(value.msg, "导入信息", {
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ElMessage.error(value.msg);
|
||||||
|
}
|
||||||
|
closeUploadLoading();
|
||||||
|
tableRef.value.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
//排序
|
||||||
|
const loading = ref(false)
|
||||||
|
async function handleEditOrder(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code } = await editFaq(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 语言类型code
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
</script>
|
@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加交叉轮播图" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='cross_banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.cross_banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24" :hidden="true">
|
||||||
|
<el-form-item :label-width="labelWidth" label="位置" prop="cross_banner_position">
|
||||||
|
<el-select style="width:150px" v-model="formData.cross_banner_position" clearable placeholder="请选择位置">
|
||||||
|
<el-option label="上" :value="1"></el-option>
|
||||||
|
<el-option label="下" :value="2"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="cross_banner_sort">
|
||||||
|
<el-input-number v-model='formData.cross_banner_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { addCrossBanner } from "~/service/cross_banner";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({
|
||||||
|
cross_banner_position: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "cross_banner"
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
cross_banner_img: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '图片不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
cross_banner_position: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '位置不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// cross_banner_sort: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// message: '排序不能为空'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
handleResetClick(formRef.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await addCrossBanner(formData);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = flase;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="交叉轮播图详情" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :disabled="true">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='cross_banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.cross_banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='false' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24" :hidden="true">
|
||||||
|
<el-form-item :label-width="labelWidth" label="位置" prop="cross_banner_position">
|
||||||
|
<el-select style="width:150px" v-model="formData.cross_banner_position" clearable placeholder="请选择位置">
|
||||||
|
<el-option label="上" :value="1"></el-option>
|
||||||
|
<el-option label="下" :value="2"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="cross_banner_sort">
|
||||||
|
<el-input-number v-model='formData.cross_banner_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { isEmptyObject } from "~/utils/index";
|
||||||
|
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="编辑交叉轮播图" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span='12'>
|
||||||
|
<el-form-item :label-width='labelWidth' label='图片' prop='cross_banner_img'>
|
||||||
|
<UploadImage ref='uploadRef' v-model='formData.cross_banner_img' :data=uoloadData :limit='1' :fileSize='5'
|
||||||
|
:drag='true' :isShowTip='true' />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="24" :hidden="true">
|
||||||
|
<el-form-item :label-width="labelWidth" label="位置" prop="cross_banner_position">
|
||||||
|
<el-select style="width:150px" v-model="formData.cross_banner_position" clearable placeholder="请选择位置">
|
||||||
|
<el-option label="上" :value="1"></el-option>
|
||||||
|
<el-option label="下" :value="2"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="cross_banner_sort">
|
||||||
|
<el-input-number v-model='formData.cross_banner_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleEditClick(formRef)" :loading="isBtnLod">保存</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { editCrossBanner } from "~/service/cross_banner";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "cross_banner"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
props.done();
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
cross_banner_img: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '图片不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
cross_banner_position: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '位置不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
cross_banner_sort: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '排序不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleEditClick = async (formEl) => {
|
||||||
|
console.log(formData.value);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await editCrossBanner(formData.value);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
213
src/pages/index/business/homeData/cross_banner/index.vue
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>交叉轮播图</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/CrossBanner/list">交叉轮播图列表</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<el-form inline :model="params">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <el-form-item>
|
||||||
|
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item> -->
|
||||||
|
</el-form>
|
||||||
|
<el-space style="margin-bottom: 10px;">
|
||||||
|
<!-- 添加合作伙伴 -->
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="addCrossBannerDialogVisible = true"> 添加 </el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 下拉操作 -->
|
||||||
|
<el-dropdown v-if="selectionData.length">
|
||||||
|
<el-button type="primary">
|
||||||
|
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleDelete(selectionData)">
|
||||||
|
批量删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
<!-- 数据表格 -->
|
||||||
|
<DataTable ref="tableRef" style="width: 100%" :onSelectionChange="data => (selectionData = data)" :column="column"
|
||||||
|
:params="params" :request="params => getCrossBannerList(params)">
|
||||||
|
|
||||||
|
<template #cross_banner_img="scope">
|
||||||
|
<el-image v-if="scope.row.cross_banner_img" :src="scope.row.cross_banner_img.split(',')[0]" lazy
|
||||||
|
:preview-src-list="scope.row.cross_banner_img.split(',')" :preview-teleported="true" :hide-on-click-modal="true"
|
||||||
|
fit="contain" class="el-avatar"></el-image>
|
||||||
|
<template v-else>暂无图片</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- <template #cross_banner_position="scope">
|
||||||
|
<el-select style="width:150px" v-model="scope.row.cross_banner_position" placeholder="请选择位置"
|
||||||
|
@change="handleEditPosition(scope.row)">
|
||||||
|
<el-option label="上" :value="1"></el-option>
|
||||||
|
<el-option label="下" :value="2"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</template> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 排序 -->
|
||||||
|
<template #cross_banner_sort='scope'>
|
||||||
|
<el-input-number :disabled='loading' v-model='scope.row.cross_banner_sort' :min='1' controls-position='right'
|
||||||
|
@change='handleEditOrder(scope.row)'></el-input-number>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<template #chaoz="scope">
|
||||||
|
<el-space>
|
||||||
|
<el-button size="small" @click="handleUpdate(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="handleCommand">
|
||||||
|
<el-button type="primary" size="small">
|
||||||
|
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
|
||||||
|
详情
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<!-- 添加合作伙伴 -->
|
||||||
|
<AddCrossBannerDialog v-model="addCrossBannerDialogVisible" :done="() => tableRef.reload()"></AddCrossBannerDialog>
|
||||||
|
<!-- 编辑合作伙伴 -->
|
||||||
|
<EditCrossBannerDialog v-model="EditCrossBannerDialogVisible" :data="EditCrossBannerDialogRow"
|
||||||
|
:done="() => tableRef.reload()">
|
||||||
|
</EditCrossBannerDialog>
|
||||||
|
<!-- 合作伙伴详情 -->
|
||||||
|
<DetailCrossBannerDialog v-model="DetailCrossBannerDialogVisible" :data="DetailCrossBannerDialogRow">
|
||||||
|
</DetailCrossBannerDialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue';
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getCrossBannerList, editCrossBanner, deleteCrossBanner } from '~/service/cross_banner';
|
||||||
|
import AddCrossBannerDialog from './components/AddCrossBannerDialog.vue';
|
||||||
|
import EditCrossBannerDialog from './components/EditCrossBannerDialog.vue';
|
||||||
|
import DetailCrossBannerDialog from './components/DetailCrossBannerDialog.vue';
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const selectionData = ref([]);
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const addCrossBannerDialogVisible = ref(false);
|
||||||
|
const EditCrossBannerDialogVisible = ref(false);
|
||||||
|
const EditCrossBannerDialogRow = ref({});
|
||||||
|
const DetailCrossBannerDialogVisible = ref(false);
|
||||||
|
const DetailCrossBannerDialogRow = ref({});
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const params = reactive({
|
||||||
|
|
||||||
|
});
|
||||||
|
const column = [
|
||||||
|
|
||||||
|
{
|
||||||
|
fixed: true,
|
||||||
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "cross_banner_img",
|
||||||
|
label: '图片',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: "cross_banner_position",
|
||||||
|
// label: '位置',
|
||||||
|
// width: '180'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: "cross_banner_sort",
|
||||||
|
label: '排序',
|
||||||
|
width: '180'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
prop: 'chaoz',
|
||||||
|
width: '250',
|
||||||
|
fixed: 'right'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const handleCommand = ({ type, row }) => {
|
||||||
|
switch (type) {
|
||||||
|
case "detail":
|
||||||
|
handleDetail(row);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
handleDelete([row]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const handleDelete = data => {
|
||||||
|
ElMessageBox.confirm(`您确定要删除该交叉轮播图吗?`).then(async () => {
|
||||||
|
const res = await deleteCrossBanner({
|
||||||
|
cross_banner_guid: data.map(v => v.cross_banner_guid).join()
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
function handleUpdate(row) {
|
||||||
|
EditCrossBannerDialogVisible.value = true
|
||||||
|
EditCrossBannerDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
DetailCrossBannerDialogVisible.value = true
|
||||||
|
DetailCrossBannerDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//排序
|
||||||
|
const loading = ref(false)
|
||||||
|
async function handleEditOrder(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code } = await editCrossBanner(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 位置
|
||||||
|
async function handleEditPosition(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code } = await editCrossBanner(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,150 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="添加亮点" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select v-model="formData.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid"
|
||||||
|
:label="item.i18n_lang_type_code" :value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="highlights_title">
|
||||||
|
<el-input v-model='formData.highlights_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="highlights_sort">
|
||||||
|
<el-input-number v-model='formData.highlights_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleAddClick(formRef)">添加</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { addHighlights } from "~/service/highlights";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 90;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
const formData = reactive({});
|
||||||
|
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Highlights"
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(props, (v) => {
|
||||||
|
dialogVisible.value = v.modelValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '语言类型不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
highlights_title: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '标题不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// highlights_sort: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// message: '排序不能为空'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = async () => {
|
||||||
|
await geti18n_lang_typeList()
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
handleResetClick(formRef.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAddClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await addHighlights(formData);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = flase;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="亮点详情" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :disabled="true">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型guid" prop="i18n_lang_type_guid">
|
||||||
|
<el-input v-model='formData.i18n_lang_type_guid' type="text" placeholder='请输入语言类型guid'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="highlights_title">
|
||||||
|
<el-input v-model='formData.highlights_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="highlights_sort">
|
||||||
|
<el-input-number v-model='formData.highlights_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { isEmptyObject } from "~/utils/index";
|
||||||
|
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="props.modelValue" title="编辑亮点" width="900px" @closed="closeDialog" @open="openDialog">
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules">
|
||||||
|
<el-row>
|
||||||
|
|
||||||
|
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型guid" prop="i18n_lang_type_guid">
|
||||||
|
<el-input v-model='formData.i18n_lang_type_guid' type="text" placeholder='请输入语言类型guid'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="标题" prop="highlights_title">
|
||||||
|
<el-input v-model='formData.highlights_title' type="text" placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label-width="labelWidth" label="排序" prop="highlights_sort">
|
||||||
|
<el-input-number v-model='formData.highlights_sort' controls-position='right' :min='1'></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="handleEditClick(formRef)" :loading="isBtnLod">保存</el-button>
|
||||||
|
<el-button @click="handleResetClick(formRef)">重置</el-button>
|
||||||
|
<el-button @click="closeDialog()">取消</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from "vue";
|
||||||
|
import { editHighlights } from "~/service/highlights";
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
|
||||||
|
// --业务参数
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --业务方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --基础参数
|
||||||
|
const store = useLoginStore();
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
const isBtnLod = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const labelWidth = 100;
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
data: Object,
|
||||||
|
done: Function,
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
const formData = ref({
|
||||||
|
...props.data,
|
||||||
|
});
|
||||||
|
const uoloadData = ref({
|
||||||
|
dirName: "Highlights"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// --基础方法
|
||||||
|
watch(props, (v) => {
|
||||||
|
formData.value = v.data;
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开弹窗时执行
|
||||||
|
const openDialog = () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDialog = () => {
|
||||||
|
props.done();
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
i18n_lang_type_guid: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '语言类型guid不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
highlights_title: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '标题不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
highlights_sort: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '排序不能为空'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleEditClick = async (formEl) => {
|
||||||
|
console.log(formData.value);
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isBtnLod.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
const { code } = await editHighlights(formData.value);
|
||||||
|
if (code == 0) {
|
||||||
|
closeDialog();
|
||||||
|
props.done();
|
||||||
|
}
|
||||||
|
isBtnLod.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleResetClick = async (formEl) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped></style>
|
217
src/pages/index/business/homeData/highlights/index.vue
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 面包屑 -->
|
||||||
|
<el-breadcrumb>
|
||||||
|
<el-breadcrumb-item>亮点管理</el-breadcrumb-item>
|
||||||
|
<el-breadcrumb-item to="/highlights/list">亮点列表</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<el-form inline :model="params">
|
||||||
|
|
||||||
|
|
||||||
|
<el-form-item :label-width="labelWidth" label="语言类型" prop="i18n_lang_type">
|
||||||
|
<el-select style="width:150px" v-model="params.i18n_lang_type_guid" clearable placeholder="请选择">
|
||||||
|
<el-option v-for="item in i18n_lang_type" :key="item.i18n_lang_type_guid" :label="item.i18n_lang_type_code"
|
||||||
|
:value="item.i18n_lang_type_guid"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="标题">
|
||||||
|
<el-input v-model='params.highlights_title' placeholder='请输入标题'></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="tableRef.reload()" icon="ElIconSearch">
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-space style="margin-bottom: 10px;">
|
||||||
|
<!-- 添加亮点 -->
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-button type="primary" @click="addHighlightsDialogVisible = true"> 添加 </el-button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 下拉操作 -->
|
||||||
|
<el-dropdown v-if="selectionData.length">
|
||||||
|
<el-button type="primary">
|
||||||
|
批量操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleDelete(selectionData)">
|
||||||
|
批量删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
<!-- 数据表格 -->
|
||||||
|
<DataTable ref="tableRef" style="width: 100%" :onSelectionChange="data => (selectionData = data)" :column="column"
|
||||||
|
:params="params" :request="params => getHighlightsList(params)">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 排序 -->
|
||||||
|
<template #highlights_sort='scope'>
|
||||||
|
<el-input-number :disabled='loading' v-model='scope.row.highlights_sort' :min='1' controls-position='right'
|
||||||
|
@change='handleEditOrder(scope.row)'></el-input-number>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #i18n_lang_type_code="scope">
|
||||||
|
<el-tag type="primary">{{ scope.row.i18n_lang_type_code }}</el-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #chaoz="scope">
|
||||||
|
<el-space>
|
||||||
|
<el-button size="small" @click="handleUpdate(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown @command="handleCommand">
|
||||||
|
<el-button type="primary" size="small">
|
||||||
|
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item :command="{ type: 'detail', row: scope.row }">
|
||||||
|
详情
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="{ type: 'delete', row: scope.row }">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
</DataTable>
|
||||||
|
|
||||||
|
<!-- 添加亮点 -->
|
||||||
|
<AddHighlightsDialog v-model="addHighlightsDialogVisible" :done="() => tableRef.reload()"></AddHighlightsDialog>
|
||||||
|
<!-- 编辑亮点 -->
|
||||||
|
<EditHighlightsDialog v-model="EditHighlightsDialogVisible" :data="EditHighlightsDialogRow"
|
||||||
|
:done="() => tableRef.reload()"></EditHighlightsDialog>
|
||||||
|
<!-- 亮点详情 -->
|
||||||
|
<DetailHighlightsDialog v-model="DetailHighlightsDialogVisible" :data="DetailHighlightsDialogRow">
|
||||||
|
</DetailHighlightsDialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ArrowDown } from '@element-plus/icons-vue';
|
||||||
|
import { ref, reactive, watch } from 'vue';
|
||||||
|
import { useLoginStore } from "~/store";
|
||||||
|
import { getHighlightsList, editHighlights, deleteHighlights } from '~/service/highlights';
|
||||||
|
import { getI18nLangTypeList } from '~/service/i18n_lang_type';
|
||||||
|
import AddHighlightsDialog from './components/AddHighlightsDialog.vue';
|
||||||
|
import EditHighlightsDialog from './components/EditHighlightsDialog.vue';
|
||||||
|
import DetailHighlightsDialog from './components/DetailHighlightsDialog.vue';
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const selectionData = ref([]);
|
||||||
|
const store = useLoginStore();
|
||||||
|
|
||||||
|
const addHighlightsDialogVisible = ref(false);
|
||||||
|
const EditHighlightsDialogVisible = ref(false);
|
||||||
|
const EditHighlightsDialogRow = ref({});
|
||||||
|
const DetailHighlightsDialogVisible = ref(false);
|
||||||
|
const DetailHighlightsDialogRow = ref({});
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: "application/json",
|
||||||
|
...store.headers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const params = reactive({
|
||||||
|
i18n_lang_type_guid: "",
|
||||||
|
highlights_title: "",
|
||||||
|
|
||||||
|
});
|
||||||
|
const column = [
|
||||||
|
|
||||||
|
{
|
||||||
|
fixed: true,
|
||||||
|
type: 'selection'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "i18n_lang_type_code",
|
||||||
|
label: '语言类型code',
|
||||||
|
width: '150'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "highlights_title",
|
||||||
|
label: '标题',
|
||||||
|
width: '450'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "highlights_sort",
|
||||||
|
label: '排序',
|
||||||
|
width: '250'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
prop: 'chaoz',
|
||||||
|
width: '250',
|
||||||
|
fixed: 'right'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const handleCommand = ({ type, row }) => {
|
||||||
|
switch (type) {
|
||||||
|
case "detail":
|
||||||
|
handleDetail(row);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
handleDelete([row]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const handleDelete = data => {
|
||||||
|
ElMessageBox.confirm(`您确定要删除该亮点吗?`).then(async () => {
|
||||||
|
const res = await deleteHighlights({
|
||||||
|
highlights_guid: data.map(v => v.highlights_guid).join()
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
tableRef.value.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
function handleUpdate(row) {
|
||||||
|
EditHighlightsDialogVisible.value = true
|
||||||
|
EditHighlightsDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
DetailHighlightsDialogVisible.value = true
|
||||||
|
DetailHighlightsDialogRow.value = row
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//排序
|
||||||
|
const loading = ref(false)
|
||||||
|
async function handleEditOrder(data) {
|
||||||
|
loading.value = true
|
||||||
|
const { code } = await editHighlights(data);
|
||||||
|
if (code == 0) {
|
||||||
|
loading.value = false
|
||||||
|
tableRef.value.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const i18n_lang_type = ref();
|
||||||
|
async function geti18n_lang_typeList() {
|
||||||
|
getI18nLangTypeList({ limit: 9999 }).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
i18n_lang_type.value = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
geti18n_lang_typeList()
|
||||||
|
|
||||||
|
</script>
|