Commit 8632d44f authored by “yiyousong”'s avatar “yiyousong”

feat: 新增内容

parent 18c2ec08
> 1%
last 2 versions
not ie <= 10
# 系统名称
VUE_APP_systemName = 数字政务数据仓库管理服务系统
#门户
VUE_APP_API_portal_URL=http://192.168.0.98:11072
\ No newline at end of file
#开发环境
NODE_ENV = "development"
VUE_APP_API_BASE_URL=http://192.168.0.98:11078
VUE_APP_API_IMG_URL=http://192.168.0.98:11078/
# 生产环境配置
NODE_ENV = production
VUE_APP_API_BASE_URL=/basics_api
VUE_APP_API_portal_URL=/portal_home
VUE_APP_API_IMG_URL = /basics_api/
#测试环境
NODE_ENV = "test"
VUE_APP_API_BASE_URL=/basics_api
VUE_APP_API_portal_URL=/portal_home
VUE_APP_API_IMG_URL = /basics_api/
\ No newline at end of file
#宜宾环境
NODE_ENV = "production"
VUE_APP_API_BASE_URL=/basics_api
\ No newline at end of file
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/essential", "eslint:recommended"],
parserOptions: {
parser: "@babel/eslint-parser",
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
overrides: [
{
files: ["src/**/**/*.vue"],
rules: {
"vue/multi-word-component-names": 0,
},
},
],
};
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# 数字政务应用服务多端管理中台
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
This diff is collapsed.
{
"name": "portal",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@ianwalter/vuex-reset": "^4.3.4",
"@jiaminghi/data-view": "^2.10.0",
"axios": "^1.4.0",
"core-js": "^3.8.3",
"crypto-js": "^4.1.1",
"echarts": "^5.4.3",
"element-ui": "^2.15.14",
"js-export-excel": "^1.1.4",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"secure-ls": "^1.2.6",
"swiper": "5",
"vue": "^2.6.14",
"vue-lazyload": "1.3.3",
"vue-router": "^3.5.1",
"vuex": "^3.6.2",
"vuex-persistedstate": "^4.1.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@tailwindcss/postcss7-compat": "^2.2.17",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"autoprefixer": "^10.4.14",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"less": "^4.0.0",
"less-loader": "^8.0.0",
"postcss": "^8.4.27",
"prettier": "2.8.8",
"prettier-plugin-tailwindcss": "0.4.1",
"tailwindcss": "^3.3.3",
"vue-template-compiler": "^2.6.14"
}
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
// prettier.config.js
module.exports = {
plugins: ['prettier-plugin-tailwindcss'],
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= process.env.VUE_APP_systemName %></title>
<style>
@font-face {
font-family: Source Han Sans CN ;
src: url('./SourceHanSansSC-Regular-2.otf');
}
</style>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div class="app h-full w-full">
<router-view />
</div>
</template>
<script>
export default {
data() {
return {};
},
created() {},
methods: {},
};
</script>
<style lang="less" scoped>
.app {
background-color: #f5f5f5;
}
</style>
import request from "@/utils/request";
// 获取个人站点树
export const getSiteTree = (params) => {
return request({
url: `/base/site/siteTree`,
method: "get",
params,
});
};
/* 颜色 */
.primary {
color: #1890ff;
}
.delete {
color: #ff4d4f;
}
.green {
color: #1bbc9b;
}
.clofff {
color: #fff;
}
.orange {
color: orange;
}
.bgdel {
background-color: #ff4d4f;
}
.bgpr {
background-color: #1890ff;
}
.bgg {
background-color: #1bbc9b;
}
.bgw{
background-color: #fff;
}
.primary-bg{
background: linear-gradient(90deg, #1845c6 0%, #2999ff 100%);
}
.pagination {
margin-top: 10px;
text-align: right;
}
/**
element-ui
*/
/* el-table列数据为空自动显示-- */
.cell:empty::before {
content: "--";
color: gray;
}
.el-dialog__body {
border-top: 1px solid #ececec;
border-bottom: 1px solid #ececec;
padding: 20px !important;
}
.el-card {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.el-card__body {
width: 100%;
flex: 1;
padding-bottom: 10px !important;
}
.gutter {
width: 6px !important;
}
.auto-scroll{
overflow-y: auto;
}
// ::-webkit-scrollbar {
// width: 6px;
// height: 6px;
// overflow-y: auto;
// }
// ::-webkit-scrollbar-thumb {
// border-radius: 6px;
// background-color: rgba(144, 147, 153, 0.5);
// }
// ::-webkit-scrollbar-track {
// border-radius: 6px;
// background: rbga(0, 0, 0, 0);
// }
.autoWidth {
min-width: 120px;
}
.autoWidth .el-input__prefix {
position: relative;
left: 0px;
box-sizing: border-box;
border: 1px solid #ffffff00;
padding: 0px 30px;
height: 32px;
line-height: 32px;
visibility: hidden;
}
.autoWidth .el-input__inner {
padding-left: 15px !important;
position: absolute;
}
.el-tooltip__popper {
max-width: 20%;
}
.el-drawer__header {
margin-bottom: 20px !important;
}
.el-drawer__body {
border-top: 1px solid #ececec;
}
.el-button--primary {
background: linear-gradient(90deg, #5ab6ff, #2e9aff) !important;
border: none !important;
border-color: transparent !important;
}
.el-dialog__header {
.el-dialog__title {
color: #1890ff !important;
font-size: 18px;
font-weight: bold;
}
.el-dialog__close {
color: #188fff !important;
font-size: 26px;
font-weight: bold;
}
}
.el-pagination__jump {
margin-left: 0px !important;
}
.el-tabs__nav-scroll {
padding-left: 15px;
.tab-label {
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
}
.is-active {
.tab-label {
color:#2681e8
}
}
}
.el-tabs__header{
margin: 0px !important;
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
\ No newline at end of file
/*
* 在 normalize.css 基础上进行的其他重置
*/
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
}
html {
/* AntD 字体家族:https://ant.design/docs/spec/font-cn#%E5%AD%97%E4%BD%93%E5%AE%B6%E6%97%8F */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
p {
margin: 0;
padding: 0;
}
input,
button {
border: none;
/* 去掉浏览器默认的 input 边框样式 */
outline: none;
/* 去掉浏览器默认的聚焦时候的蓝色边框 */
}
a {
text-decoration: none;
color: #000;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
padding: 0
}
\ No newline at end of file
/* @import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities'; */
/* @tailwind base; */
@tailwind components;
@tailwind utilities;
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
This diff is collapsed.
@font-face {
font-family: "iconfont"; /* Project id 4222008 */
src: url('iconfont.woff2?t=1692777691620') format('woff2'),
url('iconfont.woff?t=1692777691620') format('woff'),
url('iconfont.ttf?t=1692777691620') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-dot:before {
content: "\e608";
}
.icon-hidden:before {
content: "\e607";
}
.icon-pwd:before {
content: "\e615";
}
.icon-show:before {
content: "\e61c";
}
.icon-user:before {
content: "\e649";
}
window._iconfont_svg_string_4222008='<svg><symbol id="icon-dot" viewBox="0 0 1024 1024"><path d="M512 320a192.064 192.064 0 0 1 0 384 192 192 0 0 1 0-384z" fill="" ></path></symbol><symbol id="icon-hidden" viewBox="0 0 1024 1024"><path d="M853.504 451.072c46.592-34.816 85.504-76.288 110.592-123.904 7.168-13.824 1.536-31.232-11.776-37.888-6.656-3.584-14.336-4.608-21.504-2.048-7.168 2.048-13.312 7.168-16.384 14.336-62.464 118.272-223.744 198.144-401.92 198.144S173.568 419.84 110.592 301.568c-3.584-6.656-9.216-11.776-16.384-13.824-7.168-2.048-14.848-1.536-21.504 2.048-14.336 6.656-19.456 24.576-11.776 37.888 25.088 47.616 63.488 90.112 110.592 123.904l-107.52 134.144c-6.656 8.704-8.192 20.48-3.584 30.208 4.608 9.728 14.848 16.384 25.6 16.384 8.704 0 16.384-3.584 22.016-10.752l111.616-138.752c49.664 27.648 106.496 48.128 167.936 60.416l-71.168 155.136c-6.656 14.336 0 31.232 14.336 37.376 4.096 1.536 8.192 3.072 11.776 3.072 10.752 0 20.992-6.144 26.112-16.384l76.8-170.496c21.504 2.048 44.032 4.096 66.56 4.096 18.432 0 35.84-1.536 53.248-3.072l77.312 168.96c3.072 6.656 8.704 12.288 15.872 14.848 7.168 2.56 14.848 2.048 21.504-1.024 14.336-6.144 20.48-23.552 14.336-37.376l-69.632-153.6c63.488-10.24 124.416-31.744 180.224-62.976l111.104 138.752c5.632 6.656 13.824 10.752 22.016 10.752 6.144 0 12.288-2.048 17.408-6.144 12.288-9.728 14.336-27.648 4.608-39.936l-106.496-134.144z m0 0" ></path></symbol><symbol id="icon-pwd" viewBox="0 0 1024 1024"><path d="M725.4 928.3H299.7c-88 0-159.6-71.6-159.6-159.6V555.8c0-88 71.6-159.6 159.6-159.6h425.7c88 0 159.6 71.6 159.6 159.6v212.8c0 88.1-71.6 159.7-159.6 159.7zM299.7 460c-52.8 0-95.8 43-95.8 95.8v212.8c0 52.8 43 95.8 95.8 95.8h425.7c52.8 0 95.8-43 95.8-95.8V555.8c0-52.8-43-95.8-95.8-95.8H299.7z" fill="#A1A0A5" ></path><path d="M778.6 406.8h-63.9c0-110.9-90.2-244.8-202.2-244.8S310.3 296 310.3 406.8h-63.9c0-142.7 116.2-308.6 266.1-308.6s266.1 165.9 266.1 308.6z" fill="#A1A0A5" ></path></symbol><symbol id="icon-show" viewBox="0 0 1024 1024"><path d="M678.976 586.24c0 92.224-74.752 166.976-166.976 166.976S345.024 678.464 345.024 586.24 419.776 419.2 512 419.2s166.976 74.816 166.976 167.04z" fill="#666666" ></path><path d="M512 266.112C229.248 266.112 0 586.24 0 586.24s229.248 320.128 512 320.128 512-320.128 512-320.128-229.248-320.128-512-320.128z m0 532.992c-117.568 0-212.864-95.296-212.864-212.864 0-117.568 95.296-212.864 212.864-212.864s212.864 95.296 212.864 212.864c0 117.568-95.296 212.864-212.864 212.864z" fill="#666666" ></path><path d="M678.976 586.24c0 92.224-74.752 166.976-166.976 166.976S345.024 678.464 345.024 586.24 419.776 419.2 512 419.2s166.976 74.816 166.976 167.04z" fill="#666666" ></path><path d="M678.976 586.24c0 92.224-74.752 166.976-166.976 166.976S345.024 678.464 345.024 586.24 419.776 419.2 512 419.2s166.976 74.816 166.976 167.04z" fill="#666666" ></path></symbol><symbol id="icon-user" viewBox="0 0 1024 1024"><path d="M602.08 960.576H423.488c-169.408 0-303.2 0-303.2-87.872v-17.568c0-164.672 136.032-298.624 303.2-298.624H602.08c167.168 0 303.2 133.952 303.2 298.624v17.568c-0.032 87.872-140.544 87.872-303.2 87.872zM423.456 609.184c-138.112 0-250.496 110.304-250.496 245.92v17.568c0 35.168 144.768 35.168 250.496 35.168h178.592c87.52 0 250.496 0 250.496-35.168v-17.568c0-135.616-112.384-245.92-250.496-245.92H423.456z m80.384-70.304c-132.736 0-240.672-106.4-240.672-237.184S371.104 64.544 503.84 64.544s240.672 106.368 240.672 237.152S636.544 538.88 503.84 538.88zM315.872 301.696c0 101.696 84.32 184.48 187.968 184.48s187.968-82.752 187.968-184.48-84.32-184.448-187.968-184.448S315.872 200 315.872 301.696z" ></path></symbol></svg>',function(n){var t=(t=document.getElementsByTagName("script"))[t.length-1],e=t.getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var c,i,o,l,d,s=function(t,e){e.parentNode.insertBefore(t,e)};if(e&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(t){console&&console.log(t)}}c=function(){var t,e=document.createElement("div");e.innerHTML=n._iconfont_svg_string_4222008,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?s(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),c()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(o=c,l=n.document,d=!1,h(),l.onreadystatechange=function(){"complete"==l.readyState&&(l.onreadystatechange=null,a())})}function a(){d||(d=!0,o())}function h(){try{l.documentElement.doScroll("left")}catch(t){return void setTimeout(h,50)}a()}}(window);
\ No newline at end of file
{
"id": "4222008",
"name": "门户",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "1920286",
"name": "点",
"font_class": "dot",
"unicode": "e608",
"unicode_decimal": 58888
},
{
"icon_id": "12183287",
"name": "不可见",
"font_class": "hidden",
"unicode": "e607",
"unicode_decimal": 58887
},
{
"icon_id": "12387627",
"name": "密码",
"font_class": "pwd",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "15391351",
"name": "可见",
"font_class": "show",
"unicode": "e61c",
"unicode_decimal": 58908
},
{
"icon_id": "29195000",
"name": "用户",
"font_class": "user",
"unicode": "e649",
"unicode_decimal": 58953
}
]
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
let customComponents = {
install: function (Vue) {
//在use的时候vue会自动调用此方法
const files = require.context("@/components/autoRegister", true, /\.vue$/); //返回的是一个函数
// require.context()的参数
// 参数一 {String}:读取文件的目录路径
// 参数二 {Boolean}:是否深入遍历,即是否遍历子目录(二级目录)
// 参数三 {RegExp}:匹配目录内文件的正则表达式/\.vue$/表示匹配所有.vue后缀名的文件
files.keys().forEach((item) => {
const componentConfig = files(item);
const name = componentConfig.default.name || componentConfig.name;
const component = componentConfig.default || componentConfig;
Vue.component(name, component); //注册当前组件
});
},
};
export default customComponents;
export const pageSizeOptions = ["10", "30", "50", "100", "200"]; // 翻页-每页显示数量
import store from "@/store";
// 权限渲染
export const permission = {
inserted: function (el, binding) {
const { value } = binding;
const roles = store.getters["user/userId"];
if (value) {
const permissionRoles = value;
const hasPermission = permissionRoles.includes(roles);
if (!hasPermission) {
el.remove();
}
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`);
}
},
};
import moment from "moment";
// 时间格式 年月日时分秒
export function dateFormat(val) {
return moment(val).format("YYYY-MM-DD HH:mm:ss");
}
// 时分秒
export function times(val) {
return moment(val).format("HH:mm:ss");
}
// 年
export function year(val) {
return moment(val).format("YYYY");
}
// 号数
export function days(val) {
return moment(val).format("MM-DD");
}
// 过滤叫号状态
export function filterStyle(val) {
const style = {
0: "排队中",
1: "办理中",
4: "办理完成",
};
let str;
Object.keys(style).forEach((key) => {
if (key == val) {
str = style[key];
}
});
return str;
}
// 过滤政治面貌
export function filterPolitical(val) {
const obj = {
0: "中共党员",
1: "中共预备党员",
2: "共青团员",
3: "普通居民",
4: "其他",
};
let str;
Object.keys(obj).forEach((key) => {
if (key == val) {
str = obj[key];
}
});
return str;
}
// 过滤密码显示*号
export function filterPwd(val) {
let str = val.replace(/\S/g, "*");
return str;
}
// 过滤会员等级
export function filterMember(val) {
const member = {
1: "试用客户",
// 2: "VIP客户",
3: "设计师",
};
let str = "--";
Object.keys(member).forEach((key) => {
if (key == val) {
str = member[key];
}
});
return str;
}
// 过滤客户来源
export function filterCustomerSrc(val) {
const customer = {
1: "申请试用",
2: "顾问签单",
};
let str = "--";
Object.keys(customer).forEach((key) => {
if (key == val) {
str = customer[key];
}
});
return str;
}
<template>
<div class="flex h-full w-full flex-col">
<Header></Header>
<div
:class="[
'out-box',
'flex-1',
'overflow-auto',
'pb-[24px]',
{
'not-home': $route.path != '/home',
},
]"
>
<keep-alive>
<!-- 需要缓存的视图组件 -->
<router-view v-if="$route.meta.keepAlive"> </router-view>
</keep-alive>
<!-- 不需要缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive"> </router-view>
</div>
</div>
</template>
<script>
import Header from "./components/Header.vue";
export default {
components: {
Header,
},
};
</script>
<style lang="less" scoped>
.not-home {
padding-left: 50px;
padding-right: 50px;
}
</style>
<template>
<div class="header flex items-center justify-between">
<div class="left flex items-center">
<img
class="logo mr-[10px] cursor-pointer"
:src="sysLogo ? sysLogo : require('@/assets/img/logo.png')"
alt="LOGO"
@click="handleGoHome"
/>
<h1 class="title cursor-pointer" @click="handleGoHome">
{{ sysName ? sysName : systemName }}
</h1>
<HeaderSite class="mr50 ml20"></HeaderSite>
<!-- 导航 -->
<el-menu
:default-active="activeMenu"
mode="horizontal"
router
text-color="rgba(254, 254, 254, 0.65)"
>
<template v-for="v in menus">
<el-submenu
v-if="!v.hideChildrenInMenu && v.children && v.children.length"
:key="'a' + v.path"
:index="v.path"
>
<template slot="title">
<i v-if="v.meta && v.meta.icon" :class="v.meta.icon"></i>
{{ v.meta.title }}
</template>
<el-menu-item
v-for="item in v.children"
:key="item.path"
:index="item.path"
>
<i v-if="item.meta && item.meta.icon" :class="item.meta.icon"></i>
{{ item.meta && item.meta.title }}
</el-menu-item>
</el-submenu>
<el-menu-item v-else :key="v.path" :index="v.path">
<i v-if="v.meta && v.meta.icon" :class="v.meta.icon"></i>
{{ v.meta.title }}
</el-menu-item>
</template>
</el-menu>
</div>
<!-- 返回门户 -->
<div class="back-btn">
<el-tooltip effect="dark" content="返回门户" placement="bottom">
<a class="pointer" :href="portal + (path ? path : '')">
<i class="el-icon-s-home"></i> 返回门户
</a>
</el-tooltip>
</div>
</div>
</template>
<script>
import HeaderSite from "./HeaderSite.vue";
import { mapState } from "vuex";
export default {
components: {
HeaderSite,
},
data() {
return {
systemName: process.env.VUE_APP_sysName,
portal: process.env.VUE_APP_API_portal_URL + "/#",
};
},
computed: {
activeMenu() {
const route = this.$route;
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
...mapState("user", ["menus", "sysName", "sysLogo", "path"]),
},
created() {
document.title = this.sysName ? this.sysName : this.systemName; // 设置项目标题
},
methods: {
handleGoHome() {
this.$router.push("/home");
},
},
};
</script>
<style lang="less" scoped>
.header {
height: 64px;
width: 100%;
padding: 0px 24px;
// background-color: #2681e8;
background: linear-gradient(90deg, #1845c6 0%, #2999ff 100%);
color: #fff;
flex-shrink: 0;
.left {
height: 100%;
}
.logo {
height: 32px;
object-fit: contain;
}
.title {
max-width: 200px;
font-size: 18px;
}
.back-btn {
a {
color: #fff;
font-size: 14px;
}
}
}
/deep/.el-menu {
height: 100% !important;
border: none !important;
background-color: transparent;
i {
color: rgba(254, 254, 254, 0.65);
}
.el-menu-item {
height: 100% !important;
border: none !important;
display: flex;
align-items: center;
color: rgba(254, 254, 254, 0.65);
&:hover {
// background-color: transparent !important;
color: #fff !important;
background-color: #1890ff !important;
// border-bottom: 2px solid #fff !important;
}
}
}
/deep/.el-submenu {
height: 100% !important;
.el-submenu__title {
height: 100% !important;
display: flex;
align-items: center;
color: rgba(254, 254, 254, 0.65) !important;
border: none !important;
&:hover {
// background-color: transparent !important;
color: #fff !important;
background-color: #1890ff !important;
// border-bottom: 2px solid #fff !important;
}
}
}
.el-menu--horizontal .el-menu .el-menu-item {
color: #909399;
&:hover {
i {
color: #1890ff;
}
color: #1890ff;
}
}
.el-menu--horizontal .el-menu .el-menu-item.is-active {
color: #1890ff !important;
}
/deep/.is-active {
// border-bottom: 2px solid #fff !important;
color: #fff !important;
// background-color: transparent !important;
background-color: #1890ff !important;
.el-submenu__title {
border: none !important;
color: #fff !important;
// background-color: transparent !important;
background-color: #1890ff !important;
}
}
</style>
<template>
<el-popover placement="bottom-start" trigger="manual" v-model="visible">
<a slot="reference" class="ant-dropdown-link" @click="visible = true">
{{ siteName }} <i class="el-icon-arrow-down"></i>
</a>
<div
class="content"
style="min-width: 60vw; max-width: 80vw; min-height: 200px"
>
<div class="flex_row flex_align_c primary-color name">
<i class="el-icon-location" style="margin-right: 10px"></i>
<span style="">{{ siteName }}</span>
</div>
<div class="site-list">
<span
v-for="(item, index) in sitelist"
:key="index"
:class="{ 'primary-color': item.id == checkid }"
@click="setSite(item)"
>{{ item.label }}</span
>
</div>
<div class="check-site">
<span>您的选择是:</span>
<span
v-for="(item, index) in checkarr"
:key="index"
@click="updataSite(item)"
>{{ index > 0 ? ">" : "" }}{{ item.label }}</span
>
</div>
<div class="site-btn">
<el-button size="small" @click="visible = false">取消</el-button>
<el-button
type="primary"
size="small"
@click="onSucessSite"
:disabled="isSite"
>确定</el-button
>
</div>
</div>
</el-popover>
</template>
<script>
import { getSiteTree } from "@/api/site";
import storage from "@/utils/storage";
export default {
data() {
return {
sitelist: [],
visible: false,
offsetLeft: 0,
checkarr: [], //选中站点
checkid: undefined, //最终选中站点
siteName: "请选择站点",
isSite: true,
};
},
computed: {},
created() {
this.getwaitedListdata();
},
mounted() {},
methods: {
// 确认站点
onSucessSite() {
if (this.checkarr.length == 0) return;
let obj = this.checkarr[this.checkarr.length - 1];
this.clickSite(obj);
},
// 选中
setSite(obj) {
this.checkid = undefined;
// 为子节点不添加数据
let data = this.checkarr[this.checkarr.length - 1];
if (data && (data.isLeaf || data.children.length == 0)) {
// 如果为子节点更新最后一个数据
this.checkid = obj.id;
this.checkarr[this.checkarr.length - 1] = obj;
// 如果选中数据有子集更新站点列表
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
} else {
this.checkarr.push(obj);
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
}
if (obj && obj.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
},
// 更新选中
updataSite(row) {
const { id } = row;
this.checkid = undefined;
let index = this.checkarr.findIndex((v) => v.id == id);
if (index > -1) {
this.checkarr.splice(index + 1, this.checkarr.length - (index + 1));
}
if (row.children && row.children.length > 0) {
this.sitelist = row.children;
}
if (row && row.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
// this.getwaitedListdata(id);
},
getwaitedListdata() {
getSiteTree().then((res) => {
const { code, data } = res.data;
if (code == 1) {
const { siteTree } = data;
this.sitelist = siteTree;
let arr = [];
const treeFn = function (e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
treeFn(element.children);
}
});
};
const siteid = storage.get(2, "siteId");
treeFn(siteTree);
const siteObj = arr.find((v) => v.id == siteid);
this.siteName = siteObj ? siteObj.label : "请选择站点";
}
});
},
clickSite(obj) {
storage.set(2, "siteId", obj.id);
this.show = false;
if (location.href.search(/token/gi) >= 0) {
setTimeout(() => {
location.reload();
});
} else {
location.reload();
}
},
// ontrigger(e) {
// if (e.target && e.target.nodeName == "A") {
// this.show = !this.show;
// }
// },
},
};
</script>
<style lang="less" scoped>
.ant-dropdown-link {
padding: 0 20px;
font-size: 16px;
min-width: 200px;
display: inline-block;
}
.content {
display: flex;
flex-direction: column;
justify-content: space-around;
.name {
font-size: 20px;
color: #1890ff;
}
.site-list {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
display: flex;
flex-wrap: wrap;
span {
line-height: 1.5;
padding: 10px 20px;
cursor: pointer;
&:hover {
color: #1890ff;
}
}
}
.check-site,
.site-btn {
padding: 0 20px;
}
.check-site {
cursor: pointer;
}
}
.trigger {
display: inline-block;
position: relative;
}
.ant-dropdown-link {
padding: 0 20px;
font-size: 16px;
display: inline-block;
color: #fff;
cursor: pointer;
}
.select-site {
position: fixed;
left: 300px !important;
top: 65px;
background: #fff;
border-radius: 6px;
padding: 10px;
min-width: 60%;
max-width: 80%;
z-index: 9;
color: rgba(0, 0, 0, 0.8);
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
.name {
font-size: 20px;
}
.site-list {
// padding: 10px 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
overflow: hidden;
span {
float: left;
line-height: 1.5;
padding: 10px 20px;
cursor: pointer;
&:hover {
color: #1890ff;
}
}
}
.check-site,
.site-btn {
padding: 0 20px;
}
}
</style>
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
// UI
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
import { message } from "@/utils/resetMessage";
Vue.prototype.$message = message;
// 公共样式
import "@/assets/css/normalize.css";
import "@/assets/css/reset.css";
import "@/assets/css/common.less";
import "@/assets/css/tailwindcss.css";
import "@/assets/fonts/iconfont.css";
// 事件总线
Vue.prototype.$bus = new Vue();
// moment 时间处理
import moment from "moment";
Vue.prototype.$moment = moment;
// 全局过滤器
import * as filters from "@/filters";
Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]);
});
// 引入注册全局指令
import * as directives from "@/directive";
Object.keys(directives).forEach((name) =>
Vue.directive(name, directives[name])
);
// 引入echarts
import * as echarts from "echarts";
Vue.prototype.$echarts = echarts;
// 注册全局组件
// import customComponents from "@/components";
// Vue.use(customComponents);
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
<template>
<div>数据引擎</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped></style>
<template>
<div class="home h-full w-full">
<div class="top-bg primary-bg h-[210px] w-full"></div>
<div class="main flex w-full flex-col gap-5">
<div class="top-data-box flex h-[100px] w-full items-center gap-5">
<div class="top-data-total h-full w-[30%] rounded-md p-[20px]">
<div class="flex flex-col gap-5">
<div>
<span class="mr-5"> 累计汇聚数据 </span>
<span class="text-[14px] text-[#888888]">
数仓最近汇聚时间:2024-06-26 23:59:59
</span>
</div>
<div class="flex">
<el-statistic
group-separator=","
:value="895671230"
suffix="条"
:value-style="{
color: '#1890ff',
fontSize: '22px',
fontWeight: 'bold',
}"
></el-statistic>
</div>
</div>
</div>
<div
class="top-data-text flex h-full flex-1 items-center rounded-md p-[20px]"
>
<el-carousel
height="26px"
direction="vertical"
indicator-position="none"
>
<el-carousel-item>
<div class="top-text primary">您好,欢迎使用数据仓库工作台。</div>
</el-carousel-item>
<el-carousel-item>
<div class="top-text primary">
累计接入站点:64个(含区/县、镇/街道)
</div>
</el-carousel-item>
<el-carousel-item>
<div class="top-text primary">您好,欢迎使用数据仓库工作台。</div>
</el-carousel-item>
<el-carousel-item>
<div class="top-text primary">
累计接入站点:64个(含区/县、镇/街道)
</div>
</el-carousel-item>
</el-carousel>
</div>
</div>
<div class="bottom-data-show-box flex w-full flex-1 gap-5">
<div class="data-echarts-box w-[30%] rounded-md bg-white">
<div class="b-border flex h-[50px] w-full items-center pl-[20px]">
主题数据分析
</div>
<div class="flex w-full flex-col gap-5 p-[20px]">
<div class="echarts-box">
<LineEchart ref="DataTotalEchart"></LineEchart>
</div>
<div class="echarts-box">
<LineEchart ref="DataQueueUpEchart"></LineEchart>
</div>
<div class="echarts-box">
<LineEchart ref="DataEvaluateEchart"></LineEchart>
</div>
</div>
</div>
<div class="data-area-box flex-1 rounded-md bg-white">
<div class="b-border flex h-[50px] w-full items-center pl-[20px]">
对接站点矩阵
</div>
<div class="w-full p-[20px]"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import LineEchart from "./components/LineEchart.vue";
export default {
components: {
LineEchart,
},
data() {
return {};
},
created() {},
mounted() {
let name = [
"06-1",
"06-2",
"06-3",
"06-4",
"06-5",
"06-6",
"06-7",
"06-8",
"06-9",
"06-10",
"06-11",
"06-12",
"06-13",
"06-14",
"06-15",
"06-16",
"06-17",
"06-18",
"06-19",
"06-20",
];
let data = [
900000, 800000, 700000, 900000, 500000, 900000, 80000, 200000, 100000,
90000, 80000, 70000, 900000, 50000, 40000, 900000, 20000, 10000, 80000,
];
this.$refs.DataTotalEchart.initChart("近30日数据总量趋势", name, data);
this.$refs.DataQueueUpEchart.initChart("近30日数据总量趋势", name, data);
this.$refs.DataEvaluateEchart.initChart("近30日数据总量趋势", name, data);
},
methods: {},
};
</script>
<style lang="less" scoped>
.home {
position: relative;
.b-border {
border-bottom: 1px solid #ccc;
}
}
.main {
height: calc(100% - 50px);
padding: 0px 50px;
position: absolute;
top: 50px;
left: 0px;
.echarts-box {
width: 100%;
height: 180px;
background: #f6fafa;
border-radius: 4px;
}
}
.top-data-total {
background: url("@/assets/img/u54.svg") no-repeat center / 100% 100%;
}
.top-data-text {
background: url("@/assets/img/card_bg_2.png") no-repeat center / 100% 100%;
}
.top-text {
font-size: 24px;
font-weight: 600;
}
:deep(.el-carousel--vertical) {
width: 100%;
}
:deep(.el-statistic) {
.con {
justify-content: flex-start;
}
.suffix {
color: #1890ff;
}
}
</style>
<template>
<div class="h-full w-full" ref="MyEchart"></div>
</template>
<script>
export default {
props: {
endValue: {
type: Number,
default: 6,
},
},
data() {
return {
myChart: null,
timer: null,
};
},
mounted() {},
methods: {
// 适配
adapterEcharts() {
this.myChart && this.myChart.resize();
},
initChart(title = "", dataset) {
let data = dataset.source || [];
let dom = this.$refs.MyEchart;
this.myChart = this.$echarts.init(dom);
let option = {
title: {
text: title,
top: "5%",
textStyle: {
fontSize: 14,
},
},
grid: {
top: "25%",
left: "15%",
right: "5%",
bottom: "12%",
},
// 鼠标移入信息查看
tooltip: {
trigger: "axis",
borderWidth: 0,
},
dataZoom: [
{
// 开启数据平移
type: "inside",
show: true,
startValue: 0,
endValue: this.endValue - 1,
},
],
xAxis: {
type: "category",
boundaryGap: false,
axisLabel: {
textStyle: {
color: "#333",
},
},
axisLine: {
lineStyle: {
color: "#D9D9D9",
},
},
data: names,
},
yAxis: {
type: "value",
splitNumber: 3, // 配置 Y 轴数值间隔
axisLabel: {
textStyle: {
color: "#666",
},
},
nameTextStyle: {
color: "#666",
fontSize: 12,
lineHeight: 40,
},
splitLine: {
lineStyle: {
type: "dashed",
color: "#E9E9E9",
},
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
series: [
{
name: "数据量",
type: "line",
smooth: true,
// showSymbol: false,
symbolSize: 8,
lineStyle: {
color: "rgb(0, 202, 105)",
},
areaStyle: {
color: new this.$echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: "rgba(0, 202, 105,0.3)",
},
{
offset: 1,
color: "rgba(0, 202, 105, 0.1)",
},
],
false
),
shadowBlur: 10,
},
},
],
dataset,
};
this.myChart.setOption(option);
// 适配
window.addEventListener("resize", this.adapterEcharts);
clearInterval(this.timer);
this.timer = setInterval(() => {
if (option.dataZoom[0].endValue >= data.length - 1) {
option.dataZoom[0].endValue = this.endValue - 1;
option.dataZoom[0].startValue = 0;
} else {
option.dataZoom[0].endValue += 1;
option.dataZoom[0].startValue += 1;
}
option && this.myChart.setOption(option);
}, 2000);
//鼠标移入组件时停止轮播
this.myChart.on("mousemove", () => {
clearInterval(this.timer); //清除循环
});
//鼠标移出组件时恢复轮播
this.myChart.on("mouseout", () => {
clearInterval(this.timer); //清除循环
this.timer = setInterval(() => {
if (option.dataZoom[0].endValue >= data.length - 1) {
option.dataZoom[0].endValue = this.endValue - 1;
option.dataZoom[0].startValue = 0;
} else {
option.dataZoom[0].endValue += 1;
option.dataZoom[0].startValue += 1;
}
option && this.myChart.setOption(option);
}, 2000);
});
},
},
beforeDestroy() {
window.removeEventListener("resize", this.adapterEcharts);
clearInterval(this.timer);
},
};
</script>
<style lang="less" scoped></style>
<template>
<div>登录页</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped></style>
<template>
<div>数据集市</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped></style>
<template>
<div>
<div>页面跳转中......</div>
</div>
</template>
<script>
import storage from "@/utils/storage";
import { mapMutations } from "vuex";
export default {
data() {
return {};
},
created() {
this.getToken();
},
methods: {
...mapMutations("user", [
"SET_token",
"SET_sysName",
"SET_sysLogo",
"SET_path",
"SET_userInfo",
]),
// 获取token
getToken() {
let { token, userInfo, siteid, siteName, sysName, sysLogo, path } =
this.$route.query;
if (token && userInfo) {
userInfo = JSON.parse(userInfo);
this.SET_userInfo(userInfo);
this.SET_token(token);
this.SET_sysName(sysName);
this.SET_sysLogo(sysLogo);
this.SET_path(path);
storage.set(2, "siteId", siteid);
storage.set(2, "siteName", siteName);
this.$router.push("/home");
} else {
this.$message.warning("跳转失败,请重新登录");
setTimeout(() => {
location.href = process.env.VUE_APP_API_portal_URL;
}, 2000);
}
},
},
};
</script>
<style lang="less" scoped></style>
<template>
<div>系统设置</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped></style>
import Vue from "vue";
import VueRouter from "vue-router";
import Layouts from "@/layouts/Layouts.vue";
import store from "@/store";
// import local from "@/utils/local";
// 解决重复点击同一个路由报错
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (location) {
return originalPush.call(this, location).catch((err) => err);
};
Vue.use(VueRouter);
/**
* Route 对象配置:
* hidden:控制路由是否显示在在菜单
* hideChildrenInMenu:强制菜单显示为Item而不是SubItem
* meta对象配置:
* title:标题
* keepAlive:缓存该路由
* activeMenu:当前的激活路由
* icon:图标
* hidden:控制路由是否显示在在菜单
*/
const routes = [
{
path: "/",
component: Layouts,
redirect: "/sso",
children: [
{
path: "/home",
hideChildrenInMenu: true,
component: () => import("@/pages/home/Home"),
meta: {
icon: "el-icon-house",
title: "数仓工作台",
},
},
{
path: "/engine",
hideChildrenInMenu: true,
component: () => import("@/pages/engine/Engine"),
meta: {
icon: "el-icon-cpu",
title: "数据引擎",
},
},
{
path: "/market",
hideChildrenInMenu: true,
component: () => import("@/pages/market/Market"),
meta: {
icon: "el-icon-office-building",
title: "数据集市",
},
},
{
path: "/system",
hideChildrenInMenu: true,
component: () => import("@/pages/system/System"),
meta: {
icon: "el-icon-setting",
title: "系统设置",
},
},
],
},
{
path: "/sso",
name: "跳转页",
hidden: true,
component: () => import("@/pages/sso/Sso"),
},
{
path: "/login",
name: "登录页",
hidden: true,
component: () => import("@/pages/login/Login"),
},
];
const router = new VueRouter({
routes,
});
// 前置路由卫士
// router.beforeEach((to, from, next) => {
// let islogin = store.getters["user/token"];
// if (islogin) {
// next();
// } else {
// if (to.path === "/sso") {
// next();
// } else {
// location.href = process.env.VUE_APP_API_portal_URL;
// }
// }
// });
// 过滤菜单
function menusFilter(arr) {
let router = arr.filter((v) => {
if (!v.hidden) {
if (v.children) {
v.children = menusFilter(v.children);
}
return v;
}
});
return router;
}
// 动态菜单
export function calcMenu() {
// dynamicRouter.forEach((v) => {
// router.addRoute(v);
// });
let menus = menusFilter(routes[0].children);
store.commit("user/SET_menus", menus);
}
calcMenu();
export default router;
import Vue from "vue";
import Vuex from "vuex";
import user from "./modules/user";
import createPersistedState from "vuex-persistedstate";
import VuexReset from "@ianwalter/vuex-reset";
import { SessionCrypto } from "@/utils";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {
user,
},
plugins: [
// 重置状态插件
VuexReset(),
// 持久化插件
createPersistedState({
key: "info",
storage: {
getItem: (key) => SessionCrypto.getItem(key),
setItem: (key, value) => SessionCrypto.setItem(key, value),
removeItem: (key) => SessionCrypto.remove(key),
},
}),
],
});
export default {
namespaced: true,
state: {
menus: [], // 菜单
token: "",
siteId: "", // 站点id
deptList: [], // 部门列表
userInfo: {}, // 用户信息
sysName: "", // 系统名称
sysLogo: "", // 系统logo
path: "", // 门户跳转过来的路由
},
getters: {
siteId(state) {
return state.siteId;
},
deptList(state) {
return state.deptList;
},
userInfo(state) {
return state.userInfo;
},
token(state) {
return state.token;
},
path(state) {
return state.path;
},
},
mutations: {
SET_path(state, path) {
state.path = path;
},
SET_menus(state, menus) {
state.menus = menus;
},
SET_siteId(state, siteId) {
state.siteId = siteId;
},
SET_deptList(state, deptList) {
state.deptList = deptList;
},
SET_userInfo(state, userInfo) {
state.userInfo = userInfo;
},
SET_sysName(state, sysName) {
state.sysName = sysName;
},
SET_sysLogo(state, sysLogo) {
state.sysLogo = sysLogo;
},
SET_token(state, token) {
state.token = token;
},
// 重置所有仓库状态
reset: () => {},
},
actions: {},
};
// 导出表格数据
const ExportJsonExcel = require("js-export-excel");
/**
* 导出excel
* @param {导出的表头名信息} tHeader
* @param {导出的表头字段名,需要导出表格字段名} filterVal
* @param {导出数据} list
* @param {导出文件名称} fileName
*/
export const export2Excel = (tHeader, filterVal, list, fileName) => {
let option = {
fileName,
datas: [
{
sheetData: list,
sheetName: "sheet",
sheetFilter: filterVal,
sheetHeader: tHeader,
// columnWidths: columnWidths, // 列宽
},
],
};
let toExcel = new ExportJsonExcel(option);
toExcel.saveExcel(); //保存
};
import CryptoJS from "crypto-js";
// 加密数据
export let encrypt = (str, keyStr, ivStr) => {
keyStr = keyStr ? keyStr : "0000000671595991";
ivStr = ivStr ? ivStr : "tdrdadq59tbss5n7";
//密钥16位
let key = CryptoJS.enc.Utf8.parse(keyStr);
//加密向量16位
let iv = CryptoJS.enc.Utf8.parse(ivStr);
let encrypted = CryptoJS.AES.encrypt(str, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString();
};
// 解密
export const decrypt = (word, keyStr, ivStr) => {
keyStr = keyStr ? keyStr : "0000000671595991";
ivStr = ivStr ? ivStr : "tdrdadq59tbss5n7";
let key = CryptoJS.enc.Utf8.parse(keyStr);
let iv = CryptoJS.enc.Utf8.parse(ivStr);
let decrypt = CryptoJS.AES.decrypt(word, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypt.toString(CryptoJS.enc.Utf8);
};
/**
* 加密存储临时数据并解析对象
*/
const aseKey = "**_FXxx_1234_KEY";
const KEY = "KEY_EXTRA";
export class SessionCrypto {
// 加密
static setItem(key = KEY, value = "") {
if (typeof key === "string") {
const stringify = JSON.stringify(value);
const encrypt = CryptoJS.AES.encrypt(
stringify,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString();
window.sessionStorage.setItem(key, encrypt);
return encrypt;
}
}
// 解密
static getItem(key = KEY) {
const ssStr = window.sessionStorage.getItem(key) || "";
try {
if (ssStr) {
const decrypt = CryptoJS.AES.decrypt(
ssStr,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString(CryptoJS.enc.Utf8);
const parseStr = JSON.parse(decrypt);
return parseStr;
}
return "";
} catch (e) {
return "";
}
}
// 删除
static remove(key) {
window.sessionStorage.removeItem(key);
}
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
}
/**
* 对象数组去重
* @param {数组} arr
* @param {判断字段} field
*/
export function uniqueFunc(arr, field) {
const res = new Map();
return arr.filter((item) => !res.has(item[field]) && res.set(item[field], 1));
}
/**
* axios 工具函数层
*/
import axios from "axios";
import router from "@/router";
import store from "@/store";
import { message } from "@/utils/resetMessage";
// 加载条插件
import NProgress from "nprogress";
// 请求超时时间
axios.defaults.timeout = 60 * 1000;
// 设置统一服务器地址
axios.defaults.baseURL = process.env.VUE_APP_API_BASE_URL;
// 请求拦截
axios.interceptors.request.use(
(config) => {
let token = store.getters["user/token"];
if (token) {
config.headers.Authorization = token;
}
NProgress.start();
return config;
},
(err) => {
return Promise.reject(err);
}
);
// 响应拦截
axios.interceptors.response.use(
(response) => {
if (response.data.code !== undefined && response.data.msg !== undefined) {
// 取出数据
let { code, msg } = response.data;
if (code === -1) {
message.error({
content: msg,
maxCount: 1,
duration: 1,
});
if (msg === "非法用户,不可访问") {
store.commit("user/reset");
router.push("/");
}
} else if (code === 401 || code === 201 || code == 9001 || code == 9002) {
message.error({
content: msg,
maxCount: 1,
duration: 1,
});
store.commit("user/reset");
setTimeout(() => {
location.href = process.env.VUE_APP_API_portal_URL;
}, 2000);
}
}
NProgress.done();
return response;
},
(error) => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = "错误请求";
break;
case 403:
error.message = "拒绝访问";
break;
case 404:
error.message = "请求错误,未找到该资源";
break;
case 405:
error.message = "请求方法未允许";
break;
case 408:
error.message = "请求超时";
break;
case 500:
error.message = "服务器端出错";
break;
case 501:
error.message = "网络未实现";
break;
case 502:
error.message = "网络错误";
break;
case 503:
error.message = "服务不可用";
break;
case 504:
error.message = "网络超时";
break;
case 505:
error.message = "http版本不支持该请求";
break;
default:
error.message = `连接错误${error.response.status}`;
}
} else {
if (JSON.stringify(error).includes("timeout")) {
error.message = "服务器响应超时,请刷新当前页";
} else {
error.message = "连接服务器失败";
}
}
message.error({
message: error.message,
maxCount: 1,
duration: 1,
});
return Promise.resolve(error.response);
}
);
export default axios;
//防止element点击多次弹出message弹框
//创建一个js文件将此内容放入即可
import { Message } from "element-ui";
let messageval = null;
const Messages = (opt) => {
if (messageval) {
// 如果已经有一个message
messageval.close(); // 将上一个关闭
}
messageval = Message(opt);
};
["error", "success", "info", "warning"].forEach((type) => {
// 判断弹窗类型
Messages[type] = (opt) => {
if (typeof opt === "string") {
opt = {
message: opt,
duration: 1000,
};
}
opt.type = type;
return Messages(opt);
};
});
export const message = Messages;
/*
Storage本地储存
*/
export default {
set(type, key, value) {
if (type == 1) {
sessionStorage.setItem(key, JSON.stringify(value));
} else {
localStorage.setItem(key, JSON.stringify(value));
}
},
get(type, key) {
if (type == 1) {
return JSON.parse(sessionStorage.getItem(key));
} else {
return JSON.parse(localStorage.getItem(key));
}
},
remove(type, key) {
if (type == 1) {
sessionStorage.removeItem(key);
} else {
localStorage.removeItem(key);
}
},
clear(type) {
if (type == 1) {
sessionStorage.clear();
} else {
localStorage.clear();
}
},
};
// 只能为数字验证
export function isNumber(rule, value, callback) {
var number = /^\d+$/;
if (!number.test(value)) {
callback(new Error("格式有误,只能为数字"));
} else {
callback();
}
}
// 验证流水编号
export const checkFlowNum = (rule, value, callback) => {
let reg = /^[A-Z][a-zA-Z0-9]{3,32}$/;
if (!value) {
callback(new Error("请输入流水编号"));
} else if (!reg.test(value)) {
callback(new Error("格式为大写字母开头,4~32位"));
} else {
callback();
}
};
// 验证英文
export const checkEn = (rule, value, callback) => {
let reg = /^[a-zA-Z]{2,15}$/;
if (!value) {
callback(new Error("请输入英文名称"));
} else if (!reg.test(value)) {
callback(new Error("格式为字母a-z,A-Z,2~15位"));
} else {
callback();
}
};
// 验证账号
export const changeAccount = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入用户名"));
} else if (!/^[a-zA-Z0-9_-]{4,16}$/.test(value)) {
callback(new Error("4到16位(字母,数字,下划线,中横线)"));
} else {
callback();
}
};
// 验证密码
export const changePassWord = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入密码"));
} else if (
!/^\S*(?=\S{8,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*()_+{}|:;<>,.?~])\S*$/.test(
value
)
) {
callback(
new Error(
"最少8位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符"
)
);
} else {
callback();
}
};
// 验证手机号码
export const changePhone = (rule, value, callback) => {
if (!value) {
// callback(new Error("请输入手机号"));
callback();
} else if (!/^1[3-9]\d{9}$/.test(value)) {
callback(new Error("手机号码格式不正确"));
} else {
callback();
}
};
// 验证座机号码
export const changeLandline = (rule, value, callback) => {
if (!value) {
// callback(new Error("请输入座机号"));
callback();
} else if (!/^[0][1-9]{2,3}-[0-9]{5,10}$/.test(value)) {
callback(new Error("区号-电话号码"));
} else {
callback();
}
};
// 窗口编号验证(字母加数字 数字不能大于1000)
export const changeWindowNumber = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入窗口编号"));
callback();
} else if (!/^[a-zA-Z]+\d{1,3}$/.test(value)) {
callback(new Error("字母+数字,数字不能大于999"));
} else {
callback();
}
};
// 校验编码
export const changeCodeNumber = (rule, value, callback) => {
let reg = /^[a-zA-Z\d]{2,30}$/;
if (!value) {
callback(new Error("请输入编码"));
} else if (!reg.test(value)) {
callback(new Error("格式:数字,字母2至30位"));
} else {
callback();
}
};
/** @type {import('tailwindcss').Config} */
module.exports = {
// prefix: "p-",
content: ["./public/index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
proxy: {
"/file": {
target: process.env.VUE_APP_API_BASE_URL,
changeOrigin: true,
// pathRewrite:{
// "^/file": "",
// }
},
},
},
});
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment