前后端全面升级

This commit is contained in:
pycook
2023-07-10 17:42:15 +08:00
parent c444fed436
commit db5ff60aff
629 changed files with 97789 additions and 23995 deletions

View File

@@ -1,3 +1,5 @@
NODE_ENV=production
VUE_APP_PREVIEW=false
VUE_APP_API_BASE_URL=http://127.0.0.1:5000/api
VUE_APP_API_BASE_URL=/api
VUE_APP_BUILD_PACKAGES="ticket,calendar,acl"
VUE_APP_IS_OUTER=true

View File

@@ -1,3 +1,3 @@
NODE_ENV=production
VUE_APP_PREVIEW=true
VUE_APP_API_BASE_URL=http://127.0.0.1:5001/api
VUE_APP_API_BASE_URL=/api

2
cmdb-ui/.eslintignore Normal file
View File

@@ -0,0 +1,2 @@
/public/iconfont
/src/modules/cmdb/3rd

View File

@@ -8,7 +8,10 @@ module.exports = {
'@vue/standard'
],
rules: {
'no-unused-vars': 'warn',
'space-before-function-paren': 0,
'no-console': 'off',
'comma-dangle': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'generator-star-spacing': 'off',
'no-mixed-operators': 0,
@@ -31,6 +34,7 @@ module.exports = {
'vue/multiline-html-element-content-newline': 0,
'vue/no-use-v-if-with-v-for': 0,
'vue/html-closing-bracket-newline': 0,
'vue/prop-name-casing': 0,
'vue/no-parsing-error': 0,
'no-tabs': 0,
'quotes': [
@@ -56,7 +60,8 @@ module.exports = {
}
],
'template-curly-spacing': 'off',
'indent': 'off'
'indent': 'off',
'camelcase': 'off'
},
parserOptions: {
parser: 'babel-eslint'
@@ -65,7 +70,8 @@ module.exports = {
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)'
'**/tests/unit/**/*.spec.{j,t}s?(x)',
'**/src/components/**'
],
env: {
jest: true

1
cmdb-ui/.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
public/* linguist-vendored

26
cmdb-ui/.gitignore vendored Normal file
View File

@@ -0,0 +1,26 @@
.DS_Store
node_modules
/dist
/dist.zip
/temp
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
*.css.map
.env.development

View File

@@ -1,5 +1,6 @@
{
"printWidth": 120,
"semi": false,
"singleQuote": true
"singleQuote": true,
"trailingComma": "es5"
}

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Anan Yang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

11
cmdb-ui/README.zh-CN.md Normal file
View File

@@ -0,0 +1,11 @@
#Oneops-UI
```shell
## build
yarn run build
## develop
yarn run serve
```

View File

@@ -1,25 +1,28 @@
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV)
const plugins = ['@babel/plugin-syntax-import-meta', '@babel/plugin-proposal-optional-chaining', '@babel/plugin-proposal-nullish-coalescing-operator']
if (IS_PROD) {
plugins.push('transform-remove-console')
}
// lazy load ant-design-vue
// if your use import on Demand, Use this code
// plugins.push(['import', {
// 'libraryName': 'ant-design-vue',
// 'libraryDirectory': 'es',
// 'style': true // `style: true` 会加载 less 文件
// }])
module.exports = {
presets: [
'@vue/app',
'@vue/cli-plugin-babel/preset',
[
'@babel/preset-env',
{
'useBuiltIns': 'usage', // "usage" | "entry" | false, defaults to false.
'corejs': '3.1.2',
'targets': {
'esmodules': true,
'ie': '11'
}
'useBuiltIns': 'entry',
'corejs': 3
}
]
]
// if your use import on Demand, Use this code
// ,
// plugins: [
// [ 'import', {
// 'libraryName': 'ant-design-vue',
// 'libraryDirectory': 'es',
// 'style': true // `style: true` 会加载 less 文件
// } ]
// ]
],
plugins
}

View File

@@ -0,0 +1,46 @@
const ThemeColorReplacer = require('webpack-theme-color-replacer')
const generate = require('@ant-design/colors/lib/generate').default
const getAntdSerials = (color) => {
// 淡化即less的tint
const lightens = new Array(9).fill().map((t, i) => {
return ThemeColorReplacer.varyColor.lighten(color, i / 10)
})
const colorPalettes = generate(color)
const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',')
return lightens.concat(colorPalettes).concat(rgb)
}
const themePluginOption = {
fileName: 'css/theme-colors-[contenthash:8].css',
matchColors: getAntdSerials('#1890ff'), // 主色系列
// 改变样式选择器解决样式覆盖问题
changeSelector (selector) {
switch (selector) {
case '.ant-calendar-today .ant-calendar-date':
return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector
case '.ant-btn:focus,.ant-btn:hover':
return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)'
case '.ant-btn.active,.ant-btn:active':
return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)'
case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon':
return ':not(.ant-steps-item-process)' + selector
case '.ant-menu-horizontal>.ant-menu-item-active,.ant-menu-horizontal>.ant-menu-item-open,.ant-menu-horizontal>.ant-menu-item-selected,.ant-menu-horizontal>.ant-menu-item:hover,.ant-menu-horizontal>.ant-menu-submenu-active,.ant-menu-horizontal>.ant-menu-submenu-open,.ant-menu-horizontal>.ant-menu-submenu-selected,.ant-menu-horizontal>.ant-menu-submenu:hover':
case '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal > .ant-menu-submenu-selected,.ant-menu-horizontal > .ant-menu-submenu:hover':
return '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover'
case '.ant-menu-horizontal > .ant-menu-item-selected > a':
case '.ant-menu-horizontal>.ant-menu-item-selected>a':
return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a'
case '.ant-menu-horizontal > .ant-menu-item > a:hover':
case '.ant-menu-horizontal>.ant-menu-item>a:hover':
return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover'
default :
return selector
}
}
}
const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption)
module.exports = createThemeColorReplacerPlugin

View File

@@ -7,5 +7,5 @@
}
},
"exclude": ["node_modules", "dist"],
"include": ["src/**/*"]
"include": ["src/*"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "vue-antd-pro",
"version": "3.0.0",
"name": "oneops",
"version": "0.0.9",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -8,144 +8,76 @@
"build:preview": "vue-cli-service build --mode preview",
"lint": "vue-cli-service lint",
"lint:nofix": "vue-cli-service lint --no-fix",
"test:unit": "vue-cli-service test:unit",
"postinstall": "opencollective-postinstall"
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"@handsontable-pro/vue": "^3.1.1",
"@handsontable/vue": "^4.1.1",
"ant-design-vue": "^1.6.2",
"axios": "^0.19.0",
"core-js": "^3.1.2",
"enquire.js": "^2.1.6",
"handsontable": "^7.2.2",
"handsontable-pro": "^6.2.3",
"http-proxy": "^1.18.1",
"@antv/data-set": "^0.11.8",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/plugin-proposal-optional-chaining": "^7.18.9",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@riophae/vue-treeselect": "^0.4.0",
"@vue/composition-api": "^1.7.1",
"ant-design-vue": "^1.6.5",
"axios": "0.18.0",
"babel-eslint": "^8.2.2",
"butterfly-dag": "^4.3.26",
"codemirror": "^5.65.13",
"core-js": "^3.31.0",
"echarts": "^5.3.2",
"element-ui": "^2.15.10",
"exceljs": "^4.3.0",
"html2canvas": "^1.0.0-rc.5",
"is-buffer": "^2.0.5",
"jquery": "^3.6.0",
"js-cookie": "^2.2.0",
"json2csv": "^4.5.2",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"moment": "^2.24.0",
"node-fetch": "^2.6.1",
"node-forge": "^0.10.0",
"nprogress": "^0.2.0",
"serialize-javascript": "^3.1.0",
"vis-network": "^6.4.4",
"viser-vue": "^2.3.3",
"vue": "^2.6.10",
"vue-clipboard2": "^0.2.1",
"vue-cropper": "0.4.9",
"vue-i18n": "^8.15.3",
"vue-json-excel": "^0.2.98",
"relation-graph": "^1.1.0",
"sortablejs": "1.9.0",
"viser-vue": "^2.4.8",
"vue": "2.6.11",
"vue-clipboard2": "^0.3.3",
"vue-codemirror": "^4.0.6",
"vue-cropper": "^0.6.2",
"vue-grid-layout": "2.3.12",
"vue-infinite-scroll": "^2.0.2",
"vue-json-editor": "^1.4.3",
"vue-ls": "^3.2.1",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.1.2",
"vue-svg-component-runtime": "^1.0.1",
"vue-template-compiler": "2.6.11",
"vuedraggable": "^2.23.0",
"vuex": "^3.1.2",
"wangeditor": "^3.1.1",
"xlsx": "latest",
"yarn": "^1.22.0"
"vuex": "^3.1.1",
"vxe-table": "3.6.9",
"vxe-table-plugin-export-xlsx": "^3.0.4",
"xe-utils": "3",
"xlsx": "0.15.0",
"xlsx-js-style": "^1.2.0"
},
"devDependencies": {
"@ant-design/colors": "^3.2.1",
"@vue/cli-plugin-babel": "^4.0.4",
"@vue/cli-plugin-eslint": "^4.0.4",
"@vue/cli-plugin-router": "^4.0.4",
"@vue/cli-plugin-unit-jest": "^4.0.4",
"@vue/cli-plugin-vuex": "^4.0.4",
"@vue/cli-service": "^4.0.4",
"@ant-design/colors": "^3.2.2",
"@babel/polyfill": "^7.2.5",
"@vue/cli-plugin-babel": "4.5.17",
"@vue/cli-plugin-eslint": "^4.0.5",
"@vue/cli-plugin-unit-jest": "^4.0.5",
"@vue/cli-service": "^4.0.5",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-eslint": "^10.0.1",
"babel-plugin-import": "^1.12.2",
"@vue/test-utils": "^1.0.0-beta.30",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^23.6.0",
"babel-plugin-import": "^1.11.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "^5.16.0",
"eslint": "^5.8.0",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-vue": "^5.2.3",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"eslint-plugin-vue": "^5.0.0",
"less": "^3.8.1",
"less-loader": "^4.1.0",
"true-case-path": "^2.2.1",
"vue-svg-icon-loader": "^2.1.1",
"vue-template-compiler": "^2.6.10",
"webpack-theme-color-replacer": "^1.2.17"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/strongly-recommended",
"@vue/standard"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {
"generator-star-spacing": "off",
"no-mixed-operators": 0,
"vue/max-attributes-per-line": [
2,
{
"singleline": 5,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}
],
"vue/attribute-hyphenation": 0,
"vue/html-self-closing": 0,
"vue/component-name-in-template-casing": 0,
"vue/html-closing-bracket-spacing": 0,
"vue/singleline-html-element-content-newline": 0,
"vue/no-unused-components": 0,
"vue/multiline-html-element-content-newline": 0,
"vue/no-use-v-if-with-v-for": 0,
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-console": 0,
"no-tabs": 0,
"quotes": [
2,
"single",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
],
"semi": [
2,
"never",
{
"beforeStatementContinuationChars": "never"
}
],
"no-delete-var": 2,
"prefer-const": [
2,
{
"ignoreReadBeforeAssign": false
}
]
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"collective": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design-pro-vue"
}
}

View File

@@ -0,0 +1,5 @@
module.exports = {
plugins: {
autoprefixer: {}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 KiB

View File

@@ -1721,7 +1721,7 @@ this.tinycolor = tinycolor;
// Layout
@layout-body-background : #f0f2f5;
@layout-header-background : #001529;
@layout-header-background : #012970;
@layout-footer-background : @layout-body-background;
@layout-header-height : 64px;
@layout-header-padding : 0 50px;
@@ -2365,7 +2365,7 @@ i.trigger:hover {
border-right-color: transparent;
}
:global .drawer .drawer-content {
background: #001529;
background: #012970;
}
.standardFormRow {
border-bottom: 1px dashed #e8e8e8;
@@ -4538,7 +4538,7 @@ li.ant-calendar-time-picker-select-option-disabled:hover {
}
.ant-dropdown-menu-dark,
.ant-dropdown-menu-dark .ant-dropdown-menu {
background: #001529;
background: #012970;
}
.ant-dropdown-menu-dark .ant-dropdown-menu-item,
.ant-dropdown-menu-dark .ant-dropdown-menu-submenu-title,
@@ -5096,21 +5096,21 @@ form .ant-upload {
background: #f0f2f5;
}
.ant-layout-header {
background: #001529;
background: #012970;
}
.ant-layout-footer {
background: #f0f2f5;
color: rgba(0, 0, 0, 0.65);
}
.ant-layout-sider {
background: #001529;
background: #012970;
}
.ant-layout-sider-trigger {
color: #fff;
background: #002140;
}
.ant-layout-sider-zero-width-trigger {
background: #001529;
background: #012970;
color: #fff;
border-radius: 0 4px 4px 0;
}
@@ -5455,7 +5455,7 @@ form .ant-upload {
.ant-menu-dark,
.ant-menu-dark .ant-menu-sub {
color: rgba(255, 255, 255, 0.65);
background: #001529;
background: #012970;
}
.ant-menu-dark .ant-menu-submenu-title .ant-menu-submenu-arrow:after,
.ant-menu-dark .ant-menu-sub .ant-menu-submenu-title .ant-menu-submenu-arrow:after,
@@ -5475,7 +5475,7 @@ form .ant-upload {
}
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item,
.ant-menu-dark.ant-menu-horizontal > .ant-menu-submenu {
border-color: #001529;
border-color: #012970;
border-bottom: 0;
}
.ant-menu-dark .ant-menu-item,
@@ -7657,7 +7657,7 @@ li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper:hover {
}
.drawer .drawer-content {
background: #001529;
background: #012970;
}
.ant-list-item-meta .taobao {

View File

@@ -0,0 +1,539 @@
/* 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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,11 +1,28 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>CMDB</title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<title>OneOps</title>
<style>#loading-mask{position:fixed;left:0;top:0;height:100%;width:100%;background:#fff;user-select:none;z-index:9999;overflow:hidden}.loading-wrapper{position:absolute;top:50%;left:50%;transform:translate(-50%,-100%)}.loading-dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:64px;width:64px;height:64px;box-sizing:border-box}.loading-dot i{width:22px;height:22px;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}.loading-dot i:nth-child(1){top:0;left:0}.loading-dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.loading-dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.loading-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>
<!-- require cdn assets css -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
<% } %>
<script>
  const userAgent = navigator.userAgent
const isEdge = userAgent.indexOf("Edge") > -1
  const isChrome = userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1 && !isEdge
  if (!isChrome) {
alert("推荐使用Chrome浏览器 其他环境下未做严格测试!")
}
</script>
</head>
<body>
<noscript>
@@ -18,6 +35,11 @@
</div>
</div>
</div>
<!-- require cdn assets js -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<script src="http://wwcdn.weixin.qq.com/node/wework/wwopen/js/wwLogin-1.2.7.js"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>

BIN
cmdb-ui/public/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,46 +1,70 @@
<template>
<a-config-provider :locale="locale">
<div id="app">
<div id="app" :class="{ 'ops-fullscreen': isOpsFullScreen, 'ops-only-topmenu': isOpsOnlyTopMenu }">
<router-view v-if="alive" />
</div>
</a-config-provider>
</template>
<script>
import i18n from '@/locales'
import { mapActions } from 'vuex'
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import { AppDeviceEnquire } from '@/utils/mixin'
import { mixin } from '@/store/i18n-mixin'
import { debounce } from './utils/util'
export default {
mixins: [AppDeviceEnquire, mixin],
provide () {
mixins: [AppDeviceEnquire],
provide() {
return {
reload: this.reload
reload: this.reload,
}
},
data () {
data() {
return {
locale: {},
alive: true
locale: zhCN,
alive: true,
timer: null,
}
},
created () {
this.$watch('currentLang', () => {
this.locale = i18n.getLocaleMessage(this.currentLang).antLocale
})
computed: {
isOpsFullScreen() {
return this.$route.name === 'cmdb_screen'
},
isOpsOnlyTopMenu() {
return ['fullscreen_index', 'setting_person'].includes(this.$route.name)
},
},
created() {
this.timer = setInterval(() => {
this.setTime(new Date().getTime())
}, 1000)
},
mounted() {
this.$store.dispatch('setWindowSize')
window.addEventListener(
'resize',
debounce(() => {
this.$store.dispatch('setWindowSize')
})
)
},
beforeDestroy() {
clearInterval(this.timer)
},
methods: {
reload () {
...mapActions(['setTime']),
reload() {
this.alive = false
this.$nextTick(() => {
this.alive = true
})
}
}
},
},
}
</script>
<style>
<style lang="less">
@import './style/index.less';
#app {
height: 100%;
}

View File

@@ -1,34 +0,0 @@
import { axios } from '@/utils/request'
const urlPrefix = '/v1/acl'
export function searchRole (params) {
return axios({
url: urlPrefix + `/roles`,
method: 'GET',
params: params
})
}
export function addRole (params) {
return axios({
url: urlPrefix + '/roles',
method: 'POST',
data: params
})
}
export function updateRoleById (id, params) {
return axios({
url: urlPrefix + `/roles/${id}`,
method: 'PUT',
data: params
})
}
export function deleteRoleById (id) {
return axios({
url: urlPrefix + `/roles/${id}`,
method: 'DELETE'
})
}

View File

@@ -1,56 +0,0 @@
import { axios } from '@/utils/request'
const urlPrefix = '/v1/acl'
export function getResourcePerms (resourceID) {
return axios({
url: urlPrefix + `/resources/${resourceID}/permissions`,
method: 'GET'
})
}
export function getResourceTypePerms (typeID) {
return axios({
url: urlPrefix + `/resource_types/${typeID}/perms`,
method: 'GET'
})
}
export function getResourceGroupPerms (resourceGroupID) {
return axios({
url: urlPrefix + `/resource_groups/${resourceGroupID}/permissions`,
method: 'GET'
})
}
export function setRoleResourcePerm (rid, resourceID, params) {
return axios({
url: urlPrefix + `/roles/${rid}/resources/${resourceID}/grant`,
method: 'POST',
data: params
})
}
export function setRoleResourceGroupPerm (rid, resourceGroupID, params) {
return axios({
url: urlPrefix + `/roles/${rid}/resource_groups/${resourceGroupID}/grant`,
method: 'POST',
data: params
})
}
export function deleteRoleResourcePerm (rid, resourceID, params) {
return axios({
url: urlPrefix + `/roles/${rid}/resources/${resourceID}/revoke`,
method: 'POST',
data: params
})
}
export function deleteRoleResourceGroupPerm (rid, resourceGroupID, params) {
return axios({
url: urlPrefix + `/roles/${rid}/resource_groups/${resourceGroupID}/revoke`,
method: 'POST',
data: params
})
}

View File

@@ -1,66 +0,0 @@
import { axios } from '@/utils/request'
const urlPrefix = '/v1/acl'
export function searchRole (params) {
return axios({
url: urlPrefix + `/roles`,
method: 'GET',
params: params
})
}
export function addRole (params) {
return axios({
url: urlPrefix + '/roles',
method: 'POST',
data: params
})
}
export function updateRoleById (id, params) {
return axios({
url: urlPrefix + `/roles/${id}`,
method: 'PUT',
data: params
})
}
export function deleteRoleById (id) {
return axios({
url: urlPrefix + `/roles/${id}`,
method: 'DELETE'
})
}
export function addParentRole (id, otherID) {
return axios({
url: urlPrefix + `/roles/${id}/parents`,
method: 'POST',
data: { parent_id: otherID }
})
}
export function addChildRole (id, otherID) {
return axios({
url: urlPrefix + `/roles/${otherID}/parents`,
method: 'POST',
data: { parent_id: id }
})
}
export function delParentRole (cid, pid) {
return axios({
url: urlPrefix + `/roles/${cid}/parents`,
method: 'DELETE',
data: { parent_id: pid }
})
}
export function delChildRole (pid, cid) {
return axios({
url: urlPrefix + `/roles/${cid}/parents`,
method: 'DELETE',
data: { parent_id: pid }
})
}

View File

@@ -1,38 +0,0 @@
import { axios } from '@/utils/request'
export function getFirstCIs (ciId) {
return axios({
url: '/v0.1/ci_relations/' + ciId + '/first_cis',
method: 'GET'
})
}
export function getSecondCIs (ciId) {
return axios({
url: '/v0.1/ci_relations/' + ciId + '/second_cis',
method: 'GET'
})
}
export function searchCIRelation (params) {
return axios({
url: `/v0.1/ci_relations/s?${params}`,
method: 'GET'
})
}
export function statisticsCIRelation (params) {
return axios({
url: '/v0.1/ci_relations/statistics',
method: 'GET',
params: params
})
}
export function batchUpdateCIRelation (ciIds, parents) {
return axios({
url: '/v0.1/ci_relations/batch',
method: 'POST',
data: { ci_ids: ciIds, parents: parents }
})
}

View File

@@ -1,123 +0,0 @@
import { axios } from '@/utils/request'
/**
* get all CI Type
* @param parameter
* @returns {AxiosPromise}
*/
export function getCITypes (parameter) {
return axios({
url: '/v0.1/ci_types',
method: 'GET',
params: parameter
})
}
/**
* get a CI Type
* @param CITypeName
* @param parameter
* @returns {AxiosPromise}
*/
export function getCIType (CITypeName, parameter) {
return axios({
url: `/v0.1/ci_types/${CITypeName}`,
method: 'GET',
params: parameter
})
}
/**
* Create CI Type
* @param data
* @returns {AxiosPromise}
*/
export function createCIType (data) {
return axios({
url: '/v0.1/ci_types',
method: 'POST',
data: data
})
}
/**
* Update CI Type
* @param CITypeId
* @param data
* @returns {AxiosPromise}
*/
export function updateCIType (CITypeId, data) {
return axios({
url: `/v0.1/ci_types/${CITypeId}`,
method: 'PUT',
data: data
})
}
/**
* Delete CI Type
* @param CITypeId
* @returns {AxiosPromise}
*/
export function deleteCIType (CITypeId) {
return axios({
url: `/v0.1/ci_types/${CITypeId}`,
method: 'DELETE'
})
}
/**
* Gets a grouping of a CI Type
* @param CITypeId
* @param data
* @returns {AxiosPromise}
*/
export function getCITypeGroupById (CITypeId, data) {
return axios({
url: `/v0.1/ci_types/${CITypeId}/attribute_groups`,
method: 'GET',
params: data
})
}
/**
* Save a group of CI Type
* @param CITypeId
* @param data
* @returns {AxiosPromise}
*/
export function createCITypeGroupById (CITypeId, data) {
return axios({
url: `/v0.1/ci_types/${CITypeId}/attribute_groups`,
method: 'POST',
data: data
})
}
/**
* Changes the grouping of a CI Type
* @param groupId
* @param data
* @returns {AxiosPromise}
*/
export function updateCITypeGroupById (groupId, data) {
return axios({
url: `/v0.1/ci_types/attribute_groups/${groupId}`,
method: 'PUT',
data: data
})
}
/**
* Removes a group for a CI Type
* @param groupId
* @param data
* @returns {AxiosPromise}
*/
export function deleteCITypeGroupById (groupId, data) {
return axios({
url: `/v0.1/ci_types/attribute_groups/${groupId}`,
method: 'delete',
data: data
})
}

View File

@@ -1,39 +0,0 @@
import { axios } from '@/utils/request'
export function getCITypeChildren (CITypeID, parameter) {
return axios({
url: '/v0.1/ci_type_relations/' + CITypeID + '/children',
method: 'GET',
params: parameter
})
}
export function getCITypeParent (CITypeID) {
return axios({
url: '/v0.1/ci_type_relations/' + CITypeID + '/parents',
method: 'GET'
})
}
export function getCITypeRelations () {
return axios({
url: '/v0.1/ci_type_relations',
method: 'GET'
})
}
export function createRelation (parentId, childrenId, relationTypeId) {
return axios({
url: `/v0.1/ci_type_relations/${parentId}/${childrenId}`,
method: 'POST',
data: { relation_type_id: relationTypeId }
})
}
export function deleteRelation (parentId, childrenId) {
return axios({
url: `/v0.1/ci_type_relations/${parentId}/${childrenId}`,
method: 'DELETE'
})
}

View File

@@ -1,41 +0,0 @@
import { axios } from '@/utils/request'
const urlPrefix = '/v0.1'
export function searchCI (params) {
return axios({
url: urlPrefix + `/ci/s?${params}`,
method: 'GET'
})
}
export function addCI (params) {
return axios({
url: urlPrefix + '/ci',
method: 'POST',
data: params
})
}
export function updateCI (id, params) {
return axios({
url: urlPrefix + `/ci/${id}`,
method: 'PUT',
data: params
})
}
export function deleteCI (ciId) {
return axios({
url: urlPrefix + `/ci/${ciId}`,
method: 'DELETE'
})
}
// Get a single CI instance
export function getCIById (ciId) {
return axios({
url: urlPrefix + `/ci/${ciId}`,
method: 'GET'
})
}

View File

@@ -1,8 +0,0 @@
import { axios } from '@/utils/request'
export function getCIHistory (ciId) {
return axios({
url: `/v0.1/history/ci/${ciId}`,
method: 'GET'
})
}

View File

@@ -1,64 +0,0 @@
import { axios } from '@/utils/request'
export function getPreference (instance = true, tree = null) {
return axios({
url: '/v0.1/preference/ci_types',
method: 'GET',
params: { instance: instance, tree: tree }
})
}
export function getSubscribeAttributes (ciTypeId) {
return axios({
url: `/v0.1/preference/ci_types/${ciTypeId}/attributes`,
method: 'GET'
})
}
export function getSubscribeTreeView () {
return axios({
url: '/v0.1/preference/tree/view',
method: 'GET'
})
}
export function subscribeCIType (ciTypeId, attrs) {
return axios({
url: `/v0.1/preference/ci_types/${ciTypeId}/attributes`,
method: 'POST',
data: {
attr: attrs
}
})
}
export function subscribeTreeView (ciTypeId, levels) {
return axios({
url: `/v0.1/preference/tree/view`,
method: 'POST',
data: { type_id: ciTypeId, levels: levels }
})
}
export function getRelationView () {
return axios({
url: `/v0.1/preference/relation/view`,
method: 'GET'
})
}
export function deleteRelationView (viewName) {
return axios({
url: `/v0.1/preference/relation/view`,
method: 'DELETE',
data: { name: viewName }
})
}
export function subscribeRelationView (payload) {
return axios({
url: `/v0.1/preference/relation/view`,
method: 'POST',
data: payload
})
}

View File

@@ -0,0 +1,97 @@
import { axios } from '@/utils/request'
export function getCompanyInfo() {
return axios({
url: '/common-setting/v1/company/info',
method: 'get',
})
}
export function postCompanyInfo(parameter) {
return axios({
url: '/common-setting/v1/company/info',
method: 'post',
data: parameter,
})
}
export function putCompanyInfo(id, parameter) {
return axios({
url: `/common-setting/v1/company/info/${id}`,
method: 'put',
data: parameter,
})
}
export function postImageFile(parameter) {
return axios({
url: '/common-setting/v1/file',
method: 'post',
data: parameter,
})
}
export function getDepartmentList(params) {
// ?department_parent_id=-1 查询第一级部门下面的id根据实际的传
return axios({
url: '/common-setting/v1/department',
method: 'get',
params: params
})
}
export function getAllDepartmentList(params) { // is_tree
return axios({
url: '/common-setting/v1/department/all',
method: 'get',
params: params
})
}
export function postDepartment(departmentData) {
// 创建部门参数
// department_name
// department_director_id 部门负责人ID, 默认 0
// department_parent_id 上级部门ID 默认0 不为0时必须是已存在的部门ID
return axios({
url: '/common-setting/v1/department',
method: 'post',
data: departmentData,
})
}
export function putDepartmentById(department_id, departmentData) {
// 修改部门参数departmentData
// department_name
// department_director_id 部门负责人ID, 默认 0
// department_parent_id 上级部门ID 默认0 不为0时必须是已存在的部门ID
return axios({
url: `/common-setting/v1/department/${department_id}`,
method: 'put',
data: departmentData,
})
}
export function deleteDepartmentById(department_id) {
return axios({
url: `/common-setting/v1/department/${department_id}`,
method: 'delete',
})
}
export function getParentDepartmentList(department_id) {
return axios({
url: '/common-setting/v1/department/allow_parent',
method: 'get',
params: department_id,
})
}
// 获取全部部门和员工的树状结构
export function getAllDepAndEmployee(params) {
return axios({
url: '/common-setting/v1/department/all_with_employee',
method: 'get',
params
})
}
// 更新部门排序
export function updateDepartmentsSort(data) {
return axios({
url: '/common-setting/v1/department/update_sort',
method: 'put',
data
})
}

119
cmdb-ui/src/api/employee.js Normal file
View File

@@ -0,0 +1,119 @@
import { axios } from '@/utils/request'
export function getEmployeeList(params) {
return axios({
url: '/common-setting/v1/employee',
method: 'get',
params: params,
})
}
// export function getEmployeeList(params, orderBy) {
// return axios({
// url: '/common-setting/v1/employee' + '/' + orderBy,
// method: 'get',
// params: params,
// })
// }
export function postEmployee(data) {
return axios({
url: '/common-setting/v1/employee',
method: 'post',
data: data,
})
}
export function getEmployeeCount(params) {
return axios({
url: '/common-setting/v1/employee/count',
method: 'get',
params: params,
})
}
export function deleteEmployee(_id) {
return axios({
url: `/common-setting/v1/employee/${_id}`,
method: 'delete',
})
}
export function putEmployee(_id, data) {
return axios({
url: `/common-setting/v1/employee/${_id}`,
method: 'put',
data: data,
})
}
export function batchEditEmployee(data) {
return axios({
url: '/common-setting/v1/employee/batch',
method: 'post',
data: data,
})
}
export function importEmployee(data) {
return axios({
url: '/common-setting/v1/employee/import',
method: 'post',
data
})
}
export function getEmployeeByUid(uid) {
return axios({
url: `/common-setting/v1/employee/by_uid/${uid}`,
method: 'get',
})
}
export function updateEmployeeByUid(uid, data) {
return axios({
url: `/common-setting/v1/employee/by_uid/${uid}`,
method: 'put',
data
})
}
export function updatePasswordByUid(uid, data) {
return axios({
url: `/common-setting/v1/employee/by_uid/change_password/${uid}`,
method: 'put',
data
})
}
export function bindWxByUid(uid) {
return axios({
url: `/common-setting/v1/employee/by_uid/bind_work_wechat/${uid}`,
method: 'put',
})
}
export function getAllPosition() {
return axios({
url: `/common-setting/v1/employee/position`,
method: 'get',
})
}
export function getEmployeeByEmployeeId(employee_id) {
return axios({
url: `/common-setting/v1/employee/${employee_id}`,
method: 'get',
})
}
// 下载员工列表
export function downloadAllEmployee(params) {
return axios({
url: `/common-setting/v1/employee/export_all`,
method: 'get',
params,
responseType: 'blob'
})
}
export function getEmployeeListByFilter(data) {
return axios({
url: '/common-setting/v1/employee/filter',
method: 'post',
data
})
}

View File

@@ -1,14 +1,15 @@
import config from '@/config/defaultSettings'
import config from '@/config/setting'
const api = {
Login: config.useSSO ? config.ssoLoginRedirectUrl : '/login',
Logout: config.useSSO ? config.ssoLogoutRedirectUrl : '/logout',
Login: config.useSSO ? '/api/sso/login' : '/v1/acl/login',
Logout: config.useSSO ? '/api/sso/logout' : '/v1/acl/logout',
ForgePassword: '/auth/forge-password',
Register: '/auth/register',
twoStepCode: '/auth/2step-code',
SendSms: '/account/sms',
SendSmsErr: '/account/sms_err',
// get my info
UserInfo: '/v1/acl/users/info'
// UserInfo: '/v1/perms/user/info'
UserInfo: process.env.VUE_APP_IS_OUTER === 'false' ? '/v1/perms/user/info' : '/v1/acl/users/info',
}
export default api

View File

@@ -1,6 +1,6 @@
import api from './index'
import { axios } from '@/utils/request'
import config from '@/config/defaultSettings'
import config from '@/config/setting'
/**
* login func
* parameter: {
@@ -12,15 +12,19 @@ import config from '@/config/defaultSettings'
* @param parameter
* @returns {*}
*/
export function login (parameter) {
return axios({
url: api.Login,
method: 'post',
data: parameter
})
export function login(data) {
if (config.useSSO) {
window.location.href = config.ssoLoginUrl
} else {
return axios({
url: api.Login,
method: 'POST',
data: data
})
}
}
export function getSmsCaptcha (parameter) {
export function getSmsCaptcha(parameter) {
return axios({
url: api.SendSms,
method: 'post',
@@ -28,7 +32,7 @@ export function getSmsCaptcha (parameter) {
})
}
export function getInfo () {
export function getInfo() {
return axios({
url: api.UserInfo,
method: 'get',
@@ -38,11 +42,9 @@ export function getInfo () {
})
}
export function logout () {
console.log('logout........', config.useSSO)
export function logout() {
if (config.useSSO) {
window.location.href = api.Logout
return Promise.resolve()
window.location.replace(api.Logout)
} else {
return axios({
url: api.Logout,
@@ -58,10 +60,18 @@ export function logout () {
* get user 2step code open?
* @param parameter {*}
*/
export function get2step (parameter) {
export function get2step(parameter) {
return axios({
url: api.twoStepCode,
method: 'post',
data: parameter
})
}
export function getAllUsers(params) {
return axios({
url: '/v1/acl/users',
method: 'GET',
params
})
}

View File

@@ -1,62 +0,0 @@
import { axios } from '@/utils/request'
const api = {
user: '/user',
role: '/role',
service: '/service',
permission: '/permission',
permissionNoPager: '/permission/no-pager',
orgTree: '/org/tree'
}
export default api
export function getUserList (parameter) {
return axios({
url: api.user,
method: 'get',
params: parameter
})
}
export function getRoleList (parameter) {
return axios({
url: api.role,
method: 'get',
params: parameter
})
}
export function getServiceList (parameter) {
return axios({
url: api.service,
method: 'get',
params: parameter
})
}
export function getPermissions (parameter) {
return axios({
url: api.permissionNoPager,
method: 'get',
params: parameter
})
}
export function getOrgTree (parameter) {
return axios({
url: api.orgTree,
method: 'get',
params: parameter
})
}
// id == 0 add post
// id != 0 update put
export function saveService (parameter) {
return axios({
url: api.service,
method: parameter.id === 0 ? 'post' : 'put',
data: parameter
})
}

View File

@@ -0,0 +1,55 @@
import { axios } from '@/utils/request'
export const getNoticeApps = () => {
return axios({
url: `/common-setting/v1/message/apps`,
method: 'get',
})
}
export const getNoticeCategoriesByApp = (app_name) => {
return axios({
url: `/common-setting/v1/message/${app_name}/categories`,
method: 'get',
})
}
export const getMessage = (params) => {
return axios({
url: `/common-setting/v1/message`,
method: 'get',
params
})
}
export const postMessage = (data) => {
return axios({
url: `/common-setting/v1/message`,
method: 'post',
data
})
}
export const updateMessage = (id, data) => {
return axios({
url: `/common-setting/v1/message/${id}`,
method: 'put',
data
})
}
export const getUnreadMessageCount = (params) => {
return axios({
url: `/common-setting/v1/message/unread`,
method: 'get',
params
})
}
export const batchUpdateMessage = (data) => {
return axios({
url: `/common-setting/v1/message/batch`,
method: 'post',
data
})
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1 +0,0 @@
<?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="1551058675966" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7872" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M85.333333 512h85.333334a340.736 340.736 0 0 1 99.712-241.621333 337.493333 337.493333 0 0 1 108.458666-72.96 346.453333 346.453333 0 0 1 261.546667-1.749334A106.154667 106.154667 0 0 0 746.666667 298.666667C805.802667 298.666667 853.333333 251.136 853.333333 192S805.802667 85.333333 746.666667 85.333333c-29.397333 0-55.978667 11.776-75.221334 30.933334-103.722667-41.514667-222.848-40.874667-325.76 2.517333a423.594667 423.594667 0 0 0-135.68 91.264 423.253333 423.253333 0 0 0-91.306666 135.637333A426.88 426.88 0 0 0 85.333333 512z m741.248 133.205333c-17.109333 40.618667-41.685333 77.141333-72.96 108.416s-67.797333 55.850667-108.458666 72.96a346.453333 346.453333 0 0 1-261.546667 1.749334A106.154667 106.154667 0 0 0 277.333333 725.333333C218.197333 725.333333 170.666667 772.864 170.666667 832S218.197333 938.666667 277.333333 938.666667c29.397333 0 55.978667-11.776 75.221334-30.933334A425.173333 425.173333 0 0 0 512 938.666667a425.941333 425.941333 0 0 0 393.258667-260.352A426.325333 426.325333 0 0 0 938.666667 512h-85.333334a341.034667 341.034667 0 0 1-26.752 133.205333z" p-id="7873"></path><path d="M512 318.378667c-106.752 0-193.621333 86.869333-193.621333 193.621333S405.248 705.621333 512 705.621333s193.621333-86.869333 193.621333-193.621333S618.752 318.378667 512 318.378667z m0 301.909333c-59.690667 0-108.288-48.597333-108.288-108.288S452.309333 403.712 512 403.712s108.288 48.597333 108.288 108.288-48.597333 108.288-108.288 108.288z" p-id="7874"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View 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="1663902596358" class="icon" style="width:20px;height:20px;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4084" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024"><path d="M320 306.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L320 306.6z" p-id="4085"></path><path d="M576 306.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L576 306.6z" p-id="4086"></path><path d="M832 306.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L832 306.6z" p-id="4087"></path><path d="M320 562.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L320 562.6z" p-id="4088"></path><path d="M576 562.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L576 562.6z" p-id="4089"></path><path d="M832 562.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L832 562.6z" p-id="4090"></path><path d="M320 818.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L320 818.6z" p-id="4091"></path><path d="M576 818.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L576 818.6z" p-id="4092"></path><path d="M832 818.6c0 7.4-6 13.4-13.4 13.4l-101 0c-7.4 0-13.4-6-13.4-13.4l0-101c0-7.4 6-13.4 13.4-13.4l101 0c7.4 0 13.4 6 13.4 13.4L832 818.6z" p-id="4093"></path></svg><?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="1652149253074" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2678" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }</style></defs><path d="M512 505.6c-2.133333 0-4.266667 0-8.533333-2.133333L298.666667 426.666667v298.666666h426.666666V426.666667l-204.8 76.8c-4.266667 0-6.4 2.133333-8.533333 2.133333z" p-id="2679"></path><path d="M298.666667 379.733333l213.333333 81.066667 213.333333-81.066667V298.666667H298.666667z" p-id="2680"></path><path d="M512 0C228.266667 0 0 228.266667 0 512s228.266667 512 512 512 512-228.266667 512-512S795.733333 0 512 0z m256 725.333333c0 23.466667-19.2 42.666667-42.666667 42.666667H298.666667c-23.466667 0-42.666667-19.2-42.666667-42.666667V298.666667c0-23.466667 19.2-42.666667 42.666667-42.666667h426.666666c23.466667 0 42.666667 19.2 42.666667 42.666667v426.666666z" p-id="2681"></path></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,14 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0H2.5V1.25H1.25V2.5H0V1C0 0.447715 0.447715 0 1 0ZM0 7.5V9C0 9.55229 0.447715 10 1 10H2.5V8.75H1.25V7.5H0ZM8.75 7.5V8.75H7.5V10H9C9.55229 10 10 9.55228 10 9V7.5H8.75ZM10 2.5V1C10 0.447715 9.55228 0 9 0H7.5V1.25H8.75V2.5H10Z" fill="url(#paint0_linear_124_16807)"/>
<rect x="2.5" y="3.125" width="5" height="3.75" fill="url(#paint1_linear_124_16807)"/>
<defs>
<linearGradient id="paint0_linear_124_16807" x1="5" y1="0" x2="5" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#4F84FF"/>
<stop offset="1" stop-color="#85CBFF"/>
</linearGradient>
<linearGradient id="paint1_linear_124_16807" x1="5" y1="3.125" x2="5" y2="6.875" gradientUnits="userSpaceOnUse">
<stop stop-color="#4F84FF"/>
<stop offset="1" stop-color="#85CBFF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 916 B

View File

@@ -0,0 +1,14 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="2.5" y="2.5" width="5" height="5" rx="0.5" fill="url(#paint0_linear_124_16808)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0C0.447715 0 0 0.447715 0 1V9C0 9.55229 0.447715 10 1 10H9C9.55229 10 10 9.55228 10 9V1C10 0.447715 9.55228 0 9 0H1ZM8.75 1.25H1.25V8.75H8.75V1.25Z" fill="url(#paint1_linear_124_16808)"/>
<defs>
<linearGradient id="paint0_linear_124_16808" x1="5" y1="2.5" x2="5" y2="7.5" gradientUnits="userSpaceOnUse">
<stop stop-color="#5187FF"/>
<stop offset="1" stop-color="#84C9FF"/>
</linearGradient>
<linearGradient id="paint1_linear_124_16808" x1="5" y1="0" x2="5" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#5187FF"/>
<stop offset="1" stop-color="#84C9FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 840 B

View File

@@ -0,0 +1,9 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.56845 8.8409C3.06335 8.78963 1.86719 8.05799 2.06279 6.48243C2.1538 5.75105 2.64549 5.3214 3.34457 5.16041C3.67173 5.08909 4.00806 5.06954 4.34128 5.10247C4.40203 5.10811 4.44843 5.11401 4.47689 5.11837L4.51586 5.12631C4.64379 5.15574 4.77263 5.18104 4.90218 5.20219C5.26786 5.2651 5.63914 5.28941 6.0099 5.27474C6.8046 5.23219 7.21015 4.97429 7.23092 4.41672C7.25424 3.79429 6.76332 3.29619 5.86659 2.91832C5.52815 2.77793 5.17843 2.66645 4.82117 2.58506C4.70325 2.55755 4.58482 2.53328 4.46587 2.51226C4.30323 2.94847 3.9867 3.31016 3.57591 3.5292C3.16512 3.74824 2.68841 3.80952 2.23557 3.70149C1.90324 3.61651 1.60053 3.44214 1.36029 3.1973C1.12004 2.95245 0.951447 2.64649 0.872793 2.3126C0.794138 1.97872 0.808429 1.62967 0.914116 1.30333C1.0198 0.976995 1.21285 0.685836 1.4723 0.461451C1.73176 0.237065 2.04771 0.0880244 2.38588 0.0305017C2.72404 -0.0270211 3.07151 0.00917138 3.39056 0.135152C3.70961 0.261132 3.98807 0.472088 4.19571 0.745127C4.40335 1.01817 4.53225 1.34286 4.56841 1.68397C4.6812 1.70269 4.83374 1.73217 5.01524 1.77421C5.42003 1.86601 5.81625 1.99216 6.1996 2.15131C7.38191 2.64966 8.1156 3.39463 8.07638 4.4462C8.03639 5.53187 7.23425 6.04253 6.0563 6.10533C5.62418 6.12373 5.19132 6.09614 4.76503 6.02304C4.61925 5.99997 4.47398 5.9716 4.32923 5.93793C4.30731 5.93532 4.28534 5.9331 4.26335 5.93127C4.02033 5.90687 3.77501 5.92018 3.53606 5.97075C3.15153 6.05893 2.94311 6.24146 2.90056 6.58267C2.78725 7.49504 3.47915 7.94443 5.42694 8.00416C5.44492 7.65558 5.5586 7.3187 5.75548 7.03049C5.95237 6.74229 6.22485 6.51389 6.54303 6.37039C6.8612 6.22689 7.21277 6.17383 7.55912 6.21703C7.90548 6.26023 8.23323 6.39802 8.50641 6.61528C8.77959 6.83254 8.98763 7.12086 9.10769 7.4486C9.22775 7.77634 9.25519 8.13082 9.187 8.47314C9.11881 8.81545 8.95763 9.13235 8.72114 9.38907C8.48465 9.64578 8.18201 9.83237 7.84643 9.92836C7.39921 10.0556 6.92094 10.0153 6.50129 9.81515C6.08164 9.61495 5.74941 9.26855 5.56691 8.8409H5.56845Z" fill="url(#paint0_linear_124_16804)"/>
<defs>
<linearGradient id="paint0_linear_124_16804" x1="5.02318" y1="0.00390625" x2="5.02318" y2="10.0013" gradientUnits="userSpaceOnUse">
<stop stop-color="#497DFF"/>
<stop offset="1" stop-color="#8CD5FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,9 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.01211 4.50621L2.7769 5.74077C2.712 5.80565 2.66051 5.88268 2.62538 5.96747C2.59025 6.05225 2.57217 6.14313 2.57217 6.2349C2.57217 6.32668 2.59025 6.41755 2.62538 6.50234C2.66051 6.58712 2.712 6.66416 2.7769 6.72904L3.27085 7.223C3.33573 7.28791 3.41276 7.3394 3.49754 7.37453C3.58232 7.40966 3.67319 7.42774 3.76496 7.42774C3.85674 7.42774 3.94761 7.40966 4.03239 7.37453C4.11717 7.3394 4.1942 7.28791 4.25908 7.223L5.49394 5.98775C5.6237 6.1175 5.72663 6.27155 5.79686 6.44109C5.86708 6.61063 5.90323 6.79234 5.90323 6.97585C5.90323 7.15935 5.86708 7.34106 5.79686 7.5106C5.72663 7.68014 5.6237 7.83419 5.49394 7.96394L3.76479 9.69316C3.56827 9.88963 3.30176 10 3.02387 10C2.74599 10 2.47948 9.88963 2.28296 9.69316L0.306832 7.71696C0.110368 7.52043 0 7.25391 0 6.97602C0 6.69813 0.110368 6.43161 0.306832 6.23508L2.03599 4.50586C2.16574 4.3761 2.31978 4.27317 2.48931 4.20294C2.65884 4.13271 2.84055 4.09657 3.02405 4.09657C3.20755 4.09657 3.38925 4.13271 3.55879 4.20294C3.72832 4.27317 3.88236 4.3761 4.01211 4.50586V4.50621ZM5.98789 5.49414L7.2231 4.25923C7.288 4.19435 7.33949 4.11732 7.37462 4.03253C7.40975 3.94775 7.42783 3.85687 7.42783 3.7651C7.42783 3.67332 7.40975 3.58245 7.37462 3.49766C7.33949 3.41288 7.288 3.33584 7.2231 3.27096L6.72915 2.777C6.66428 2.71209 6.58724 2.6606 6.50246 2.62547C6.41768 2.59034 6.32681 2.57226 6.23504 2.57226C6.14326 2.57226 6.05239 2.59034 5.96761 2.62547C5.88283 2.6606 5.8058 2.71209 5.74092 2.777L4.50606 4.01225C4.3763 3.8825 4.27337 3.72845 4.20314 3.55891C4.13292 3.38937 4.09677 3.20766 4.09677 3.02415C4.09677 2.84065 4.13292 2.65894 4.20314 2.4894C4.27337 2.31986 4.3763 2.16581 4.50606 2.03606L6.23521 0.306843C6.43173 0.110371 6.69824 0 6.97613 0C7.25401 0 7.52052 0.110371 7.71704 0.306843L9.69317 2.28304C9.88963 2.47957 10 2.74609 10 3.02398C10 3.30187 9.88963 3.56839 9.69317 3.76492L7.96401 5.49414C7.83426 5.6239 7.68022 5.72683 7.51069 5.79706C7.34116 5.86729 7.15945 5.90343 6.97595 5.90343C6.79245 5.90343 6.61075 5.86729 6.44121 5.79706C6.27168 5.72683 6.11764 5.6239 5.98789 5.49414ZM3.51817 5.9881L5.98789 3.51829C6.05339 3.45274 6.14225 3.4159 6.23491 3.41586C6.32758 3.41583 6.41646 3.45261 6.48201 3.51812C6.54755 3.58362 6.5844 3.67248 6.58443 3.76515C6.58446 3.85782 6.54768 3.9467 6.48218 4.01225L4.01211 6.48206C3.94661 6.54761 3.85775 6.58445 3.76509 6.58449C3.67242 6.58452 3.58354 6.54774 3.51799 6.48223C3.45245 6.41673 3.4156 6.32787 3.41557 6.2352C3.41554 6.14253 3.45232 6.05365 3.51782 5.9881H3.51817Z" fill="url(#paint0_linear_124_16775)"/>
<defs>
<linearGradient id="paint0_linear_124_16775" x1="5" y1="0" x2="5" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#5A85FF"/>
<stop offset="1" stop-color="#8DD8FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,9 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.31822 4.16667H2.54549V2.5C2.54549 1.11458 3.63981 0 5.00003 0C6.36026 0 7.45458 1.11458 7.45458 2.5V4.16667H8.68185C8.90685 4.16667 9.09094 4.35417 9.09094 4.58333V9.58333C9.09094 9.8125 8.90685 10 8.68185 10H1.31822C1.09322 10 0.909124 9.8125 0.909124 9.58333V4.58333C0.909124 4.35417 1.09322 4.16667 1.31822 4.16667ZM5.00003 7.91667C5.45003 7.91667 5.81822 7.54167 5.81822 7.08333C5.81822 6.625 5.45003 6.25 5.00003 6.25C4.55003 6.25 4.18185 6.625 4.18185 7.08333C4.18185 7.54167 4.55003 7.91667 5.00003 7.91667ZM3.36367 4.16667H6.6364V2.5C6.6364 1.58333 5.90003 0.833333 5.00003 0.833333C4.10003 0.833333 3.36367 1.58333 3.36367 2.5V4.16667Z" fill="url(#paint0_linear_124_16805)"/>
<defs>
<linearGradient id="paint0_linear_124_16805" x1="5.00003" y1="0" x2="5.00003" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#4D82FF"/>
<stop offset="1" stop-color="#88CFFF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1022 B

View File

@@ -0,0 +1,9 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.91242 9.46382C3.91242 9.57428 3.82288 9.66382 3.71242 9.66382H2.35075C2.2403 9.66382 2.15075 9.57428 2.15075 9.46382V3.55962C2.15075 3.44916 2.06121 3.35962 1.95075 3.35962H0.539905C0.354312 3.35962 0.268806 3.12879 0.40961 3.00788L3.58212 0.283626C3.71182 0.172253 3.91242 0.264405 3.91242 0.43536V9.46382ZM6.08758 0.567715C6.08758 0.457258 6.17712 0.367716 6.28758 0.367716H7.64925C7.7597 0.367716 7.84925 0.457259 7.84925 0.567716V6.4411C7.84925 6.55156 7.93879 6.6411 8.04925 6.6411H9.46001C9.64561 6.6411 9.73111 6.87195 9.59029 6.99285L6.41786 9.71645C6.28816 9.8278 6.08758 9.73565 6.08758 9.5647V0.567715Z" fill="url(#paint0_linear_124_16806)"/>
<defs>
<linearGradient id="paint0_linear_124_16806" x1="5" y1="0" x2="5" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#5A85FF"/>
<stop offset="1" stop-color="#8DD8FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 979 B

View File

@@ -0,0 +1,9 @@
<svg width="1em" height="1em" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.51961 6.8937V10H4.48V6.8937H1.76732C1.65823 6.8937 1.56223 6.85372 1.48369 6.77237C1.40522 6.69504 1.3621 6.5915 1.36369 6.48421C1.36369 5.95891 1.52769 5.48566 1.85895 5.06411C2.18986 4.64428 2.56258 4.43334 2.97893 4.43334V1.64277C2.75966 1.64277 2.57167 1.56142 2.41022 1.39873C2.25355 1.24349 2.16738 1.0362 2.17022 0.821384C2.17022 0.598718 2.25022 0.407762 2.41022 0.244037C2.56912 0.0827244 2.7593 0 2.97893 0H7.01959C7.23885 0 7.42685 0.0813456 7.5883 0.244037C7.74721 0.406728 7.82866 0.598718 7.82866 0.821384C7.82866 1.04405 7.74866 1.23501 7.58867 1.39873C7.4283 1.5628 7.23885 1.64277 7.01959 1.64277V4.43196C7.43594 4.43196 7.81012 4.64291 8.13956 5.06273C8.46631 5.47151 8.64098 5.97137 8.63628 6.48421C8.63628 6.59486 8.59701 6.6924 8.51665 6.77237C8.43665 6.85234 8.34211 6.8937 8.23302 6.8937H5.51998H5.51961Z" fill="url(#paint0_linear_124_16803)"/>
<defs>
<linearGradient id="paint0_linear_124_16803" x1="5.00001" y1="0" x2="5.00001" y2="10" gradientUnits="userSpaceOnUse">
<stop stop-color="#5A85FF"/>
<stop offset="1" stop-color="#8DD8FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg t="1662694543392" class="move-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2689" aria-hidden="true" fill="currentColor"><path d="M469.333333 256a85.333333 85.333333 0 1 1-85.333333-85.333333 85.333333 85.333333 0 0 1 85.333333 85.333333z m-85.333333 170.666667a85.333333 85.333333 0 1 0 85.333333 85.333333 85.333333 85.333333 0 0 0-85.333333-85.333333z m0 256a85.333333 85.333333 0 1 0 85.333333 85.333333 85.333333 85.333333 0 0 0-85.333333-85.333333z m256-341.333334a85.333333 85.333333 0 1 0-85.333333-85.333333 85.333333 85.333333 0 0 0 85.333333 85.333333z m0 85.333334a85.333333 85.333333 0 1 0 85.333333 85.333333 85.333333 85.333333 0 0 0-85.333333-85.333333z m0 256a85.333333 85.333333 0 1 0 85.333333 85.333333 85.333333 85.333333 0 0 0-85.333333-85.333333z" p-id="2690" fill="#8a8a8a"></path></svg>

After

Width:  |  Height:  |  Size: 855 B

View 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="1663922664875" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9161" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 192c102.4 0 153.6 51.2 153.6 153.6C665.6 480 576 576 576 576L556.8 595.2l0 25.6c0 57.6 44.8 121.6 121.6 121.6 102.4 0 102.4 19.2 102.4 44.8l0 0C768 800 710.4 832 505.6 832c-185.6 0-243.2-32-262.4-38.4l0-6.4c0-25.6 0-44.8 102.4-44.8 76.8 0 121.6-64 121.6-121.6L467.2 595.2 448 576c0 0-89.6-96-89.6-230.4C358.4 243.2 409.6 192 512 192M512 128C403.2 128 294.4 185.6 294.4 345.6s108.8 275.2 108.8 275.2 0 57.6-57.6 57.6-166.4 0-166.4 108.8c0 0-44.8 108.8 326.4 108.8s332.8-108.8 332.8-108.8c0-108.8-108.8-108.8-166.4-108.8S620.8 620.8 620.8 620.8s108.8-108.8 108.8-275.2S620.8 128 512 128L512 128z" p-id="9162"></path></svg>

After

Width:  |  Height:  |  Size: 958 B

View 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="1663922655131" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8238" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M458 476.6L170.8 332.9c-19.6-9.8-38.6-10.2-53.4-1-14.8 9.2-23 26.2-23 48.1v332.2c0 31.4 21.7 67.7 49.3 82.8l289.1 156.6c10.5 5.7 20.8 8.6 30.6 8.6 8.1 0 15.6-2 22.2-5.9 14.7-8.8 22.9-25.7 22.9-47.6V558.2c0-15.4-5.2-32.2-14.5-47.4-9.4-15.1-22.2-27.3-36-34.2z m-7.3 81.6v337.4L171.2 744.2c-8.9-4.8-19.1-21.9-19.1-32V388.3l280 140c8.7 4.3 18.6 20.2 18.6 29.9zM874.5 300.8c19.3-9.5 29.9-23.1 29.8-38.3 0-15.2-10.6-28.8-29.9-38.3l-302-148c-16.3-8-37.8-12.3-60.5-12.3-22.7 0-44.2 4.4-60.4 12.3l-302 147.9c-19.3 9.5-29.8 23.1-29.8 38.3 0 15.2 10.6 28.8 29.9 38.3l302 148c16.3 8 37.8 12.3 60.5 12.3 22.7 0 44.2-4.4 60.4-12.3l302-147.9z m-671.8-38.4L477 128.1c18-8.8 52-8.8 70.1 0l274.2 134.3L547 396.8c-18 8.8-52 8.8-70.1 0L202.7 262.4zM906.7 332.4c-14.8-8.8-33.6-7.9-52.9 2.6L581 483.3c-27.6 15.1-49.3 51.6-49.3 82.9v340.3c0 22 8.1 38.8 22.8 47.4 6.4 3.7 13.6 5.6 21.4 5.6 10 0 20.4-3.1 31.1-9.1l273.8-154.7c13.3-7.6 25.7-20.3 34.8-35.8 9.1-15.5 14.1-32.5 14.1-47.7V380c-0.1-21.9-8.2-38.8-23-47.6z m-34.9 58.7v321c0 10.4-10.3 28.1-19.4 33.2L589.5 893.9V566.2c0-10.1 10.2-27.2 19.1-32.1l263.2-143z" p-id="8239"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
<title>Vue</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="69.644116%" y1="0%" x2="69.644116%" y2="100%" id="linearGradient-1">
<stop stop-color="#29CDFF" offset="0%"></stop>
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
<stop stop-color="#0A60FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="-19.8191553%" y1="-36.7931464%" x2="138.57919%" y2="157.637507%" id="linearGradient-2">
<stop stop-color="#29CDFF" offset="0%"></stop>
<stop stop-color="#0F78FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-3">
<stop stop-color="#FA8E7D" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="AntVue" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(19.000000, 9.000000)">
<path d="M89.96,90.48 C78.58,93.48 68.33,83.36 67.62,82.48 L46.6604487,62.2292258 C45.5023849,61.1103236 44.8426845,59.5728835 44.8296987,57.9626396 L44.5035564,17.5209948 C44.4948861,16.4458744 44.0537714,15.4195095 43.2796864,14.6733517 L29.6459999,1.53153737 C28.055475,-0.00160504005 25.5232423,0.0449126588 23.9900999,1.63543756 C23.2715121,2.38092066 22.87,3.37600834 22.87,4.41143746 L22.87,64.3864751 C22.87,67.0807891 23.9572233,69.6611067 25.885409,71.5429748 L63.6004615,108.352061 C65.9466323,110.641873 69.6963584,110.624605 72.0213403,108.313281" id="Path-Copy" fill="url(#linearGradient-1)" fill-rule="nonzero" transform="translate(56.415000, 54.831157) scale(-1, 1) translate(-56.415000, -54.831157) "></path>
<path d="M68,90.1163122 C56.62,93.1163122 45.46,83.36 44.75,82.48 L23.7904487,62.2292258 C22.6323849,61.1103236 21.9726845,59.5728835 21.9596987,57.9626396 L21.6335564,17.5209948 C21.6248861,16.4458744 21.1837714,15.4195095 20.4096864,14.6733517 L6.7759999,1.53153737 C5.185475,-0.00160504005 2.65324232,0.0449126588 1.12009991,1.63543756 C0.401512125,2.38092066 3.90211878e-13,3.37600834 3.90798505e-13,4.41143746 L3.94351218e-13,64.3864751 C3.94681177e-13,67.0807891 1.08722326,69.6611067 3.01540903,71.5429748 L40.7807092,108.401101 C43.1069304,110.671444 46.8180151,110.676525 49.1504445,108.412561" id="Path" fill="url(#linearGradient-2)" fill-rule="nonzero"></path>
<path d="M43.2983488,19.0991931 L27.5566079,3.88246244 C26.7624281,3.11476967 26.7409561,1.84862177 27.5086488,1.05444194 C27.8854826,0.664606611 28.4044438,0.444472651 28.9466386,0.444472651 L60.3925021,0.444472651 C61.4970716,0.444472651 62.3925021,1.33990315 62.3925021,2.44447265 C62.3925021,2.9858375 62.1730396,3.50407742 61.7842512,3.88079942 L46.0801285,19.0975301 C45.3051579,19.8484488 44.0742167,19.8491847 43.2983488,19.0991931 Z" id="Path" fill="url(#linearGradient-3)"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

2
cmdb-ui/src/bus/index.js Normal file
View File

@@ -0,0 +1,2 @@
import Vue from 'vue'
export default new Vue()

View File

@@ -1,89 +0,0 @@
<template>
<div class="antd-pro-components-article-list-content-index-listContent">
<div class="description">
<slot>
{{ description }}
</slot>
</div>
<div class="extra">
<a-avatar :src="avatar" size="small" />
<a :href="href">{{ owner }}</a> 发布在 <a :href="href">{{ href }}</a>
<em>{{ updateAt | moment }}</em>
</div>
</div>
</template>
<script>
export default {
name: 'ArticleListContent',
props: {
prefixCls: {
type: String,
default: 'antd-pro-components-article-list-content-index-listContent'
},
description: {
type: String,
default: ''
},
owner: {
type: String,
required: true
},
avatar: {
type: String,
required: true
},
href: {
type: String,
required: true
},
updateAt: {
type: String,
required: true
}
}
}
</script>
<style lang="less" scoped>
@import '../index.less';
.antd-pro-components-article-list-content-index-listContent {
.description {
max-width: 720px;
line-height: 22px;
}
.extra {
margin-top: 16px;
color: @text-color-secondary;
line-height: 22px;
& /deep/ .ant-avatar {
position: relative;
top: 1px;
width: 20px;
height: 20px;
margin-right: 8px;
vertical-align: top;
}
& > em {
margin-left: 16px;
color: @disabled-color;
font-style: normal;
}
}
}
@media screen and (max-width: @screen-xs) {
.antd-pro-components-article-list-content-index-listContent {
.extra {
& > em {
display: block;
margin-top: 8px;
margin-left: 0;
}
}
}
}
</style>

View File

@@ -1,3 +0,0 @@
import ArticleListContent from './ArticleListContent'
export default ArticleListContent

View File

@@ -1,46 +0,0 @@
<template>
<tooltip v-if="tips !== ''">
<template slot="title">{{ tips }}</template>
<avatar :size="avatarSize" :src="src" />
</tooltip>
<avatar v-else :size="avatarSize" :src="src" />
</template>
<script>
import Avatar from 'ant-design-vue/es/avatar'
import Tooltip from 'ant-design-vue/es/tooltip'
export default {
name: 'AvatarItem',
components: {
Avatar,
Tooltip
},
props: {
tips: {
type: String,
default: '',
required: false
},
src: {
type: String,
default: ''
}
},
data () {
return {
size: this.$parent.size
}
},
computed: {
avatarSize () {
return this.size !== 'mini' && this.size || 20
}
},
watch: {
'$parent.size' (val) {
this.size = val
}
}
}
</script>

View File

@@ -1,99 +0,0 @@
<!--
<template>
<div :class="[prefixCls]">
<ul>
<slot></slot>
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
<avatar-item :size="size">
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
</avatar-item>
</template>
</ul>
</div>
</template>
-->
<script>
import Avatar from 'ant-design-vue/es/avatar'
import AvatarItem from './Item'
import { filterEmpty } from '@/components/_util/util'
export default {
AvatarItem,
name: 'AvatarList',
components: {
Avatar,
AvatarItem
},
props: {
prefixCls: {
type: String,
default: 'ant-pro-avatar-list'
},
/**
* 头像大小 类型: largesmall mini, default
* 默认值: default
*/
size: {
type: [String, Number],
default: 'default'
},
/**
* 要显示的最大项目
*/
maxLength: {
type: Number,
default: 0
},
/**
* 多余的项目风格
*/
excessItemsStyle: {
type: Object,
default: () => {
return {
color: '#f56a00',
backgroundColor: '#fde3cf'
}
}
}
},
data () {
return {}
},
methods: {
getItems (items) {
const classString = {
[`${this.prefixCls}-item`]: true,
[`${this.size}`]: true
}
if (this.maxLength > 0) {
items = items.slice(0, this.maxLength)
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
}
const itemList = items.map((item) => (
<li class={ classString }>{ item }</li>
))
return itemList
}
},
render () {
const { prefixCls, size } = this.$props
const classString = {
[`${prefixCls}`]: true,
[`${size}`]: true
}
const items = filterEmpty(this.$slots.default)
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
return (
<div class={ classString }>
{ itemsDom }
</div>
)
}
}
</script>

View File

@@ -1,4 +0,0 @@
import AvatarList from './List'
import './index.less'
export default AvatarList

View File

@@ -1,60 +0,0 @@
@import "../index";
@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list";
@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item";
.@{avatar-list-prefix-cls} {
display: inline-block;
ul {
list-style: none;
display: inline-block;
padding: 0;
margin: 0 0 0 8px;
font-size: 0;
}
}
.@{avatar-list-item-prefix-cls} {
display: inline-block;
font-size: @font-size-base;
margin-left: -8px;
width: @avatar-size-base;
height: @avatar-size-base;
:global {
.ant-avatar {
border: 1px solid #fff;
cursor: pointer;
}
}
&.large {
width: @avatar-size-lg;
height: @avatar-size-lg;
}
&.small {
width: @avatar-size-sm;
height: @avatar-size-sm;
}
&.mini {
width: 20px;
height: 20px;
:global {
.ant-avatar {
width: 20px;
height: 20px;
line-height: 20px;
.ant-avatar-string {
font-size: 12px;
line-height: 18px;
}
}
}
}
}

View File

@@ -1,64 +0,0 @@
# AvatarList 用户头像列表
一组用户头像常用在项目/团队成员列表可通过设置 `size` 属性来指定头像大小
引用方式
```javascript
import AvatarList from '@/components/AvatarList'
const AvatarListItem = AvatarList.AvatarItem
export default {
components: {
AvatarList,
AvatarListItem
}
}
```
## 代码演示 [demo](https://pro.loacg.com/test/home)
```html
<avatar-list size="mini">
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
</avatar-list>
```
```html
<avatar-list :max-length="3">
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
</avatar-list>
```
## API
### AvatarList
| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | -------- | ---------------------------------- | --------- |
| size | 头像大小 | `large``small` `mini`, `default` | `default` |
| maxLength | 要显示的最大项目 | number | - |
| excessItemsStyle | 多余的项目风格 | CSSProperties | - |
### AvatarList.Item
| 参数 | 说明 | 类型 | 默认值 |
| ---- | ------ | --------- | --- |
| tips | 头像展示文案 | string | - |
| src | 头像图片连接 | string | - |

View File

@@ -0,0 +1,2 @@
import CMDBExprDrawer from './index.vue'
export default CMDBExprDrawer

View File

@@ -0,0 +1,47 @@
<template>
<CustomDrawer
width="1000px"
:visible="visible"
@close="handleClose"
:hasTitle="false"
:hasFooter="false"
:closable="false"
:bodyStyle="{ padding: '24px 12px' }"
:placement="placement"
>
<ResourceSearch :fromCronJob="true" @copySuccess="copySuccess" />
</CustomDrawer>
</template>
<script>
import ResourceSearch from '@/modules/cmdb/views/resource_search'
export default {
name: 'CMDBExprDrawer',
components: { ResourceSearch },
props: {
placement: {
type: String,
default: 'right',
},
},
data() {
return {
visible: false,
}
},
methods: {
open() {
this.visible = true
},
handleClose() {
this.visible = false
},
copySuccess(text) {
this.$emit('copySuccess', text)
this.handleClose()
},
},
}
</script>
<style></style>

View File

@@ -0,0 +1,33 @@
export const ruleTypeList = [
{ value: 'and', label: '' },
{ value: 'or', label: '' },
// { value: 'not', label: '' },
]
export const expList = [
{ value: 'is', label: '等于' },
{ value: '~is', label: '不等于' },
{ value: 'contain', label: '包含' },
{ value: '~contain', label: '不包含' },
{ value: 'start_with', label: '以...开始' },
{ value: '~start_with', label: '不以...开始' },
{ value: 'end_with', label: '以...结束' },
{ value: '~end_with', label: '不以...结束' },
{ value: '~value', label: '为空' }, // 为空的定义有点绕
{ value: 'value', label: '不为空' },
]
export const advancedExpList = [
{ value: 'in', label: 'in查询' },
{ value: '~in', label: '非in查询' },
{ value: 'range', label: '范围' },
{ value: '~range', label: '范围外' },
{ value: 'compare', label: '比较' },
]
export const compareTypeList = [
{ value: '1', label: '>' },
{ value: '2', label: '>=' },
{ value: '3', label: '<' },
{ value: '4', label: '<=' },
]

View File

@@ -0,0 +1,285 @@
<template>
<div>
<a-space :style="{ display: 'flex', marginBottom: '10px' }" v-for="(item, index) in ruleList" :key="item.id">
<div :style="{ width: '50px', height: '24px', position: 'relative' }">
<treeselect
v-if="index"
class="custom-treeselect"
:style="{ width: '50px', '--custom-height': '24px', position: 'absolute', top: '-17px', left: 0 }"
v-model="item.type"
:multiple="false"
:clearable="false"
searchable
:options="ruleTypeList"
:normalizer="
(node) => {
return {
id: node.value,
label: node.label,
children: node.children,
}
}
"
>
</treeselect>
</div>
<treeselect
class="custom-treeselect"
:style="{ width: '130px', '--custom-height': '24px' }"
v-model="item.property"
:multiple="false"
:clearable="false"
searchable
:options="canSearchPreferenceAttrList"
:normalizer="
(node) => {
return {
id: node.name,
label: node.alias || node.name,
children: node.children,
}
}
"
>
<div
:title="node.label"
slot="option-label"
slot-scope="{ node }"
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
>
<ValueTypeMapIcon :attr="node.raw" />
{{ node.label }}
</div>
<div
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
slot="value-label"
slot-scope="{ node }"
>
<ValueTypeMapIcon :attr="node.raw" /> {{ node.label }}
</div>
</treeselect>
<treeselect
class="custom-treeselect"
:style="{ width: '100px', '--custom-height': '24px' }"
v-model="item.exp"
:multiple="false"
:clearable="false"
searchable
:options="[...getExpListByProperty(item.property), ...advancedExpList]"
:normalizer="
(node) => {
return {
id: node.value,
label: node.label,
children: node.children,
}
}
"
@select="(value) => handleChangeExp(value, item, index)"
>
</treeselect>
<treeselect
class="custom-treeselect"
:style="{ width: '175px', '--custom-height': '24px' }"
v-model="item.value"
:multiple="false"
:clearable="false"
searchable
v-if="isChoiceByProperty(item.property) && (item.exp === 'is' || item.exp === '~is')"
:options="getChoiceValueByProperty(item.property)"
placeholder="请选择"
:normalizer="
(node) => {
return {
id: node[0],
label: node[0],
children: node.children,
}
}
"
>
<div
:title="node.label"
slot="option-label"
slot-scope="{ node }"
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
>
{{ node.label }}
</div>
</treeselect>
<a-input-group
size="small"
compact
v-else-if="item.exp === 'range' || item.exp === '~range'"
:style="{ width: '175px' }"
>
<a-input class="ops-input" size="small" v-model="item.min" :style="{ width: '78px' }" placeholder="最小值" />
~
<a-input class="ops-input" size="small" v-model="item.max" :style="{ width: '78px' }" placeholder="最大值" />
</a-input-group>
<a-input-group size="small" compact v-else-if="item.exp === 'compare'" :style="{ width: '175px' }">
<treeselect
class="custom-treeselect"
:style="{ width: '60px', '--custom-height': '24px' }"
v-model="item.compareType"
:multiple="false"
:clearable="false"
searchable
:options="compareTypeList"
:normalizer="
(node) => {
return {
id: node.value,
label: node.label,
children: node.children,
}
}
"
>
</treeselect>
<a-input class="ops-input" v-model="item.value" size="small" style="width: 113px" />
</a-input-group>
<a-input
v-else-if="item.exp !== 'value' && item.exp !== '~value'"
size="small"
v-model="item.value"
:placeholder="item.exp === 'in' || item.exp === '~in' ? '以 ; 分隔' : ''"
class="ops-input"
></a-input>
<div v-else :style="{ width: '175px' }"></div>
<a-tooltip title="复制">
<a class="operation" @click="handleCopyRule(item)"><ops-icon type="icon-xianxing-copy"/></a>
</a-tooltip>
<a-tooltip title="删除">
<a class="operation" @click="handleDeleteRule(item)"><ops-icon type="icon-xianxing-delete"/></a>
</a-tooltip>
</a-space>
<div class="table-filter-add">
<a @click="handleAddRule">+ 新增</a>
</div>
</div>
</template>
<script>
import _ from 'lodash'
import { v4 as uuidv4 } from 'uuid'
import { ruleTypeList, expList, advancedExpList, compareTypeList } from './constants'
import ValueTypeMapIcon from '../CMDBValueTypeMapIcon'
export default {
name: 'Expression',
components: { ValueTypeMapIcon },
model: {
prop: 'value',
event: 'change',
},
props: {
value: {
type: Array,
default: () => [],
},
canSearchPreferenceAttrList: {
type: Array,
required: true,
default: () => [],
},
},
data() {
return {
ruleTypeList,
expList,
advancedExpList,
compareTypeList,
}
},
computed: {
ruleList: {
get() {
return this.value
},
set(val) {
this.$emit('change', val)
return val
},
},
},
methods: {
getExpListByProperty(property) {
if (property) {
const _find = this.canSearchPreferenceAttrList.find((item) => item.name === property)
if (_find && ['0', '1', '3', '4', '5'].includes(_find.value_type)) {
return [
{ value: 'is', label: '等于' },
{ value: '~is', label: '不等于' },
{ value: '~value', label: '为空' }, // 为空的定义有点绕
{ value: 'value', label: '不为空' },
]
}
return this.expList
}
return this.expList
},
isChoiceByProperty(property) {
const _find = this.canSearchPreferenceAttrList.find((item) => item.name === property)
if (_find) {
return _find.is_choice
}
return false
},
handleAddRule() {
this.ruleList.push({
id: uuidv4(),
type: 'and',
property: this.canSearchPreferenceAttrList[0]?.name,
exp: 'is',
value: null,
})
this.$emit('change', this.ruleList)
},
handleCopyRule(item) {
this.ruleList.push({ ...item, id: uuidv4() })
this.$emit('change', this.ruleList)
},
handleDeleteRule(item) {
const idx = this.ruleList.findIndex((r) => r.id === item.id)
if (idx > -1) {
this.ruleList.splice(idx, 1)
}
this.$emit('change', this.ruleList)
},
getChoiceValueByProperty(property) {
const _find = this.canSearchPreferenceAttrList.find((item) => item.name === property)
if (_find) {
return _find.choice_value
}
return []
},
handleChangeExp({ value }, item, index) {
const _ruleList = _.cloneDeep(this.ruleList)
if (value === 'range') {
_ruleList[index] = {
..._ruleList[index],
min: '',
max: '',
exp: value,
}
} else if (value === 'compare') {
_ruleList[index] = {
..._ruleList[index],
compareType: '1',
exp: value,
}
} else {
_ruleList[index] = {
..._ruleList[index],
exp: value,
}
}
this.ruleList = _ruleList
this.$emit('change', this.ruleList)
},
},
}
</script>
<style></style>

View File

@@ -0,0 +1,276 @@
<template>
<div>
<a-popover
v-if="isDropdown"
v-model="visible"
trigger="click"
:placement="placement"
overlayClassName="table-filter"
@visibleChange="visibleChange"
>
<slot name="popover_item">
<a-button type="primary" ghost>条件过滤<a-icon type="filter"/></a-button>
</slot>
<template slot="content">
<Expression v-model="ruleList" :canSearchPreferenceAttrList="canSearchPreferenceAttrList" />
<a-divider :style="{ margin: '10px 0' }" />
<div style="width:534px">
<a-space :style="{ display: 'flex', justifyContent: 'flex-end' }">
<a-button type="primary" size="small" @click="handleSubmit">确定</a-button>
<a-button size="small" @click="handleClear">清空</a-button>
</a-space>
</div>
</template>
</a-popover>
<Expression v-else v-model="ruleList" :canSearchPreferenceAttrList="canSearchPreferenceAttrList" />
</div>
</template>
<script>
import { v4 as uuidv4 } from 'uuid'
import Expression from './expression.vue'
import { advancedExpList, compareTypeList } from './constants'
export default {
name: 'FilterComp',
components: { Expression },
props: {
canSearchPreferenceAttrList: {
type: Array,
required: true,
default: () => [],
},
expression: {
type: String,
default: '',
},
regQ: {
type: String,
default: '(?<=q=).+(?=&)|(?<=q=).+$',
},
placement: {
type: String,
default: 'bottomRight',
},
isDropdown: {
type: Boolean,
default: true,
},
},
data() {
return {
advancedExpList,
compareTypeList,
visible: false,
ruleList: [],
filterExp: '',
}
},
methods: {
visibleChange(open) {
// const regQ = /(?<=q=).+(?=&)|(?<=q=).+$/g
const exp = this.expression.match(new RegExp(this.regQ, 'g'))
? this.expression.match(new RegExp(this.regQ, 'g'))[0]
: null
if (open && exp) {
const expArray = exp.split(',').map((item) => {
let has_not = ''
const key = item.split(':')[0]
const val = item
.split(':')
.slice(1)
.join(':')
let type, property, exp, value, min, max, compareType
if (key.includes('-')) {
type = 'or'
if (key.includes('~')) {
property = key.substring(2)
has_not = '~'
} else {
property = key.substring(1)
}
} else {
type = 'and'
if (key.includes('~')) {
property = key.substring(1)
has_not = '~'
} else {
property = key
}
}
const in_reg = /(?<=\().+(?=\))/g
const range_reg = /(?<=\[).+(?=\])/g
const compare_reg = /(?<=>=|<=|>(?!=)|<(?!=)).+/
if (val === '*') {
exp = has_not + 'value'
value = ''
} else if (in_reg.test(val)) {
exp = has_not + 'in'
value = val.match(in_reg)[0]
} else if (range_reg.test(val)) {
exp = has_not + 'range'
value = val.match(range_reg)[0]
min = value.split('_TO_')[0]
max = value.split('_TO_')[1]
} else if (compare_reg.test(val)) {
exp = has_not + 'compare'
value = val.match(compare_reg)[0]
const _compareType = val.substring(0, val.match(compare_reg)['index'])
const idx = compareTypeList.findIndex((item) => item.label === _compareType)
compareType = compareTypeList[idx].value
} else if (!val.includes('*')) {
exp = has_not + 'is'
value = val
} else {
const resList = [
['contain', /(?<=\*).*(?=\*)/g],
['end_with', /(?<=\*).+/g],
['start_with', /.+(?=\*)/g],
]
for (let i = 0; i < 3; i++) {
const reg = resList[i]
if (reg[1].test(val)) {
exp = has_not + reg[0]
value = val.match(reg[1])[0]
break
}
}
}
return {
id: uuidv4(),
type,
property,
exp,
value,
min,
max,
compareType,
}
})
this.ruleList = [...expArray]
} else if (open) {
this.ruleList = [
{
id: uuidv4(),
type: 'and',
property: this.canSearchPreferenceAttrList[0].name,
exp: 'is',
value: null,
},
]
}
},
handleClear() {
this.ruleList = [
{
id: uuidv4(),
type: 'and',
property: this.canSearchPreferenceAttrList[0].name,
exp: 'is',
value: null,
},
]
this.filterExp = ''
this.visible = false
this.$emit('setExpFromFilter', this.filterExp)
},
handleSubmit() {
if (this.ruleList && this.ruleList.length) {
this.ruleList[0].type = 'and' // 增删后以防万一第一个不是and
this.filterExp = ''
const expList = this.ruleList.map((rule) => {
let singleRuleExp = ''
let _exp = rule.exp
if (rule.type === 'or') {
singleRuleExp += '-'
}
if (rule.exp.includes('~')) {
singleRuleExp += '~'
_exp = rule.exp.split('~')[1]
}
singleRuleExp += `${rule.property}:`
if (_exp === 'is') {
singleRuleExp += `${rule.value ?? ''}`
}
if (_exp === 'contain') {
singleRuleExp += `*${rule.value ?? ''}*`
}
if (_exp === 'start_with') {
singleRuleExp += `${rule.value ?? ''}*`
}
if (_exp === 'end_with') {
singleRuleExp += `*${rule.value ?? ''}`
}
if (_exp === 'value') {
singleRuleExp += `*`
}
if (_exp === 'in') {
singleRuleExp += `(${rule.value ?? ''})`
}
if (_exp === 'range') {
singleRuleExp += `[${rule.min}_TO_${rule.max}]`
}
if (_exp === 'compare') {
const idx = compareTypeList.findIndex((item) => item.value === rule.compareType)
singleRuleExp += `${compareTypeList[idx].label}${rule.value ?? ''}`
}
return singleRuleExp
})
this.filterExp = expList.join(',')
this.$emit('setExpFromFilter', this.filterExp)
} else {
this.$emit('setExpFromFilter', '')
}
this.visible = false
},
},
}
</script>
<style lang="less" scoped>
.table-filter {
.table-filter-add {
margin-top: 10px;
& > a {
padding: 2px 8px;
&:hover {
background-color: #f0faff;
border-radius: 5px;
}
}
}
.table-filter-extra-icon {
padding: 0px 2px;
&:hover {
display: inline-block;
border-radius: 5px;
background-color: #f0faff;
}
}
}
</style>
<style lang="less">
.table-filter-extra-operation {
.ant-popover-inner-content {
padding: 3px 4px;
.operation {
cursor: pointer;
width: 90px;
height: 30px;
line-height: 30px;
padding: 3px 4px;
border-radius: 5px;
transition: all 0.3s;
&:hover {
background-color: #f0faff;
}
> .anticon {
margin-right: 10px;
}
}
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<span>
<ops-icon :type="getPropertyIcon(attr)" />
</span>
</template>
<script>
export default {
name: 'ValueTypeIcon',
props: {
attr: {
type: Object,
default: () => {},
},
},
methods: {
getPropertyStyle(attr) {
switch (attr.value_type) {
case '0':
return { color: '#cf1322', backgroundColor: '#fff1f0' }
case '1':
return { color: '#d4b106', backgroundColor: '#feffe6' }
case '2':
return { color: '#d46b08', backgroundColor: '#fff7e6' }
case '3':
return { color: '#531dab', backgroundColor: '#f9f0ff' }
case '4':
return { color: '#389e0d', backgroundColor: '#f6ffed' }
case '5':
return { color: '#08979c', backgroundColor: '#e6fffb' }
case '6':
return { color: '#c41d7f', backgroundColor: '#fff0f6' }
}
},
getPropertyIcon(attr) {
switch (attr.value_type) {
case '0':
return 'icon-xianxing-shishu'
case '1':
return 'icon-xianxing-fudianshu'
case '2':
return 'icon-xianxing-wenben'
case '3':
return 'icon-xianxing-datetime'
case '4':
return 'icon-xianxing-date'
case '5':
return 'icon-xianxing-time'
case '6':
return 'icon-xianxing-json'
}
},
},
}
</script>
<style></style>

View File

@@ -0,0 +1,24 @@
<template>
<div class="ops-card-title">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'CardTitle',
}
</script>
<style lang="less" scoped>
.ops-card-title {
border-top-left-radius: 15px;
font-size: 1vw;
height: 2.2vw;
color: #011d93;
background: linear-gradient(270deg, rgba(206, 226, 255, 0) -6.74%, #d2e4ff 96.74%);
padding: 5px 10px;
display: inline-block;
font-weight: 500;
}
</style>

View File

@@ -0,0 +1,2 @@
import CardTitle from './CardTitle'
export default CardTitle

View File

@@ -1,62 +0,0 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:data="data"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
export default {
name: 'Bar',
props: {
title: {
type: String,
default: ''
},
data: {
type: Array,
default: () => {
return []
}
},
scale: {
type: Array,
default: () => {
return [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 22
}]
}
},
tooltip: {
type: Array,
default: () => {
return [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
}
}
},
data () {
return {
}
}
}
</script>

View File

@@ -1,120 +0,0 @@
<template>
<a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
<div class="chart-card-header">
<div class="meta">
<span class="chart-card-title">
<slot name="title">
{{ title }}
</slot>
</span>
<span class="chart-card-action">
<slot name="action"></slot>
</span>
</div>
<div class="total">
<slot name="total">
<span>{{ typeof total === 'function' && total() || total }}</span>
</slot>
</div>
</div>
<div class="chart-card-content">
<div class="content-fix">
<slot></slot>
</div>
</div>
<div class="chart-card-footer">
<div class="field">
<slot name="footer"></slot>
</div>
</div>
</a-card>
</template>
<script>
export default {
name: 'ChartCard',
props: {
title: {
type: String,
default: ''
},
total: {
type: [Function, Number, String],
required: false,
default: null
},
loading: {
type: Boolean,
default: false
}
}
}
</script>
<style lang="less" scoped>
.chart-card-header {
position: relative;
overflow: hidden;
width: 100%;
.meta {
position: relative;
overflow: hidden;
width: 100%;
color: rgba(0, 0, 0, .45);
font-size: 14px;
line-height: 22px;
}
}
.chart-card-action {
cursor: pointer;
position: absolute;
top: 0;
right: 0;
}
.chart-card-footer {
border-top: 1px solid #e8e8e8;
padding-top: 9px;
margin-top: 8px;
> * {
position: relative;
}
.field {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
}
}
.chart-card-content {
margin-bottom: 12px;
position: relative;
height: 46px;
width: 100%;
.content-fix {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
}
.total {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
white-space: nowrap;
color: #000;
margin-top: 4px;
margin-bottom: 0;
font-size: 30px;
line-height: 38px;
height: 38px;
}
</style>

View File

@@ -1,67 +0,0 @@
<template>
<div>
<v-chart
:forceFit="true"
:height="height"
:width="width"
:data="data"
:scale="scale"
:padding="0">
<v-tooltip />
<v-interval
:shape="['liquid-fill-gauge']"
position="transfer*value"
color=""
:v-style="{
lineWidth: 10,
opacity: 0.75
}"
:tooltip="[
'transfer*value',
(transfer, value) => {
return {
name: transfer,
value,
};
},
]"
></v-interval>
<v-guide
v-for="(row, index) in data"
:key="index"
type="text"
:top="true"
:position="{
gender: row.transfer,
value: 45
}"
:content="row.value + '%'"
:v-style="{
fontSize: 100,
textAlign: 'center',
opacity: 0.75,
}"
/>
</v-chart>
</div>
</template>
<script>
export default {
name: 'Liquid',
props: {
height: {
type: Number,
default: 0
},
width: {
type: Number,
default: 0
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,56 +0,0 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 0, 18, 0]">
<v-tooltip />
<v-smooth-area position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
import moment from 'moment'
const data = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 22
}]
export default {
name: 'MiniArea',
data () {
return {
data,
tooltip,
scale,
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "chart";
</style>

View File

@@ -1,57 +0,0 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]">
<v-tooltip />
<v-bar position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
import moment from 'moment'
const data = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 30
}]
export default {
name: 'MiniBar',
data () {
return {
data,
tooltip,
scale,
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "chart";
</style>

View File

@@ -1,75 +0,0 @@
<template>
<div class="chart-mini-progress">
<div class="target" :style="{ left: target + '%'}">
<span :style="{ backgroundColor: color }" />
<span :style="{ backgroundColor: color }"/>
</div>
<div class="progress-wrapper">
<div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height }"></div>
</div>
</div>
</template>
<script>
export default {
name: 'MiniProgress',
props: {
target: {
type: Number,
default: 0
},
height: {
type: String,
default: '10px'
},
color: {
type: String,
default: '#13C2C2'
},
percentage: {
type: Number,
default: 0
}
}
}
</script>
<style lang="less" scoped>
.chart-mini-progress {
padding: 5px 0;
position: relative;
width: 100%;
.target {
position: absolute;
top: 0;
bottom: 0;
span {
border-radius: 100px;
position: absolute;
top: 0;
left: 0;
height: 4px;
width: 2px;
&:last-child {
top: auto;
bottom: 0;
}
}
}
.progress-wrapper {
background-color: #f5f5f5;
position: relative;
.progress {
transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
border-radius: 1px 0 0 1px;
background-color: #1890ff;
width: 0;
height: 100%;
}
}
}
</style>

View File

@@ -1,40 +0,0 @@
<template>
<div :class="prefixCls">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="100" :data="dataSource" :scale="scale" :padding="[36, 0, 18, 0]">
<v-tooltip />
<v-smooth-line position="x*y" :size="2" />
<v-smooth-area position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
export default {
name: 'MiniSmoothArea',
props: {
prefixCls: {
type: String,
default: 'ant-pro-smooth-area'
},
scale: {
type: [Object, Array],
required: true
},
dataSource: {
type: Array,
required: true
}
},
data () {
return {
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "smooth.area.less";
</style>

View File

@@ -1,68 +0,0 @@
<template>
<v-chart :forceFit="true" height="400" :data="data" :padding="[20, 20, 95, 20]" :scale="scale">
<v-tooltip></v-tooltip>
<v-axis :dataKey="axis1Opts.dataKey" :line="axis1Opts.line" :tickLine="axis1Opts.tickLine" :grid="axis1Opts.grid" />
<v-axis :dataKey="axis2Opts.dataKey" :line="axis2Opts.line" :tickLine="axis2Opts.tickLine" :grid="axis2Opts.grid" />
<v-legend dataKey="user" marker="circle" :offset="30" />
<v-coord type="polar" radius="0.8" />
<v-line position="item*score" color="user" :size="2" />
<v-point position="item*score" color="user" :size="4" shape="circle" />
</v-chart>
</template>
<script>
const axis1Opts = {
dataKey: 'item',
line: null,
tickLine: null,
grid: {
lineStyle: {
lineDash: null
},
hideFirstLine: false
}
}
const axis2Opts = {
dataKey: 'score',
line: null,
tickLine: null,
grid: {
type: 'polygon',
lineStyle: {
lineDash: null
}
}
}
const scale = [
{
dataKey: 'score',
min: 0,
max: 80
}, {
dataKey: 'user',
alias: '类型'
}
]
export default {
name: 'Radar',
props: {
data: {
type: Array,
default: null
}
},
data () {
return {
axis1Opts,
axis2Opts,
scale
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,77 +0,0 @@
<template>
<div class="rank">
<h4 class="title">{{ title }}</h4>
<ul class="list">
<li :key="index" v-for="(item, index) in list">
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
<span>{{ item.name }}</span>
<span>{{ item.total }}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'RankList',
// ['title', 'list']
props: {
title: {
type: String,
default: ''
},
list: {
type: Array,
default: null
}
}
}
</script>
<style lang="less" scoped>
.rank {
padding: 0 32px 32px 72px;
.list {
margin: 25px 0 0;
padding: 0;
list-style: none;
li {
margin-top: 16px;
span {
color: rgba(0, 0, 0, .65);
font-size: 14px;
line-height: 22px;
&:first-child {
background-color: #f5f5f5;
border-radius: 20px;
display: inline-block;
font-size: 12px;
font-weight: 600;
margin-right: 24px;
height: 20px;
line-height: 20px;
width: 20px;
text-align: center;
}
&.active {
background-color: #314659;
color: #fff;
}
&:last-child {
float: right;
}
}
}
}
}
.mobile .rank {
padding: 0 32px 32px 32px;
}
</style>

View File

@@ -1,113 +0,0 @@
<template>
<v-chart :width="width" :height="height" :padding="[0]" :data="data" :scale="scale">
<v-tooltip :show-title="false" />
<v-coord type="rect" direction="TL" />
<v-point position="x*y" color="category" shape="cloud" tooltip="value*category" />
</v-chart>
</template>
<script>
import { registerShape } from 'viser-vue'
const DataSet = require('@antv/data-set')
const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'
const scale = [
{ dataKey: 'x', nice: false },
{ dataKey: 'y', nice: false }
]
registerShape('point', 'cloud', {
draw (cfg, container) {
return container.addShape('text', {
attrs: {
fillOpacity: cfg.opacity,
fontSize: cfg.origin._origin.size,
rotate: cfg.origin._origin.rotate,
text: cfg.origin._origin.text,
textAlign: 'center',
fontFamily: cfg.origin._origin.font,
fill: cfg.color,
textBaseline: 'Alphabetic',
...cfg.style,
x: cfg.x,
y: cfg.y
}
})
}
})
export default {
name: 'TagCloud',
props: {
tagList: {
type: Array,
required: true
},
height: {
type: Number,
default: 400
},
width: {
type: Number,
default: 640
}
},
data () {
return {
data: [],
scale
}
},
watch: {
tagList: function (val) {
if (val.length > 0) {
this.initTagCloud(val)
}
}
},
mounted () {
if (this.tagList.length > 0) {
this.initTagCloud(this.tagList)
}
},
methods: {
initTagCloud (dataSource) {
const { height, width } = this
const dv = new DataSet.View().source(dataSource)
const range = dv.range('value')
const min = range[0]
const max = range[1]
const imageMask = new Image()
imageMask.crossOrigin = ''
imageMask.src = imgUrl
imageMask.onload = () => {
dv.transform({
type: 'tag-cloud',
fields: ['name', 'value'],
size: [width, height],
imageMask,
font: 'Verdana',
padding: 0,
timeInterval: 5000, // max execute time
rotate () {
let random = ~~(Math.random() * 4) % 4
if (random === 2) {
random = 0
}
return random * 90 // 0, 90, 270
},
fontSize (d) {
if (d.value) {
return ((d.value - min) / (max - min)) * (32 - 8) + 8
}
return 0
}
})
this.data = dv.rows
}
}
}
}
</script>

View File

@@ -1,64 +0,0 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:data="data"
:scale="scale"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
title: '日期(天)',
alias: '日期(天)',
min: 2
}, {
dataKey: 'y',
title: '流量(Gb)',
alias: '流量(Gb)',
min: 1
}]
export default {
name: 'Bar',
props: {
title: {
type: String,
default: ''
}
},
data () {
return {
data: [],
scale,
tooltip
}
},
created () {
this.getMonthBar()
},
methods: {
getMonthBar () {
this.$http.get('/analysis/month-bar')
.then(res => {
this.data = res.result
})
}
}
}
</script>

View File

@@ -1,82 +0,0 @@
<template>
<div class="chart-trend">
{{ term }}
<span>{{ rate }}%</span>
<span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span>
</div>
</template>
<script>
export default {
name: 'Trend',
props: {
term: {
type: String,
default: '',
required: true
},
percentage: {
type: Number,
default: null
},
type: {
type: Boolean,
default: null
},
target: {
type: Number,
default: 0
},
value: {
type: Number,
default: 0
},
fixed: {
type: Number,
default: 2
}
},
data () {
return {
trend: this.type && 'up' || 'down',
rate: this.percentage
}
},
created () {
const type = this.type === null ? this.value >= this.target : this.type
this.trend = type ? 'up' : 'down'
this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed)
}
}
</script>
<style lang="less" scoped>
.chart-trend {
display: inline-block;
font-size: 14px;
line-height: 22px;
.trend-icon {
font-size: 12px;
&.up, &.down {
margin-left: 4px;
position: relative;
top: 1px;
i {
font-size: 12px;
transform: scale(.83);
}
}
&.up {
color: #f5222d;
}
&.down {
color: #52c41a;
top: -1px;
}
}
}
</style>

View File

@@ -1,13 +0,0 @@
.antv-chart-mini {
position: relative;
width: 100%;
.chart-wrapper {
position: absolute;
bottom: -28px;
width: 100%;
/* margin: 0 -5px;
overflow: hidden;*/
}
}

Some files were not shown because too many files have changed in this diff Show More