Merge pull request 'eslint' (#2) from dev-qsh into master

Reviewed-on: http://114.55.169.15:3000/qiushanhe/dm-manage-web/pulls/2
pull/3/head
qiushanhe 2 years ago
commit 58d702f6f7
  1. 8
      .eslintrc.js
  2. 272
      public/index.html
  3. 208
      public/loading/index.js
  4. 477
      public/loading/prefixfree.min.js
  5. BIN
      public/logo.png
  6. 16
      src/api/login.js
  7. 6
      src/api/menu.js
  8. 16
      src/api/monitor/cache.js
  9. 23
      src/api/monitor/job.js
  10. 8
      src/api/monitor/jobLog.js
  11. 10
      src/api/monitor/logininfor.js
  12. 6
      src/api/monitor/online.js
  13. 8
      src/api/monitor/operlog.js
  14. 6
      src/api/monitor/server.js
  15. 14
      src/api/sch/classType.js
  16. 8
      src/api/sch/place.js
  17. 26
      src/api/sch/school.js
  18. 16
      src/api/system/config.js
  19. 16
      src/api/system/dept.js
  20. 14
      src/api/system/dict/data.js
  21. 18
      src/api/system/dict/type.js
  22. 30
      src/api/system/employee.js
  23. 18
      src/api/system/menu.js
  24. 14
      src/api/system/notice.js
  25. 12
      src/api/system/post.js
  26. 34
      src/api/system/role.js
  27. 38
      src/api/system/user.js
  28. 20
      src/api/tool/gen.js
  29. 69
      src/api/zs/clue.js
  30. 30
      src/api/zs/sign.js
  31. 12
      src/assets/icons/index.js
  32. 37
      src/components/Breadcrumb/index.vue
  33. 297
      src/components/Crontab/day.vue
  34. 211
      src/components/Crontab/hour.vue
  35. 332
      src/components/Crontab/index.vue
  36. 213
      src/components/Crontab/min.vue
  37. 210
      src/components/Crontab/month.vue
  38. 1103
      src/components/Crontab/result.vue
  39. 216
      src/components/Crontab/second.vue
  40. 369
      src/components/Crontab/week.vue
  41. 240
      src/components/Crontab/year.vue
  42. 114
      src/components/CustomColumnTable/index.vue
  43. 50
      src/components/DictData/index.js
  44. 29
      src/components/DictTag/index.vue
  45. 213
      src/components/Editor/index.vue
  46. 79
      src/components/FileUpload/index.vue
  47. 13
      src/components/Hamburger/index.vue
  48. 101
      src/components/HeaderSearch/index.vue
  49. 58
      src/components/IconSelect/index.vue
  50. 15
      src/components/IconSelect/requireIcons.js
  51. 33
      src/components/ImagePreview/index.vue
  52. 115
      src/components/ImageUpload/index.vue
  53. 40
      src/components/Pagination/index.vue
  54. 2
      src/components/PanThumb/index.vue
  55. 2
      src/components/ParentView/index.vue
  56. 38
      src/components/RightPanel/index.vue
  57. 55
      src/components/RightToolbar/index.vue
  58. 21
      src/components/RuoYi/Doc/index.vue
  59. 21
      src/components/RuoYi/Git/index.vue
  60. 24
      src/components/Screenfull/index.vue
  61. 23
      src/components/SizeSelect/index.vue
  62. 16
      src/components/SvgIcon/index.vue
  63. 163
      src/components/ThemePicker/index.vue
  64. 70
      src/components/TopNav/index.vue
  65. 13
      src/components/iFrame/index.vue
  66. 6
      src/directive/click/throttle.js
  67. 21
      src/directive/dialog/drag.js
  68. 66
      src/directive/dialog/dragHeight.js
  69. 58
      src/directive/dialog/dragWidth.js
  70. 40
      src/directive/index.js
  71. 19
      src/directive/input/trim.js
  72. 24
      src/directive/module/clipboard.js
  73. 26
      src/directive/permission/hasPermi.js
  74. 26
      src/directive/permission/hasRole.js
  75. 34
      src/global/components.js
  76. 11
      src/global/func.js
  77. 2
      src/global/global.js
  78. 8
      src/global/index.js
  79. 14
      src/layout/components/IframeToggle/index.vue
  80. 20
      src/layout/components/InnerLink/index.vue
  81. 2
      src/layout/components/Navbar.vue
  82. 164
      src/layout/components/Settings/index.vue
  83. 16
      src/layout/components/Sidebar/FixiOSBug.js
  84. 19
      src/layout/components/Sidebar/Item.vue
  85. 14
      src/layout/components/Sidebar/Link.vue
  86. 53
      src/layout/components/Sidebar/SidebarItem.vue
  87. 82
      src/layout/components/Sidebar/index.vue
  88. 54
      src/layout/components/TagsView/ScrollPane.vue
  89. 179
      src/layout/components/TagsView/index.vue
  90. 10
      src/layout/components/index.js
  91. 104
      src/layout/index.vue
  92. 30
      src/layout/mixin/ResizeHandler.js
  93. 29
      src/main.js
  94. 58
      src/plugins/cache.js
  95. 44
      src/plugins/modal.js
  96. 19
      src/plugins/tab.js
  97. 126
      src/router/index.js
  98. 2
      src/settings.js
  99. 44
      src/store/modules/app.js
  100. 30
      src/store/modules/dict.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -24,7 +24,7 @@ module.exports = {
'vue/max-attributes-per-line': [
2,
{
singleline: 10, // 当开始标签位于单行时,每行的最大属性数
singleline: 20, // 当开始标签位于单行时,每行的最大属性数
// 当开始标签位于多行时,每行的最大属性数
multiline: {
max: 1,
@ -75,7 +75,7 @@ module.exports = {
curly: [2, 'multi-line'], // 强制所有控制语句使用一致的括号风格
'dot-location': [2, 'property'], // 在点之前和之后执行一致的换行符
'eol-last': 2, // 要求或禁止文件末尾存在空行
eqeqeq: ['error', 'always', { null: 'ignore' }], // 要求使用 === 和 !==
// eqeqeq: ['error', 'never', { null: 'ignore' }], // 要求使用 === 和 !==
// 强制 generator 函数中 * 号周围使用一致的空格
'generator-star-spacing': [
2,
@ -290,6 +290,8 @@ module.exports = {
objectsInObjects: false
}
],
'array-bracket-spacing': [2, 'never'] // 该规则在数组括号内强制实现一致的间距
'array-bracket-spacing': [2, 'never'], // 该规则在数组括号内强制实现一致的间距
'vue/require-default-prop': 'off',
'vue/require-prop-types': 'off'
}
};

@ -1,208 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= webpackConfig.name %></title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999999;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-webkit-animation: spin 2s linear infinite;
-ms-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite;
-o-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
z-index: 1001;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-webkit-animation: spin 3s linear infinite;
-moz-animation: spin 3s linear infinite;
-o-animation: spin 3s linear infinite;
-ms-animation: spin 3s linear infinite;
animation: spin 3s linear infinite;
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-moz-animation: spin 1.5s linear infinite;
-o-animation: spin 1.5s linear infinite;
-ms-animation: spin 1.5s linear infinite;
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
<!--[if lt IE 11
]><script>
window.location.href = '/html/ie.html';
</script><!
[endif]-->
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
.logo {
position: absolute;
display: block;
left: 50%;
top: 50%;
width: 100px;
/* height: 162px; */
transform: translate3d(-50%, -80px, 0);
animation: twinkling 1.2s infinite ease-in-out;
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
/* .animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
} */
@keyframes twinkling {
0% {
opacity: 0.8;
}
50% {
opacity: 0.4;
}
100% {
opacity: 0.8;
}
}
.loading {
position: absolute;
display: block;
left: 50%;
top: 50%;
transform: translate3d(-50%, 80px, 0);
color: #fefeff;
font-size: 14px;
}
canvas {
display: block;
left: 50%;
position: absolute;
top: 50%;
transform: translate3d(-50%, 100px, 0);
}
}
#loader-wrapper .loader-section {
position: fixed;
top: 0;
width: 51%;
height: 100%;
background: #7171C6;
z-index: 1000;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
#loader-wrapper .loader-section.section-left {
left: 0;
}
#loader-wrapper .loader-section.section-right {
right: 0;
}
.loaded #loader-wrapper .loader-section.section-left {
-webkit-transform: translateX(-100%);
-ms-transform: translateX(-100%);
transform: translateX(-100%);
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader-wrapper .loader-section.section-right {
-webkit-transform: translateX(100%);
-ms-transform: translateX(100%);
transform: translateX(100%);
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader {
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.loaded #loader-wrapper {
visibility: hidden;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
-webkit-transition: all 0.3s 1s ease-out;
transition: all 0.3s 1s ease-out;
}
.no-js #loader-wrapper {
display: none;
}
.no-js h1 {
color: #222222;
}
#loader-wrapper .load_title {
font-family: 'Open Sans';
color: #FFF;
font-size: 19px;
width: 100%;
text-align: center;
z-index: 9999999999999;
position: absolute;
top: 60%;
opacity: 1;
line-height: 30px;
}
#loader-wrapper .load_title span {
font-weight: normal;
font-style: italic;
font-size: 13px;
color: #FFF;
opacity: 0.5;
}
</style>
#loader-wrapper {
position: relative;
width: 100%;
height: 100%;
background: #1a1a34;
z-index: 1000;
}
</style>
<script src="/loading/prefixfree.min.js"></script>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
<div id="loader-wrapper">
<img class="logo animated" src="/logo.png" alt="" srcset="" />
<div class="loading">资源加载中...</div>
</div>
</div>
<script src="/loading/index.js"></script>
</body>
</html>

@ -0,0 +1,208 @@
/* ========================================================*/
/* Light Loader
/*========================================================*/
var lightLoader = function (c, cw, ch) {
var _this = this;
this.c = c;
this.ctx = c.getContext('2d');
this.cw = cw;
this.ch = ch;
this.loaded = 0;
this.loaderSpeed = 1.5;
this.loaderHeight = 8;
this.loaderWidth = 428;
this.loader = {
x: this.cw / 2 - this.loaderWidth / 2,
y: this.ch / 2 - this.loaderHeight / 2
};
this.particles = [];
this.particleLift = 180;
this.gravity = 0.15;
this.particleRate = 8;
/* ========================================================*/
/* Initialize
/*========================================================*/
this.init = function () {
this.loop();
};
/* ========================================================*/
/* Utility Functions
/*========================================================*/
this.rand = function (rMi, rMa) {
return ~~(Math.random() * (rMa - rMi + 1) + rMi);
};
this.hitTest = function (x1, y1, w1, h1, x2, y2, w2, h2) {
return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);
};
/* ========================================================*/
/* Update Loader
/*========================================================*/
this.updateLoader = function () {
if (this.loaded < 100) {
this.loaded += this.loaderSpeed;
} else {
this.loaded = 0;
}
};
/* ========================================================*/
/* Render Loader
/*========================================================*/
this.renderLoader = function () {
this.ctx.fillStyle = '#2F2F47';
this.ctx.fillRect(this.loader.x, this.loader.y, this.loaderWidth, this.loaderHeight);
var newWidth = (this.loaded / 100) * this.loaderWidth;
var linearGrad = this.ctx.createLinearGradient(0, 0, this.loaderWidth, 0);
linearGrad.addColorStop(0.0, '#24DED0');
linearGrad.addColorStop(1.0, '#1490EA');
this.ctx.fillStyle = linearGrad;
this.ctx.fillRect(this.loader.x, this.loader.y, newWidth, this.loaderHeight);
// this.ctx.fillStyle = '#2F2F47';
// this.ctx.fillRect(
// this.loader.x,
// this.loader.y,
// newWidth,
// this.loaderHeight
// );
};
/* ========================================================*/
/* Particles
/*========================================================*/
this.Particle = function () {
this.x = _this.loader.x + (_this.loaded / 100) * _this.loaderWidth - _this.rand(0, 1);
this.y = _this.ch / 2 + _this.rand(0, _this.loaderHeight) - _this.loaderHeight / 2;
this.vx = (_this.rand(0, 4) - 2) / 100;
this.vy = (_this.rand(0, _this.particleLift) - _this.particleLift * 2) / 100;
this.width = _this.rand(1, 4) / 2;
this.height = _this.rand(1, 4) / 2;
};
this.Particle.prototype.update = function (i) {
this.vx += (_this.rand(0, 6) - 3) / 100;
this.vy += _this.gravity;
this.x += this.vx;
this.y += this.vy;
if (this.y > _this.ch) {
_this.particles.splice(i, 1);
}
};
this.Particle.prototype.render = function () {
_this.ctx.fillStyle = 'rgba(50, 213, 203, 0.4)';
_this.ctx.fillRect(this.x, this.y, this.width, this.height);
};
this.createParticles = function () {
var i = this.particleRate;
while (i--) {
this.particles.push(new this.Particle());
}
};
this.updateParticles = function () {
var i = this.particles.length;
while (i--) {
var p = this.particles[i];
p.update(i);
}
};
this.renderParticles = function () {
var i = this.particles.length;
while (i--) {
var p = this.particles[i];
p.render();
}
};
/* ========================================================*/
/* Clear Canvas
/*========================================================*/
this.clearCanvas = function () {
this.ctx.globalCompositeOperation = 'source-over';
this.ctx.clearRect(0, 0, this.cw, this.ch);
this.ctx.globalCompositeOperation = 'lighter';
};
/* ========================================================*/
/* Animation Loop
/*========================================================*/
this.loop = function () {
var loopIt = function () {
requestAnimationFrame(loopIt, _this.c);
_this.clearCanvas();
_this.createParticles();
_this.updateLoader();
_this.updateParticles();
_this.renderLoader();
_this.renderParticles();
};
loopIt();
};
};
/* ========================================================*/
/* Check Canvas Support
/*========================================================*/
var isCanvasSupported = function () {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
};
/* ========================================================*/
/* Setup requestAnimationFrame
/*========================================================*/
var setupRAF = function () {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function () {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
};
/* ========================================================*/
/* Define Canvas and Initialize
/*========================================================*/
if (isCanvasSupported) {
var c = document.createElement('canvas');
c.width = 428;
c.height = 100;
var cw = c.width;
var ch = c.height;
// document.body.appendChild(c);
document.getElementById('loader-wrapper').appendChild(c);
var cl = new lightLoader(c, cw, ch);
setupRAF();
cl.init();
}

@ -0,0 +1,477 @@
(function () {
if (!window.addEventListener) {
return;
}
var self = (window.StyleFix = {
link: function (link) {
try {
// Ignore stylesheets with data-noprefix attribute as well as alternate stylesheets
if (link.rel !== 'stylesheet' || link.hasAttribute('data-noprefix')) {
return;
}
} catch (e) {
return;
}
var url = link.href || link.getAttribute('data-href');
var base = url.replace(/[^\/]+$/, '');
var base_scheme = (/^[a-z]{3,10}:/.exec(base) || [''])[0];
var base_domain = (/^[a-z]{3,10}:\/\/[^\/]+/.exec(base) || [''])[0];
var base_query = /^([^?]*)\??/.exec(url)[1];
var parent = link.parentNode;
var xhr = new XMLHttpRequest();
var process;
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
process();
}
};
process = function () {
var css = xhr.responseText;
if (css && link.parentNode && (!xhr.status || xhr.status < 400 || xhr.status > 600)) {
css = self.fix(css, true, link);
// Convert relative URLs to absolute, if needed
if (base) {
css = css.replace(/url\(\s*?((?:"|')?)(.+?)\1\s*?\)/gi, function ($0, quote, url) {
if (/^([a-z]{3,10}:|#)/i.test(url)) {
// Absolute & or hash-relative
return $0;
} else if (/^\/\//.test(url)) {
// Scheme-relative
// May contain sequences like /../ and /./ but those DO work
return 'url("' + base_scheme + url + '")';
} else if (/^\//.test(url)) {
// Domain-relative
return 'url("' + base_domain + url + '")';
} else if (/^\?/.test(url)) {
// Query-relative
return 'url("' + base_query + url + '")';
} else {
// Path-relative
return 'url("' + base + url + '")';
}
});
// behavior URLs shoudn’t be converted (Issue #19)
// base should be escaped before added to RegExp (Issue #81)
var escaped_base = base.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
css = css.replace(RegExp('\\b(behavior:\\s*?url\\(\'?"?)' + escaped_base, 'gi'), '$1');
}
var style = document.createElement('style');
style.textContent = css;
style.media = link.media;
style.disabled = link.disabled;
style.setAttribute('data-href', link.getAttribute('href'));
parent.insertBefore(style, link);
parent.removeChild(link);
style.media = link.media; // Duplicate is intentional. See issue #31
}
};
try {
xhr.open('GET', url);
xhr.send(null);
} catch (e) {
// Fallback to XDomainRequest if available
if (typeof XDomainRequest !== 'undefined') {
xhr = new XDomainRequest();
xhr.onerror = xhr.onprogress = function () {};
xhr.onload = process;
xhr.open('GET', url);
xhr.send(null);
}
}
link.setAttribute('data-inprogress', '');
},
styleElement: function (style) {
if (style.hasAttribute('data-noprefix')) {
return;
}
var disabled = style.disabled;
style.textContent = self.fix(style.textContent, true, style);
style.disabled = disabled;
},
styleAttribute: function (element) {
var css = element.getAttribute('style');
css = self.fix(css, false, element);
element.setAttribute('style', css);
},
process: function () {
// Linked stylesheets
$('link[rel="stylesheet"]:not([data-inprogress])').forEach(StyleFix.link);
// Inline stylesheets
$('style').forEach(StyleFix.styleElement);
// Inline styles
$('[style]').forEach(StyleFix.styleAttribute);
},
register: function (fixer, index) {
(self.fixers = self.fixers || []).splice(index === undefined ? self.fixers.length : index, 0, fixer);
},
fix: function (css, raw, element) {
for (var i = 0; i < self.fixers.length; i++) {
css = self.fixers[i](css, raw, element) || css;
}
return css;
},
camelCase: function (str) {
return str
.replace(/-([a-z])/g, function ($0, $1) {
return $1.toUpperCase();
})
.replace('-', '');
},
deCamelCase: function (str) {
return str.replace(/[A-Z]/g, function ($0) {
return '-' + $0.toLowerCase();
});
}
});
/** ************************************
* Process styles
**************************************/
(function () {
setTimeout(function () {
$('link[rel="stylesheet"]').forEach(StyleFix.link);
}, 10);
document.addEventListener('DOMContentLoaded', StyleFix.process, false);
})();
function $(expr, con) {
return [].slice.call((con || document).querySelectorAll(expr));
}
})();
/**
* PrefixFree
*/
(function (root) {
if (!window.StyleFix || !window.getComputedStyle) {
return;
}
// Private helper
function fix(what, before, after, replacement, css) {
what = self[what];
if (what.length) {
var regex = RegExp(before + '(' + what.join('|') + ')' + after, 'gi');
css = css.replace(regex, replacement);
}
return css;
}
var self = (window.PrefixFree = {
prefixCSS: function (css, raw, element) {
var prefix = self.prefix;
// Gradient angles hotfix
if (self.functions.indexOf('linear-gradient') > -1) {
// Gradients are supported with a prefix, convert angles to legacy
css = css.replace(/(\s|:|,)(repeating-)?linear-gradient\(\s*(-?\d*\.?\d*)deg/gi, function ($0, delim, repeating, deg) {
return delim + (repeating || '') + 'linear-gradient(' + (90 - deg) + 'deg';
});
}
css = fix('functions', '(\\s|:|,)', '\\s*\\(', '$1' + prefix + '$2(', css);
css = fix('keywords', '(\\s|:)', '(\\s|;|\\}|$)', '$1' + prefix + '$2$3', css);
css = fix('properties', '(^|\\{|\\s|;)', '\\s*:', '$1' + prefix + '$2:', css);
// Prefix properties *inside* values (issue #8)
if (self.properties.length) {
var regex = RegExp('\\b(' + self.properties.join('|') + ')(?!:)', 'gi');
css = fix(
'valueProperties',
'\\b',
':(.+?);',
function ($0) {
return $0.replace(regex, prefix + '$1');
},
css
);
}
if (raw) {
css = fix('selectors', '', '\\b', self.prefixSelector, css);
css = fix('atrules', '@', '\\b', '@' + prefix + '$1', css);
}
// Fix double prefixing
css = css.replace(RegExp('-' + prefix, 'g'), '-');
// Prefix wildcard
css = css.replace(/-\*-(?=[a-z]+)/gi, self.prefix);
return css;
},
property: function (property) {
return (self.properties.indexOf(property) ? self.prefix : '') + property;
},
value: function (value, property) {
value = fix('functions', '(^|\\s|,)', '\\s*\\(', '$1' + self.prefix + '$2(', value);
value = fix('keywords', '(^|\\s)', '(\\s|$)', '$1' + self.prefix + '$2$3', value);
// TODO properties inside values
return value;
},
// Warning: Prefixes no matter what, even if the selector is supported prefix-less
prefixSelector: function (selector) {
return selector.replace(/^:{1,2}/, function ($0) {
return $0 + self.prefix;
});
},
// Warning: Prefixes no matter what, even if the property is supported prefix-less
prefixProperty: function (property, camelCase) {
var prefixed = self.prefix + property;
return camelCase ? StyleFix.camelCase(prefixed) : prefixed;
}
});
/** ************************************
* Properties
**************************************/
(function () {
var prefixes = {};
var properties = [];
var shorthands = {};
var style = getComputedStyle(document.documentElement, null);
var dummy = document.createElement('div').style;
// Why are we doing this instead of iterating over properties in a .style object? Cause Webkit won't iterate over those.
var iterate = function (property) {
if (property.charAt(0) === '-') {
properties.push(property);
var parts = property.split('-');
var prefix = parts[1];
// Count prefix uses
prefixes[prefix] = ++prefixes[prefix] || 1;
// This helps determining shorthands
while (parts.length > 3) {
parts.pop();
var shorthand = parts.join('-');
if (supported(shorthand) && properties.indexOf(shorthand) === -1) {
properties.push(shorthand);
}
}
}
};
var supported = function (property) {
return StyleFix.camelCase(property) in dummy;
};
// Some browsers have numerical indices for the properties, some don't
if (style.length > 0) {
for (var i = 0; i < style.length; i++) {
iterate(style[i]);
}
} else {
for (var property in style) {
iterate(StyleFix.deCamelCase(property));
}
}
// Find most frequently used prefix
var highest = { uses: 0 };
for (var prefix in prefixes) {
var uses = prefixes[prefix];
if (highest.uses < uses) {
highest = { prefix: prefix, uses: uses };
}
}
self.prefix = '-' + highest.prefix + '-';
self.Prefix = StyleFix.camelCase(self.prefix);
self.properties = [];
// Get properties ONLY supported with a prefix
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
if (property.indexOf(self.prefix) === 0) {
// we might have multiple prefixes, like Opera
var unprefixed = property.slice(self.prefix.length);
if (!supported(unprefixed)) {
self.properties.push(unprefixed);
}
}
}
// IE fix
if (self.Prefix == 'Ms' && !('transform' in dummy) && !('MsTransform' in dummy) && 'msTransform' in dummy) {
self.properties.push('transform', 'transform-origin');
}
self.properties.sort();
})();
/** ************************************
* Values
**************************************/
(function () {
// Values that might need prefixing
var functions = {
'linear-gradient': {
property: 'backgroundImage',
params: 'red, teal'
},
calc: {
property: 'width',
params: '1px + 5%'
},
element: {
property: 'backgroundImage',
params: '#foo'
},
'cross-fade': {
property: 'backgroundImage',
params: 'url(a.png), url(b.png), 50%'
}
};
functions['repeating-linear-gradient'] = functions['repeating-radial-gradient'] = functions['radial-gradient'] = functions['linear-gradient'];
// Note: The properties assigned are just to *test* support.
// The keywords will be prefixed everywhere.
var keywords = {
initial: 'color',
'zoom-in': 'cursor',
'zoom-out': 'cursor',
box: 'display',
flexbox: 'display',
'inline-flexbox': 'display',
flex: 'display',
'inline-flex': 'display',
grid: 'display',
'inline-grid': 'display',
'min-content': 'width'
};
self.functions = [];
self.keywords = [];
var style = document.createElement('div').style;
function supported(value, property) {
style[property] = '';
style[property] = value;
return !!style[property];
}
for (var func in functions) {
var test = functions[func];
var property = test.property;
var value = func + '(' + test.params + ')';
if (!supported(value, property) && supported(self.prefix + value, property)) {
// It's supported, but with a prefix
self.functions.push(func);
}
}
for (var keyword in keywords) {
var property = keywords[keyword];
if (!supported(keyword, property) && supported(self.prefix + keyword, property)) {
// It's supported, but with a prefix
self.keywords.push(keyword);
}
}
})();
/** ************************************
* Selectors and @-rules
**************************************/
(function () {
var selectors = {
':read-only': null,
':read-write': null,
':any-link': null,
'::selection': null
};
var atrules = {
keyframes: 'name',
viewport: null,
document: 'regexp(".")'
};
self.selectors = [];
self.atrules = [];
var style = root.appendChild(document.createElement('style'));
function supported(selector) {
style.textContent = selector + '{}'; // Safari 4 has issues with style.innerHTML
return !!style.sheet.cssRules.length;
}
for (var selector in selectors) {
var test = selector + (selectors[selector] ? '(' + selectors[selector] + ')' : '');
if (!supported(test) && supported(self.prefixSelector(test))) {
self.selectors.push(selector);
}
}
for (var atrule in atrules) {
var test = atrule + ' ' + (atrules[atrule] || '');
if (!supported('@' + test) && supported('@' + self.prefix + test)) {
self.atrules.push(atrule);
}
}
root.removeChild(style);
})();
// Properties that accept properties as their value
self.valueProperties = ['transition', 'transition-property'];
// Add class for current prefix
root.className += ' ' + self.prefix;
StyleFix.register(self.prefixCSS);
})(document.documentElement);

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 登录方法
export function login(username, password, code, uuid) {
@ -7,7 +7,7 @@ export function login(username, password, code, uuid) {
password,
code,
uuid
}
};
return request({
url: '/login',
headers: {
@ -15,7 +15,7 @@ export function login(username, password, code, uuid) {
},
method: 'post',
data: data
})
});
}
// 注册方法
@ -27,7 +27,7 @@ export function register(data) {
},
method: 'post',
data: data
})
});
}
// 获取用户详细信息
@ -35,7 +35,7 @@ export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
});
}
// 退出方法
@ -43,7 +43,7 @@ export function logout() {
return request({
url: '/logout',
method: 'post'
})
});
}
// 获取验证码
@ -55,5 +55,5 @@ export function getCodeImg() {
},
method: 'get',
timeout: 20000
})
}
});
}

@ -1,9 +1,9 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 获取路由
export const getRouters = () => {
return request({
url: '/getRouters',
method: 'get'
})
}
});
};

@ -1,11 +1,11 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询缓存详细
export function getCache() {
return request({
url: '/monitor/cache',
method: 'get'
})
});
}
// 查询缓存名称列表
@ -13,7 +13,7 @@ export function listCacheName() {
return request({
url: '/monitor/cache/getNames',
method: 'get'
})
});
}
// 查询缓存键名列表
@ -21,7 +21,7 @@ export function listCacheKey(cacheName) {
return request({
url: '/monitor/cache/getKeys/' + cacheName,
method: 'get'
})
});
}
// 查询缓存内容
@ -29,7 +29,7 @@ export function getCacheValue(cacheName, cacheKey) {
return request({
url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
method: 'get'
})
});
}
// 清理指定名称缓存
@ -37,7 +37,7 @@ export function clearCacheName(cacheName) {
return request({
url: '/monitor/cache/clearCacheName/' + cacheName,
method: 'delete'
})
});
}
// 清理指定键名缓存
@ -45,7 +45,7 @@ export function clearCacheKey(cacheKey) {
return request({
url: '/monitor/cache/clearCacheKey/' + cacheKey,
method: 'delete'
})
});
}
// 清理全部缓存
@ -53,5 +53,5 @@ export function clearCacheAll() {
return request({
url: '/monitor/cache/clearCacheAll',
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询定时任务调度列表
export function listJob(query) {
@ -6,7 +6,7 @@ export function listJob(query) {
url: '/monitor/job/list',
method: 'get',
params: query
})
});
}
// 查询定时任务调度详细
@ -14,7 +14,7 @@ export function getJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'get'
})
});
}
// 新增定时任务调度
@ -23,7 +23,7 @@ export function addJob(data) {
url: '/monitor/job',
method: 'post',
data: data
})
});
}
// 修改定时任务调度
@ -32,7 +32,7 @@ export function updateJob(data) {
url: '/monitor/job',
method: 'put',
data: data
})
});
}
// 删除定时任务调度
@ -40,7 +40,7 @@ export function delJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'delete'
})
});
}
// 任务状态修改
@ -48,24 +48,23 @@ export function changeJobStatus(jobId, status) {
const data = {
jobId,
status
}
};
return request({
url: '/monitor/job/changeStatus',
method: 'put',
data: data
})
});
}
// 定时任务立即执行一次
export function runJob(jobId, jobGroup) {
const data = {
jobId,
jobGroup
}
};
return request({
url: '/monitor/job/run',
method: 'put',
data: data
})
}
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询调度日志列表
export function listJobLog(query) {
@ -6,7 +6,7 @@ export function listJobLog(query) {
url: '/monitor/jobLog/list',
method: 'get',
params: query
})
});
}
// 删除调度日志
@ -14,7 +14,7 @@ export function delJobLog(jobLogId) {
return request({
url: '/monitor/jobLog/' + jobLogId,
method: 'delete'
})
});
}
// 清空调度日志
@ -22,5 +22,5 @@ export function cleanJobLog() {
return request({
url: '/monitor/jobLog/clean',
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询登录日志列表
export function list(query) {
@ -6,7 +6,7 @@ export function list(query) {
url: '/monitor/logininfor/list',
method: 'get',
params: query
})
});
}
// 删除登录日志
@ -14,7 +14,7 @@ export function delLogininfor(infoId) {
return request({
url: '/monitor/logininfor/' + infoId,
method: 'delete'
})
});
}
// 解锁用户登录状态
@ -22,7 +22,7 @@ export function unlockLogininfor(userName) {
return request({
url: '/monitor/logininfor/unlock/' + userName,
method: 'get'
})
});
}
// 清空登录日志
@ -30,5 +30,5 @@ export function cleanLogininfor() {
return request({
url: '/monitor/logininfor/clean',
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询在线用户列表
export function list(query) {
@ -6,7 +6,7 @@ export function list(query) {
url: '/monitor/online/list',
method: 'get',
params: query
})
});
}
// 强退用户
@ -14,5 +14,5 @@ export function forceLogout(tokenId) {
return request({
url: '/monitor/online/' + tokenId,
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询操作日志列表
export function list(query) {
@ -6,7 +6,7 @@ export function list(query) {
url: '/monitor/operlog/list',
method: 'get',
params: query
})
});
}
// 删除操作日志
@ -14,7 +14,7 @@ export function delOperlog(operId) {
return request({
url: '/monitor/operlog/' + operId,
method: 'delete'
})
});
}
// 清空操作日志
@ -22,5 +22,5 @@ export function cleanOperlog() {
return request({
url: '/monitor/operlog/clean',
method: 'delete'
})
});
}

@ -1,9 +1,9 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 获取服务信息
export function getServer() {
return request({
url: '/monitor/server',
method: 'get'
})
}
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询班型列表
export function getClassTypeTableList(query) {
@ -6,7 +6,7 @@ export function getClassTypeTableList(query) {
url: '/sch/classType/list',
method: 'get',
params: query
})
});
}
// 新增班型
@ -15,7 +15,7 @@ export function insertClassType(params) {
url: '/sch/classType',
method: 'post',
data: params
})
});
}
// 修改班型
export function updateClassType(params) {
@ -23,21 +23,21 @@ export function updateClassType(params) {
url: '/sch/classType',
method: 'put',
data: params
})
});
}
// 删除班型
export function deleteClassType(ids) {
return request({
url: '/sch/classType/' + ids,
method: 'delete'
})
});
}
//克隆班型
// 克隆班型
export function cloneClassType(data) {
return request({
url: '/sch/classType/clone',
method: 'post',
data: data
})
});
}

@ -1,11 +1,11 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 获取地图数据
export function getMapData() {
return request({
url: '/sch/place/list',
method: 'get'
})
});
}
// 更新驾校状态
@ -14,7 +14,7 @@ export async function updateSchoolStatus(data) {
url: '/sch/place/updateSchool',
method: 'put',
data: data
})
});
}
// 保存场地状态
@ -23,5 +23,5 @@ export function savePlace(data) {
url: '/sch/place',
method: 'post',
data: data
})
});
}

@ -1,36 +1,36 @@
import request from '@/utils/request'
import request from '@/utils/request';
export default {
pageList(data = {}) {
return request({
url: "/sch/school/list",
method: "get",
params: data,
url: '/sch/school/list',
method: 'get',
params: data
});
},
getById(id) {
return request({
url: `/sch/school/${id}`,
method: "get",
method: 'get'
});
},
add(data = {}) {
return request({
url: "/sch/school",
method: "post",
data,
url: '/sch/school',
method: 'post',
data
});
},
update(data = {}) {
return request({
url: "/sch/school",
method: "put",
data,
url: '/sch/school',
method: 'put',
data
});
},
delete(id) {
return request({
url: `/sch/school/${id}`,
method: "delete",
method: 'delete'
});
}
}
};

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询参数列表
export function listConfig(query) {
@ -6,7 +6,7 @@ export function listConfig(query) {
url: '/system/config/list',
method: 'get',
params: query
})
});
}
// 查询参数详细
@ -14,7 +14,7 @@ export function getConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'get'
})
});
}
// 根据参数键名查询参数值
@ -22,7 +22,7 @@ export function getConfigKey(configKey) {
return request({
url: '/system/config/configKey/' + configKey,
method: 'get'
})
});
}
// 新增参数配置
@ -31,7 +31,7 @@ export function addConfig(data) {
url: '/system/config',
method: 'post',
data: data
})
});
}
// 修改参数配置
@ -40,7 +40,7 @@ export function updateConfig(data) {
url: '/system/config',
method: 'put',
data: data
})
});
}
// 删除参数配置
@ -48,7 +48,7 @@ export function delConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'delete'
})
});
}
// 刷新参数缓存
@ -56,5 +56,5 @@ export function refreshCache() {
return request({
url: '/system/config/refreshCache',
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询部门列表
export function listDept(query) {
@ -6,7 +6,7 @@ export function listDept(query) {
url: '/system/dept/list',
method: 'get',
params: query
})
});
}
// 查询部门列表(排除节点)
@ -14,7 +14,7 @@ export function listDeptExcludeChild(deptId) {
return request({
url: '/system/dept/list/exclude/' + deptId,
method: 'get'
})
});
}
// 查询部门详细
@ -22,7 +22,7 @@ export function getDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'get'
})
});
}
// 新增部门
@ -31,7 +31,7 @@ export function addDept(data) {
url: '/system/dept',
method: 'post',
data: data
})
});
}
// 修改部门
@ -40,7 +40,7 @@ export function updateDept(data) {
url: '/system/dept',
method: 'put',
data: data
})
});
}
// 删除部门
@ -48,12 +48,12 @@ export function delDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'delete'
})
});
}
// 查询部门下拉树结构
export function deptTreeSelect() {
return request({
url: '/system/dept/deptTree',
method: 'get'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询字典数据列表
export function listData(query) {
@ -6,7 +6,7 @@ export function listData(query) {
url: '/system/dict/data/list',
method: 'get',
params: query
})
});
}
// 查询字典数据详细
@ -14,7 +14,7 @@ export function getData(dictCode) {
return request({
url: '/system/dict/data/' + dictCode,
method: 'get'
})
});
}
// 根据字典类型查询字典数据信息
@ -22,7 +22,7 @@ export function getDicts(dictType) {
return request({
url: '/system/dict/data/type/' + dictType,
method: 'get'
})
});
}
// 新增字典数据
@ -31,7 +31,7 @@ export function addData(data) {
url: '/system/dict/data',
method: 'post',
data: data
})
});
}
// 修改字典数据
@ -40,7 +40,7 @@ export function updateData(data) {
url: '/system/dict/data',
method: 'put',
data: data
})
});
}
// 删除字典数据
@ -48,5 +48,5 @@ export function delData(dictCode) {
return request({
url: '/system/dict/data/' + dictCode,
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询字典类型列表
export function listType(query) {
@ -6,7 +6,7 @@ export function listType(query) {
url: '/system/dict/type/list',
method: 'get',
params: query
})
});
}
// 查询字典类型详细
@ -14,7 +14,7 @@ export function getType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'get'
})
});
}
// 新增字典类型
@ -23,7 +23,7 @@ export function addType(data) {
url: '/system/dict/type',
method: 'post',
data: data
})
});
}
// 修改字典类型
@ -32,7 +32,7 @@ export function updateType(data) {
url: '/system/dict/type',
method: 'put',
data: data
})
});
}
// 删除字典类型
@ -40,7 +40,7 @@ export function delType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'delete'
})
});
}
// 刷新字典缓存
@ -48,7 +48,7 @@ export function refreshCache() {
return request({
url: '/system/dict/type/refreshCache',
method: 'delete'
})
});
}
// 获取字典选择框列表
@ -56,5 +56,5 @@ export function optionselect() {
return request({
url: '/system/dict/type/optionselect',
method: 'get'
})
}
});
}

@ -1,42 +1,42 @@
import request from '@/utils/request'
import request from '@/utils/request';
export default {
pageList(data = {}) {
return request({
url: "/system/employee/list",
method: "get",
params: data,
url: '/system/employee/list',
method: 'get',
params: data
});
},
getById(id) {
return request({
url: `/system/employee/${id}`,
method: "get",
method: 'get'
});
},
add(data = {}) {
return request({
url: "/system/employee",
method: "post",
data,
url: '/system/employee',
method: 'post',
data
});
},
update(data = {}) {
return request({
url: "/system/employee",
method: "put",
data,
url: '/system/employee',
method: 'put',
data
});
},
delete(id) {
return request({
url: `/system/employee/${id}`,
method: "delete",
method: 'delete'
});
},
getEmployee() {
return request({
url: "/system/employee/getEmployees",
method: "get"
url: '/system/employee/getEmployees',
method: 'get'
});
}
}
};

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询菜单列表
export function listMenu(query) {
@ -6,7 +6,7 @@ export function listMenu(query) {
url: '/system/menu/list',
method: 'get',
params: query
})
});
}
// 查询菜单详细
@ -14,7 +14,7 @@ export function getMenu(menuId) {
return request({
url: '/system/menu/' + menuId,
method: 'get'
})
});
}
// 查询菜单下拉树结构
@ -22,7 +22,7 @@ export function treeselect() {
return request({
url: '/system/menu/treeselect',
method: 'get'
})
});
}
// 根据角色ID查询菜单下拉树结构
@ -30,7 +30,7 @@ export function roleMenuTreeselect(roleId) {
return request({
url: '/system/menu/roleMenuTreeselect/' + roleId,
method: 'get'
})
});
}
// 新增菜单
@ -39,7 +39,7 @@ export function addMenu(data) {
url: '/system/menu',
method: 'post',
data: data
})
});
}
// 修改菜单
@ -48,7 +48,7 @@ export function updateMenu(data) {
url: '/system/menu',
method: 'put',
data: data
})
});
}
// 删除菜单
@ -56,5 +56,5 @@ export function delMenu(menuId) {
return request({
url: '/system/menu/' + menuId,
method: 'delete'
})
}
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询公告列表
export function listNotice(query) {
@ -6,7 +6,7 @@ export function listNotice(query) {
url: '/system/notice/list',
method: 'get',
params: query
})
});
}
// 查询公告详细
@ -14,7 +14,7 @@ export function getNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'get'
})
});
}
// 新增公告
@ -23,7 +23,7 @@ export function addNotice(data) {
url: '/system/notice',
method: 'post',
data: data
})
});
}
// 修改公告
@ -32,7 +32,7 @@ export function updateNotice(data) {
url: '/system/notice',
method: 'put',
data: data
})
});
}
// 删除公告
@ -40,5 +40,5 @@ export function delNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'delete'
})
}
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询岗位列表
export function listPost(query) {
@ -6,7 +6,7 @@ export function listPost(query) {
url: '/system/post/list',
method: 'get',
params: query
})
});
}
// 查询岗位详细
@ -14,7 +14,7 @@ export function getPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'get'
})
});
}
// 新增岗位
@ -23,7 +23,7 @@ export function addPost(data) {
url: '/system/post',
method: 'post',
data: data
})
});
}
// 修改岗位
@ -32,7 +32,7 @@ export function updatePost(data) {
url: '/system/post',
method: 'put',
data: data
})
});
}
// 删除岗位
@ -40,5 +40,5 @@ export function delPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'delete'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询角色列表
export function listRole(query) {
@ -6,7 +6,7 @@ export function listRole(query) {
url: '/system/role/list',
method: 'get',
params: query
})
});
}
// 查询角色详细
@ -14,7 +14,7 @@ export function getRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'get'
})
});
}
// 新增角色
@ -23,7 +23,7 @@ export function addRole(data) {
url: '/system/role',
method: 'post',
data: data
})
});
}
// 修改角色
@ -32,7 +32,7 @@ export function updateRole(data) {
url: '/system/role',
method: 'put',
data: data
})
});
}
// 角色数据权限
@ -41,7 +41,7 @@ export function dataScope(data) {
url: '/system/role/dataScope',
method: 'put',
data: data
})
});
}
// 角色状态修改
@ -49,12 +49,12 @@ export function changeRoleStatus(roleId, status) {
const data = {
roleId,
status
}
};
return request({
url: '/system/role/changeStatus',
method: 'put',
data: data
})
});
}
// 删除角色
@ -62,7 +62,7 @@ export function delRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'delete'
})
});
}
// 查询角色已授权用户列表
@ -71,7 +71,7 @@ export function allocatedUserList(query) {
url: '/system/role/authUser/allocatedList',
method: 'get',
params: query
})
});
}
// 查询角色未授权用户列表
@ -80,7 +80,7 @@ export function unallocatedUserList(query) {
url: '/system/role/authUser/unallocatedList',
method: 'get',
params: query
})
});
}
// 取消用户授权角色
@ -89,7 +89,7 @@ export function authUserCancel(data) {
url: '/system/role/authUser/cancel',
method: 'put',
data: data
})
});
}
// 批量取消用户授权角色
@ -98,7 +98,7 @@ export function authUserCancelAll(data) {
url: '/system/role/authUser/cancelAll',
method: 'put',
params: data
})
});
}
// 授权用户选择
@ -107,7 +107,7 @@ export function authUserSelectAll(data) {
url: '/system/role/authUser/selectAll',
method: 'put',
params: data
})
});
}
// 根据角色ID查询部门树结构
@ -115,14 +115,12 @@ export function deptTreeSelect(roleId) {
return request({
url: '/system/role/deptTree/' + roleId,
method: 'get'
})
});
}
export function getRoleOptions() {
return request({
url: '/system/role/getRoles',
method: 'get'
})
});
}

@ -1,7 +1,5 @@
import request from '@/utils/request'
import {
parseStrEmpty
} from "@/utils/ruoyi";
import request from '@/utils/request';
import { parseStrEmpty } from '@/utils/ruoyi';
// 查询用户列表
export function listUser(query) {
@ -9,7 +7,7 @@ export function listUser(query) {
url: '/system/user/list',
method: 'get',
params: query
})
});
}
// 查询用户详细
@ -17,7 +15,7 @@ export function getUser(userId) {
return request({
url: '/system/user/' + parseStrEmpty(userId),
method: 'get'
})
});
}
// 新增用户
@ -26,7 +24,7 @@ export function addUser(data) {
url: '/system/user',
method: 'post',
data: data
})
});
}
// 修改用户
@ -35,7 +33,7 @@ export function updateUser(data) {
url: '/system/user',
method: 'put',
data: data
})
});
}
// 删除用户
@ -43,7 +41,7 @@ export function delUser(userId) {
return request({
url: '/system/user/' + userId,
method: 'delete'
})
});
}
// 用户密码重置
@ -51,12 +49,12 @@ export function resetUserPwd(userId, password) {
const data = {
userId,
password
}
};
return request({
url: '/system/user/resetPwd',
method: 'put',
data: data
})
});
}
// 用户状态修改
@ -64,12 +62,12 @@ export function changeUserStatus(userId, status) {
const data = {
userId,
status
}
};
return request({
url: '/system/user/changeStatus',
method: 'put',
data: data
})
});
}
// 查询用户个人信息
@ -77,7 +75,7 @@ export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
});
}
// 修改用户个人信息
@ -86,7 +84,7 @@ export function updateUserProfile(data) {
url: '/system/user/profile',
method: 'put',
data: data
})
});
}
// 用户密码重置
@ -94,12 +92,12 @@ export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
};
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
});
}
// 用户头像上传
@ -108,7 +106,7 @@ export function uploadAvatar(data) {
url: '/system/user/profile/avatar',
method: 'post',
data: data
})
});
}
// 查询授权角色
@ -116,7 +114,7 @@ export function getAuthRole(userId) {
return request({
url: '/system/user/authRole/' + userId,
method: 'get'
})
});
}
// 保存授权角色
@ -125,5 +123,5 @@ export function updateAuthRole(data) {
url: '/system/user/authRole',
method: 'put',
params: data
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询生成表数据
export function listTable(query) {
@ -6,7 +6,7 @@ export function listTable(query) {
url: '/tool/gen/list',
method: 'get',
params: query
})
});
}
// 查询db数据库列表
export function listDbTable(query) {
@ -14,7 +14,7 @@ export function listDbTable(query) {
url: '/tool/gen/db/list',
method: 'get',
params: query
})
});
}
// 查询表详细信息
@ -22,7 +22,7 @@ export function getGenTable(tableId) {
return request({
url: '/tool/gen/' + tableId,
method: 'get'
})
});
}
// 修改代码生成信息
@ -31,7 +31,7 @@ export function updateGenTable(data) {
url: '/tool/gen',
method: 'put',
data: data
})
});
}
// 导入表
@ -40,7 +40,7 @@ export function importTable(data) {
url: '/tool/gen/importTable',
method: 'post',
params: data
})
});
}
// 预览生成代码
@ -48,7 +48,7 @@ export function previewTable(tableId) {
return request({
url: '/tool/gen/preview/' + tableId,
method: 'get'
})
});
}
// 删除表数据
@ -56,7 +56,7 @@ export function delTable(tableId) {
return request({
url: '/tool/gen/' + tableId,
method: 'delete'
})
});
}
// 生成代码(自定义路径)
@ -64,7 +64,7 @@ export function genCode(tableName) {
return request({
url: '/tool/gen/genCode/' + tableName,
method: 'get'
})
});
}
// 同步数据库
@ -72,5 +72,5 @@ export function synchDb(tableName) {
return request({
url: '/tool/gen/synchDb/' + tableName,
method: 'get'
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询线索列表
export function getClueList(query) {
@ -6,7 +6,7 @@ export function getClueList(query) {
url: '/zs/clue/list',
method: 'get',
params: query
})
});
}
// 新增线索
@ -15,7 +15,7 @@ export function addClue(data) {
url: '/zs/clue',
method: 'post',
data: data
})
});
}
// 修改线索
@ -24,16 +24,16 @@ export function updateClue(data) {
url: '/zs/clue',
method: 'put',
data: data
})
});
}
//删除
// 删除
export function deleteClue(data) {
return request({
url: '/zs/clue',
method: 'delete',
params: data
})
});
}
// 导出
export function exportData(query) {
@ -41,7 +41,7 @@ export function exportData(query) {
url: '/zs/clue/export',
method: 'get',
params: query
})
});
}
// 导入模板
@ -50,7 +50,7 @@ export function importTemplate(param) {
url: '/zs/clue/importTemplate',
method: 'get',
params: param
})
});
}
// 导入
export function importData(data) {
@ -58,61 +58,60 @@ export function importData(data) {
url: '/zs/clue/importData',
method: 'post',
data: data
})
});
}
//查询登记getSign
// 查询登记getSign
export function getSign(query) {
return request({
url: '/zs/clue/sign',
method: 'get',
params: query
})
});
}
//保存登记
// 保存登记
export function saveSign(data) {
return request({
url: '/zs/clue/sign',
method: 'post',
data: data
})
});
}
//甩单
// 甩单
export function saveDistribute(data) {
return request({
url: '/zs/clue/distribute',
method: 'put',
data: data
})
});
}
//驳回
// 驳回
export function refuse(data) {
return request({
url: '/zs/clue/refuse',
method: 'put',
data: data
})
});
}
//查询甩单记录
// 查询甩单记录
export function getDistributeRecord(param) {
return request({
url: '/zs/clue/distributerecord',
method: 'get',
params: param
})
});
}
//查询跟踪记录
// 查询跟踪记录
export function getFollowRecord(param) {
return request({
url: '/zs/clue/followrecord',
method: 'get',
params: param
})
});
}
//
@ -122,14 +121,14 @@ export function getConsultRecord(param) {
url: '/zs/clue/consultrecord',
method: 'get',
params: param
})
});
}
// 获取已过期
export function getClueCountBadge() {
return request({
url: `/zs/clue/badgeCount`,
method: 'get'
})
});
}
// 批量更新
@ -138,49 +137,49 @@ export function batchUpdate(data) {
url: `/zs/clue/batchUpdate`,
method: 'put',
data: data
})
});
}
//公海线索 getPublicList
// 公海线索 getPublicList
export function getPublicList(param) {
return request({
url: `/zs/clue/public/list`,
method: 'get',
params: param
})
});
}
//拾取线索
// 拾取线索
export function pickupClue(data) {
return request({
url: `/zs/clue/public/pickup`,
method: 'put',
data: data
})
});
}
//丢弃线索
// 丢弃线索
export function discardClue(data) {
return request({
url: `/zs/clue/public/discard`,
method: 'put',
data: data
})
});
}
//查询接收
// 查询接收
export function getAccept() {
return request({
url: `/zs/clue/accept`,
method: 'get'
})
});
}
//丢弃线索
// 丢弃线索
export function updateAccept(data) {
return request({
url: `/zs/clue/accept`,
method: 'put',
data: data
})
});
}

@ -1,4 +1,4 @@
import request from '@/utils/request'
import request from '@/utils/request';
// 查询线索列表
export function getSignList(query) {
@ -6,7 +6,7 @@ export function getSignList(query) {
url: '/zs/sign/list',
method: 'get',
params: query
})
});
}
// 导出
@ -15,7 +15,7 @@ export function exportData(query) {
url: '/zs/sign/export',
method: 'get',
params: query
})
});
}
// 导入模板
@ -23,7 +23,7 @@ export function importTemplate() {
return request({
url: '/zs/sign/importTemplate',
method: 'get'
})
});
}
// 导入
export function importData(data) {
@ -31,16 +31,15 @@ export function importData(data) {
url: '/zs/sign/importData',
method: 'post',
data: data
})
});
}
export function addSign(data) {
return request({
url: '/zs/sign',
method: 'post',
data: data
})
});
}
export function updateSign(data) {
@ -48,7 +47,7 @@ export function updateSign(data) {
url: '/zs/sign',
method: 'put',
data: data
})
});
}
export function getClues(param) {
@ -56,34 +55,31 @@ export function getClues(param) {
url: '/zs/sign/clue',
method: 'get',
params: param
})
});
}
export function deleteSign(data) {
return request({
url: '/zs/sign',
method: 'delete',
params: data
})
});
}
//审核登记
// 审核登记
export function checkSign(data) {
return request({
url: '/zs/sign/check',
method: 'put',
data: data
})
});
}
//审核记录
// 审核记录
export function getCheckRecord(data) {
return request({
url: '/zs/sign/check',
method: 'get',
params: data
})
});
}

@ -1,9 +1,9 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon'; // svg component
// register globally
Vue.component('svg-icon', SvgIcon)
Vue.component('SvgIcon', SvgIcon);
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
const req = require.context('./svg', false, /\.svg$/);
const requireAll = (requireContext) => requireContext.keys().map(requireContext);
requireAll(req);

@ -14,49 +14,54 @@ export default {
data() {
return {
levelList: null
}
};
},
watch: {
$route(route) {
// if you go to the redirect page, do not update the breadcrumbs
if (route.path.startsWith('/redirect/')) {
return
return;
}
this.getBreadcrumb()
this.getBreadcrumb();
}
},
created() {
this.getBreadcrumb()
this.getBreadcrumb();
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
let matched = this.$route.matched.filter((item) => item.meta && item.meta.title);
const first = matched[0];
if (!this.isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched)
matched = [
{
path: '/index',
meta: { title: '首页' }
}
].concat(matched);
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
this.levelList = matched.filter((item) => item.meta && item.meta.title && item.meta.breadcrumb !== false);
},
isDashboard(route) {
const name = route && route.name
const name = route && route.name;
if (!name) {
return false
return false;
}
return name.trim() === 'Index'
return name.trim() === 'Index';
},
handleLink(item) {
const { redirect, path } = item
const { redirect, path } = item;
if (redirect) {
this.$router.push(redirect)
return
this.$router.push(redirect);
return;
}
this.$router.push(path)
this.$router.push(path);
}
}
}
};
</script>
<style lang="scss" scoped>

@ -1,161 +1,162 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * ? / L W]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
允许的通配符[, - * ? / L W]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
周期从
<el-input-number v-model='cycle01' :min="1" :max="30" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从
<el-input-number v-model="cycle01" :min="1" :max="30" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 2" :max="31" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始
<el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="1" :max="30" /> 号开始
<el-input-number v-model="average02" :min="1" :max="31 - average01 || 1" /> 日执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="5">
每月
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
每月
<el-input-number v-model="workday" :min="1" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="6">
本月最后一天
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="6">
本月最后一天
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="7">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="7">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 31" :key="item" :value="item">{{ item }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
radioValue: 1,
workday: 1,
cycle01: 1,
cycle02: 2,
average01: 1,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-day',
props: ['check', 'cron'],
methods: {
//
radioChange() {
('day rachange');
if (this.radioValue !== 2 && this.cron.week !== '?') {
this.$emit('update', 'week', '?', 'day')
}
name: 'CrontabDay',
// eslint-disable-next-line vue/require-prop-types
props: ['check', 'cron'],
data() {
return {
radioValue: 1,
workday: 1,
cycle01: 1,
cycle02: 2,
average01: 1,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 1, 30);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 1, 30);
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0);
return average01 + '/' + average02;
},
//
workdayCheck: function () {
const workday = this.checkNum(this.workday, 1, 31);
return workday;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str === '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
workdayCheck: 'workdayChange',
checkboxString: 'checkboxChange'
},
methods: {
//
radioChange() {
('day rachange');
if (this.radioValue !== 2 && this.cron.week !== '?') {
this.$emit('update', 'week', '?', 'day');
}
switch (this.radioValue) {
case 1:
this.$emit('update', 'day', '*');
break;
case 2:
this.$emit('update', 'day', '?');
break;
case 3:
this.$emit('update', 'day', this.cycleTotal);
break;
case 4:
this.$emit('update', 'day', this.averageTotal);
break;
case 5:
this.$emit('update', 'day', this.workday + 'W');
break;
case 6:
this.$emit('update', 'day', 'L');
break;
case 7:
this.$emit('update', 'day', this.checkboxString);
break;
}
('day rachange end');
},
//
cycleChange() {
if (this.radioValue == '3') {
this.$emit('update', 'day', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '4') {
this.$emit('update', 'day', this.averageTotal);
}
},
//
workdayChange() {
if (this.radioValue == '5') {
this.$emit('update', 'day', this.workdayCheck + 'W');
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '7') {
this.$emit('update', 'day', this.checkboxString);
}
}
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'workdayCheck': 'workdayChange',
'checkboxString': 'checkboxChange',
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 1, 30)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 1, 30)
const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0)
return average01 + '/' + average02;
},
//
workdayCheck: function () {
const workday = this.checkNum(this.workday, 1, 31)
return workday;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
switch (this.radioValue) {
case 1:
this.$emit('update', 'day', '*');
break;
case 2:
this.$emit('update', 'day', '?');
break;
case 3:
this.$emit('update', 'day', this.cycleTotal);
break;
case 4:
this.$emit('update', 'day', this.averageTotal);
break;
case 5:
this.$emit('update', 'day', this.workday + 'W');
break;
case 6:
this.$emit('update', 'day', 'L');
break;
case 7:
this.$emit('update', 'day', this.checkboxString);
break;
}
('day rachange end');
},
//
cycleChange() {
if (this.radioValue === '3') {
this.$emit('update', 'day', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue === '4') {
this.$emit('update', 'day', this.averageTotal);
}
},
//
workdayChange() {
if (this.radioValue === '5') {
this.$emit('update', 'day', this.workdayCheck + 'W');
}
},
// checkbox
checkboxChange() {
if (this.radioValue === '7') {
this.$emit('update', 'day', this.checkboxString);
}
}
}
};
</script>

@ -1,114 +1,115 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
小时允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
小时允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="22" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="22" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="22" /> 小时开始
<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="22" /> 小时开始
<el-input-number v-model="average02" :min="1" :max="23 - average01 || 0" /> 小时执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 24" :key="item" :value="item-1">{{ item-1 }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
radioValue: 1,
cycle01: 0,
cycle02: 1,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-hour',
props: ['check', 'cron'],
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'hour', '*')
break;
case 2:
this.$emit('update', 'hour', this.cycleTotal);
break;
case 3:
this.$emit('update', 'hour', this.averageTotal);
break;
case 4:
this.$emit('update', 'hour', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'hour', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'hour', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'hour', this.checkboxString);
}
}
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange'
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 22)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 22)
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
name: 'CrontabHour',
// eslint-disable-next-line vue/require-prop-types
props: ['check', 'cron'],
data() {
return {
radioValue: 1,
cycle01: 0,
cycle02: 1,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 22);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 22);
const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0);
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str === '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
checkboxString: 'checkboxChange'
},
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'hour', '*');
break;
case 2:
this.$emit('update', 'hour', this.cycleTotal);
break;
case 3:
this.$emit('update', 'hour', this.averageTotal);
break;
case 4:
this.$emit('update', 'hour', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue === '2') {
this.$emit('update', 'hour', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue === '3') {
this.$emit('update', 'hour', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue === '4') {
this.$emit('update', 'hour', this.checkboxString);
}
}
}
};
</script>

@ -1,67 +1,32 @@
<template>
<div>
<el-tabs type="border-card">
<el-tab-pane label="秒" v-if="shouldHide('second')">
<CrontabSecond
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronsecond"
/>
<el-tab-pane v-if="shouldHide('second')" label="秒">
<CrontabSecond ref="cronsecond" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="分钟" v-if="shouldHide('min')">
<CrontabMin
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronmin"
/>
<el-tab-pane v-if="shouldHide('min')" label="分钟">
<CrontabMin ref="cronmin" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="小时" v-if="shouldHide('hour')">
<CrontabHour
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronhour"
/>
<el-tab-pane v-if="shouldHide('hour')" label="小时">
<CrontabHour ref="cronhour" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="日" v-if="shouldHide('day')">
<CrontabDay
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronday"
/>
<el-tab-pane v-if="shouldHide('day')" label="日">
<CrontabDay ref="cronday" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="月" v-if="shouldHide('month')">
<CrontabMonth
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronmonth"
/>
<el-tab-pane v-if="shouldHide('month')" label="月">
<CrontabMonth ref="cronmonth" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="周" v-if="shouldHide('week')">
<CrontabWeek
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronweek"
/>
<el-tab-pane v-if="shouldHide('week')" label="周">
<CrontabWeek ref="cronweek" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
<el-tab-pane label="年" v-if="shouldHide('year')">
<CrontabYear
@update="updateCrontabValue"
:check="checkNumber"
:cron="crontabValueObj"
ref="cronyear"
/>
<el-tab-pane v-if="shouldHide('year')" label="年">
<CrontabYear ref="cronyear" :check="checkNumber" :cron="crontabValueObj" @update="updateCrontabValue" />
</el-tab-pane>
</el-tabs>
@ -70,38 +35,38 @@
<p class="title">时间表达式</p>
<table>
<thead>
<th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
<th v-for="item of tabTitles" :key="item" width="40">{{ item }}</th>
<th>Cron 表达式</th>
</thead>
<tbody>
<td>
<span>{{crontabValueObj.second}}</span>
<span>{{ crontabValueObj.second }}</span>
</td>
<td>
<span>{{crontabValueObj.min}}</span>
<span>{{ crontabValueObj.min }}</span>
</td>
<td>
<span>{{crontabValueObj.hour}}</span>
<span>{{ crontabValueObj.hour }}</span>
</td>
<td>
<span>{{crontabValueObj.day}}</span>
<span>{{ crontabValueObj.day }}</span>
</td>
<td>
<span>{{crontabValueObj.month}}</span>
<span>{{ crontabValueObj.month }}</span>
</td>
<td>
<span>{{crontabValueObj.week}}</span>
<span>{{ crontabValueObj.week }}</span>
</td>
<td>
<span>{{crontabValueObj.year}}</span>
<span>{{ crontabValueObj.year }}</span>
</td>
<td>
<span>{{crontabValueString}}</span>
<span>{{ crontabValueString }}</span>
</td>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<CrontabResult :ex="crontabValueString" />
<div class="pop_btn">
<el-button size="small" type="primary" @click="submitFill">确定</el-button>
@ -113,34 +78,62 @@
</template>
<script>
import CrontabSecond from "./second.vue";
import CrontabMin from "./min.vue";
import CrontabHour from "./hour.vue";
import CrontabDay from "./day.vue";
import CrontabMonth from "./month.vue";
import CrontabWeek from "./week.vue";
import CrontabYear from "./year.vue";
import CrontabResult from "./result.vue";
import CrontabSecond from './second.vue';
import CrontabMin from './min.vue';
import CrontabHour from './hour.vue';
import CrontabDay from './day.vue';
import CrontabMonth from './month.vue';
import CrontabWeek from './week.vue';
import CrontabYear from './year.vue';
import CrontabResult from './result.vue';
export default {
name: 'Vcrontab',
components: {
CrontabSecond,
CrontabMin,
CrontabHour,
CrontabDay,
CrontabMonth,
CrontabWeek,
CrontabYear,
CrontabResult
},
// eslint-disable-next-line vue/require-prop-types
props: ['expression', 'hideComponent'],
data() {
return {
tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
tabTitles: ['秒', '分钟', '小时', '日', '月', '周', '年'],
tabActive: 0,
myindex: 0,
crontabValueObj: {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
},
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
}
};
},
name: "vcrontab",
props: ["expression", "hideComponent"],
computed: {
crontabValueString: function () {
const obj = this.crontabValueObj;
const str =
obj.second + ' ' + obj.min + ' ' + obj.hour + ' ' + obj.day + ' ' + obj.month + ' ' + obj.week + (obj.year == '' ? '' : ' ' + obj.year);
return str;
}
},
watch: {
expression: 'resolveExp',
hideComponent(value) {
//
}
},
mounted: function () {
this.resolveExp();
},
methods: {
shouldHide(key) {
if (this.hideComponent && this.hideComponent.includes(key)) return false;
@ -149,22 +142,22 @@ export default {
resolveExp() {
//
if (this.expression) {
let arr = this.expression.split(" ");
const arr = this.expression.split(' ');
if (arr.length >= 6) {
//6
let obj = {
// 6
const obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : "",
year: arr[6] ? arr[6] : ''
};
this.crontabValueObj = {
...obj,
...obj
};
for (let i in obj) {
for (const i in obj) {
if (obj[i]) this.changeRadio(i, obj[i]);
}
}
@ -179,7 +172,8 @@ export default {
},
//
updateCrontabValue(name, value, from) {
"updateCrontabValue", name, value, from;
// eslint-disable-next-line no-sequences
'updateCrontabValue', name, value, from;
this.crontabValueObj[name] = value;
if (from && from !== name) {
console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
@ -188,104 +182,88 @@ export default {
},
//
changeRadio(name, value) {
let arr = ["second", "min", "hour", "month"],
refName = "cron" + name,
insValue;
const arr = ['second', 'min', 'hour', 'month'];
const refName = 'cron' + name;
let insValue;
if (!this.$refs[refName]) return;
if (arr.includes(name)) {
if (value === "*") {
if (value === '*') {
insValue = 1;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
isNaN(indexArr[0]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
insValue = 2;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]);
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 0) : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
insValue = 3;
} else {
insValue = 4;
this.$refs[refName].checkboxList = value.split(",");
this.$refs[refName].checkboxList = value.split(',');
}
} else if (name == "day") {
if (value === "*") {
} else if (name == 'day') {
if (value === '*') {
insValue = 1;
} else if (value == "?") {
} else if (value == '?') {
insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
isNaN(indexArr[0]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
insValue = 3;
} else if (value.indexOf("/") > -1) {
let indexArr = value.split("/");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 0)
: (this.$refs[refName].average01 = indexArr[0]);
} else if (value.indexOf('/') > -1) {
const indexArr = value.split('/');
isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 0) : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
insValue = 4;
} else if (value.indexOf("W") > -1) {
let indexArr = value.split("W");
isNaN(indexArr[0])
? (this.$refs[refName].workday = 0)
: (this.$refs[refName].workday = indexArr[0]);
} else if (value.indexOf('W') > -1) {
const indexArr = value.split('W');
isNaN(indexArr[0]) ? (this.$refs[refName].workday = 0) : (this.$refs[refName].workday = indexArr[0]);
insValue = 5;
} else if (value === "L") {
} else if (value === 'L') {
insValue = 6;
} else {
this.$refs[refName].checkboxList = value.split(",");
this.$refs[refName].checkboxList = value.split(',');
insValue = 7;
}
} else if (name == "week") {
if (value === "*") {
} else if (name == 'week') {
if (value === '*') {
insValue = 1;
} else if (value == "?") {
} else if (value == '?') {
insValue = 2;
} else if (value.indexOf("-") > -1) {
let indexArr = value.split("-");
isNaN(indexArr[0])
? (this.$refs[refName].cycle01 = 0)
: (this.$refs[refName].cycle01 = indexArr[0]);
} else if (value.indexOf('-') > -1) {
const indexArr = value.split('-');
isNaN(indexArr[0]) ? (this.$refs[refName].cycle01 = 0) : (this.$refs[refName].cycle01 = indexArr[0]);
this.$refs[refName].cycle02 = indexArr[1];
insValue = 3;
} else if (value.indexOf("#") > -1) {
let indexArr = value.split("#");
isNaN(indexArr[0])
? (this.$refs[refName].average01 = 1)
: (this.$refs[refName].average01 = indexArr[0]);
} else if (value.indexOf('#') > -1) {
const indexArr = value.split('#');
isNaN(indexArr[0]) ? (this.$refs[refName].average01 = 1) : (this.$refs[refName].average01 = indexArr[0]);
this.$refs[refName].average02 = indexArr[1];
insValue = 4;
} else if (value.indexOf("L") > -1) {
let indexArr = value.split("L");
isNaN(indexArr[0])
? (this.$refs[refName].weekday = 1)
: (this.$refs[refName].weekday = indexArr[0]);
} else if (value.indexOf('L') > -1) {
const indexArr = value.split('L');
isNaN(indexArr[0]) ? (this.$refs[refName].weekday = 1) : (this.$refs[refName].weekday = indexArr[0]);
insValue = 5;
} else {
this.$refs[refName].checkboxList = value.split(",");
this.$refs[refName].checkboxList = value.split(',');
insValue = 6;
}
} else if (name == "year") {
if (value == "") {
} else if (name == 'year') {
if (value == '') {
insValue = 1;
} else if (value == "*") {
} else if (value == '*') {
insValue = 2;
} else if (value.indexOf("-") > -1) {
} else if (value.indexOf('-') > -1) {
insValue = 3;
} else if (value.indexOf("/") > -1) {
} else if (value.indexOf('/') > -1) {
insValue = 4;
} else {
this.$refs[refName].checkboxList = value.split(",");
this.$refs[refName].checkboxList = value.split(',');
insValue = 5;
}
}
@ -304,68 +282,30 @@ export default {
},
//
hidePopup() {
this.$emit("hide");
this.$emit('hide');
},
//
submitFill() {
this.$emit("fill", this.crontabValueString);
this.$emit('fill', this.crontabValueString);
this.hidePopup();
},
clearCron() {
//
("准备还原");
('准备还原');
this.crontabValueObj = {
second: "*",
min: "*",
hour: "*",
day: "*",
month: "*",
week: "?",
year: "",
second: '*',
min: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
year: ''
};
for (let j in this.crontabValueObj) {
for (const j in this.crontabValueObj) {
this.changeRadio(j, this.crontabValueObj[j]);
}
},
},
computed: {
crontabValueString: function() {
let obj = this.crontabValueObj;
let str =
obj.second +
" " +
obj.min +
" " +
obj.hour +
" " +
obj.day +
" " +
obj.month +
" " +
obj.week +
(obj.year == "" ? "" : " " + obj.year);
return str;
},
},
components: {
CrontabSecond,
CrontabMin,
CrontabHour,
CrontabDay,
CrontabMonth,
CrontabWeek,
CrontabYear,
CrontabResult,
},
watch: {
expression: "resolveExp",
hideComponent(value) {
//
},
},
mounted: function() {
this.resolveExp();
},
}
}
};
</script>
<style scoped>

@ -1,116 +1,115 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
分钟允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
分钟允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="58" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="58" /> 分钟开始
<el-input-number v-model="average02" :min="1" :max="59 - average01 || 0" /> 分钟执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{ item-1 }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-min',
props: ['check', 'cron'],
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'min', '*', 'min');
break;
case 2:
this.$emit('update', 'min', this.cycleTotal, 'min');
break;
case 3:
this.$emit('update', 'min', this.averageTotal, 'min');
break;
case 4:
this.$emit('update', 'min', this.checkboxString, 'min');
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'min', this.cycleTotal, 'min');
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'min', this.averageTotal, 'min');
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'min', this.checkboxString, 'min');
}
},
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange',
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 58)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 58)
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
</script>
name: 'CrontabMin',
props: ['check', 'cron'],
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 58);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 58);
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0);
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str == '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
checkboxString: 'checkboxChange'
},
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'min', '*', 'min');
break;
case 2:
this.$emit('update', 'min', this.cycleTotal, 'min');
break;
case 3:
this.$emit('update', 'min', this.averageTotal, 'min');
break;
case 4:
this.$emit('update', 'min', this.checkboxString, 'min');
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'min', this.cycleTotal, 'min');
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'min', this.averageTotal, 'min');
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'min', this.checkboxString, 'min');
}
}
}
};
</script>

@ -1,114 +1,114 @@
<template>
<el-form size='small'>
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="1" :max="11" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="1" :max="11" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 2" :max="12" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始
<el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="1" :max="11" /> 月开始
<el-input-number v-model="average02" :min="1" :max="12 - average01 || 0" /> 月月执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 12" :key="item" :value="item">{{ item }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 1,
average02: 1,
checkboxList: [],
checkNum: this.check
}
},
name: 'crontab-month',
props: ['check', 'cron'],
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'month', '*');
break;
case 2:
this.$emit('update', 'month', this.cycleTotal);
break;
case 3:
this.$emit('update', 'month', this.averageTotal);
break;
case 4:
this.$emit('update', 'month', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'month', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'month', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'month', this.checkboxString);
}
}
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange'
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 1, 11)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 1, 11)
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0)
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
name: 'CrontabMonth',
props: ['check', 'cron'],
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 1,
average02: 1,
checkboxList: [],
checkNum: this.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 1, 11);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 1, 11);
const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0);
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str == '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
checkboxString: 'checkboxChange'
},
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'month', '*');
break;
case 2:
this.$emit('update', 'month', this.cycleTotal);
break;
case 3:
this.$emit('update', 'month', this.averageTotal);
break;
case 4:
this.$emit('update', 'month', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'month', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'month', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'month', this.checkboxString);
}
}
}
};
</script>

File diff suppressed because it is too large Load Diff

@ -1,117 +1,117 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
周期从
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
周期从
<el-input-number v-model="cycle01" :min="0" :max="58" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : 1" :max="59" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始
<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
<el-input-number v-model="average01" :min="0" :max="58" /> 秒开始
<el-input-number v-model="average02" :min="1" :max="59 - average01 || 0" /> 秒执行一次
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="item in 60" :key="item" :value="item-1">{{ item-1 }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-second',
props: ['check', 'radioParent'],
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'second', '*', 'second');
break;
case 2:
this.$emit('update', 'second', this.cycleTotal);
break;
case 3:
this.$emit('update', 'second', this.averageTotal);
break;
case 4:
this.$emit('update', 'second', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'second', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'second', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'second', this.checkboxString);
}
}
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange',
radioParent() {
this.radioValue = this.radioParent
}
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 58)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 58)
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
name: 'CrontabSecond',
props: ['check', 'radioParent'],
data() {
return {
radioValue: 1,
cycle01: 1,
cycle02: 2,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, 0, 58);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, 0, 58);
const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0);
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str == '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
checkboxString: 'checkboxChange',
radioParent() {
this.radioValue = this.radioParent;
}
},
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'second', '*', 'second');
break;
case 2:
this.$emit('update', 'second', this.cycleTotal);
break;
case 3:
this.$emit('update', 'second', this.averageTotal);
break;
case 4:
this.$emit('update', 'second', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '2') {
this.$emit('update', 'second', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '3') {
this.$emit('update', 'second', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '4') {
this.$emit('update', 'second', this.checkboxString);
}
}
}
};
</script>

@ -1,202 +1,191 @@
<template>
<el-form size='small'>
<el-form-item>
<el-radio v-model='radioValue' :label="1">
允许的通配符[, - * ? / L #]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
允许的通配符[, - * ? / L #]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
不指定
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="3">
周期从星期
<el-select clearable v-model="cycle01">
<el-option
v-for="(item,index) of weekList"
:key="index"
:label="item.value"
:value="item.key"
:disabled="item.key === 1"
>{{item.value}}</el-option>
</el-select>
-
<el-select clearable v-model="cycle02">
<el-option
v-for="(item,index) of weekList"
:key="index"
:label="item.value"
:value="item.key"
:disabled="item.key < cycle01 && item.key !== 1"
>{{item.value}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从星期
<el-select v-model="cycle01" clearable>
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key" :disabled="item.key === 1">{{ item.value }}</el-option>
</el-select>
-
<el-select v-model="cycle02" clearable>
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key" :disabled="item.key < cycle01 && item.key !== 1">{{ item.value }}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="4">
<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
<el-select clearable v-model="average02">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="1" :max="4" /> 周的星期
<el-select v-model="average02" clearable>
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{ item.value }}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="5">
本月最后一个星期
<el-select clearable v-model="weekday">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
本月最后一个星期
<el-select v-model="weekday" clearable>
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{ item.value }}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model='radioValue' :label="6">
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{item.value}}</el-option>
</el-select>
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="6">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple style="width:100%">
<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{ item.value }}</el-option>
</el-select>
</el-radio>
</el-form-item>
</el-form>
</el-form>
</template>
<!-- eslint-disable vue/no-side-effects-in-computed-properties -->
<script>
export default {
data() {
return {
radioValue: 2,
weekday: 2,
cycle01: 2,
cycle02: 3,
average01: 1,
average02: 2,
checkboxList: [],
weekList: [
{
key: 2,
value: '星期一'
},
{
key: 3,
value: '星期二'
},
{
key: 4,
value: '星期三'
},
{
key: 5,
value: '星期四'
},
{
key: 6,
value: '星期五'
},
{
key: 7,
value: '星期六'
},
{
key: 1,
value: '星期日'
}
],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-week',
props: ['check', 'cron'],
methods: {
//
radioChange() {
if (this.radioValue !== 2 && this.cron.day !== '?') {
this.$emit('update', 'day', '?', 'week');
}
switch (this.radioValue) {
case 1:
this.$emit('update', 'week', '*');
break;
case 2:
this.$emit('update', 'week', '?');
break;
case 3:
this.$emit('update', 'week', this.cycleTotal);
break;
case 4:
this.$emit('update', 'week', this.averageTotal);
break;
case 5:
this.$emit('update', 'week', this.weekdayCheck + 'L');
break;
case 6:
this.$emit('update', 'week', this.checkboxString);
break;
}
},
name: 'CrontabWeek',
props: ['check', 'cron'],
data() {
return {
radioValue: 2,
weekday: 2,
cycle01: 2,
cycle02: 3,
average01: 1,
average02: 2,
checkboxList: [],
weekList: [
{
key: 2,
value: '星期一'
},
{
key: 3,
value: '星期二'
},
{
key: 4,
value: '星期三'
},
{
key: 5,
value: '星期四'
},
{
key: 6,
value: '星期五'
},
{
key: 7,
value: '星期六'
},
{
key: 1,
value: '星期日'
}
],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
this.cycle01 = this.checkNum(this.cycle01, 1, 7);
this.cycle02 = this.checkNum(this.cycle02, 1, 7);
return this.cycle01 + '-' + this.cycle02;
},
//
averageTotal: function () {
this.average01 = this.checkNum(this.average01, 1, 4);
this.average02 = this.checkNum(this.average02, 1, 7);
return this.average02 + '#' + this.average01;
},
//
weekdayCheck: function () {
this.weekday = this.checkNum(this.weekday, 1, 7);
return this.weekday;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str == '' ? '*' : str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
weekdayCheck: 'weekdayChange',
checkboxString: 'checkboxChange'
},
methods: {
//
radioChange() {
if (this.radioValue !== 2 && this.cron.day !== '?') {
this.$emit('update', 'day', '?', 'week');
}
switch (this.radioValue) {
case 1:
this.$emit('update', 'week', '*');
break;
case 2:
this.$emit('update', 'week', '?');
break;
case 3:
this.$emit('update', 'week', this.cycleTotal);
break;
case 4:
this.$emit('update', 'week', this.averageTotal);
break;
case 5:
this.$emit('update', 'week', this.weekdayCheck + 'L');
break;
case 6:
this.$emit('update', 'week', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '3') {
this.$emit('update', 'week', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '4') {
this.$emit('update', 'week', this.averageTotal);
}
},
//
weekdayChange() {
if (this.radioValue == '5') {
this.$emit('update', 'week', this.weekday + 'L');
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '6') {
this.$emit('update', 'week', this.checkboxString);
}
},
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'weekdayCheck': 'weekdayChange',
'checkboxString': 'checkboxChange',
},
computed: {
//
cycleTotal: function () {
this.cycle01 = this.checkNum(this.cycle01, 1, 7)
this.cycle02 = this.checkNum(this.cycle02, 1, 7)
return this.cycle01 + '-' + this.cycle02;
},
//
averageTotal: function () {
this.average01 = this.checkNum(this.average01, 1, 4)
this.average02 = this.checkNum(this.average02, 1, 7)
return this.average02 + '#' + this.average01;
},
//
weekdayCheck: function () {
this.weekday = this.checkNum(this.weekday, 1, 7)
return this.weekday;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str == '' ? '*' : str;
}
}
}
//
cycleChange() {
if (this.radioValue == '3') {
this.$emit('update', 'week', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '4') {
this.$emit('update', 'week', this.averageTotal);
}
},
//
weekdayChange() {
if (this.radioValue == '5') {
this.$emit('update', 'week', this.weekday + 'L');
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '6') {
this.$emit('update', 'week', this.checkboxString);
}
}
}
};
</script>

@ -1,131 +1,131 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio :label="1" v-model='radioValue'>
不填允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1">
不填允许的通配符[, - * /]
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="2" v-model='radioValue'>
每年
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
每年
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="3" v-model='radioValue'>
周期从
<el-input-number v-model='cycle01' :min='fullYear' :max="2098" /> -
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
周期从
<el-input-number v-model="cycle01" :min="fullYear" :max="2098" /> -
<el-input-number v-model="cycle02" :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" />
</el-radio>
</el-form-item>
<el-form-item>
<el-radio :label="4" v-model='radioValue'>
<el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始
<el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear" /> 年执行一次
</el-radio>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
<el-input-number v-model="average01" :min="fullYear" :max="2098" /> 年开始
<el-input-number v-model="average02" :min="1" :max="2099 - average01 || fullYear" /> 年执行一次
</el-radio>
</el-form-item>
</el-form-item>
<el-form-item>
<el-radio :label="5" v-model='radioValue'>
指定
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
<el-form-item>
<el-radio v-model="radioValue" :label="5">
指定
<el-select v-model="checkboxList" clearable placeholder="可多选" multiple>
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
</el-select>
</el-radio>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
fullYear: 0,
radioValue: 1,
cycle01: 0,
cycle02: 0,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
}
},
name: 'crontab-year',
props: ['check', 'month', 'cron'],
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'year', '');
break;
case 2:
this.$emit('update', 'year', '*');
break;
case 3:
this.$emit('update', 'year', this.cycleTotal);
break;
case 4:
this.$emit('update', 'year', this.averageTotal);
break;
case 5:
this.$emit('update', 'year', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '3') {
this.$emit('update', 'year', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '4') {
this.$emit('update', 'year', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '5') {
this.$emit('update', 'year', this.checkboxString);
}
}
},
watch: {
'radioValue': 'radioChange',
'cycleTotal': 'cycleChange',
'averageTotal': 'averageChange',
'checkboxString': 'checkboxChange'
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098)
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099)
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, this.fullYear, 2098)
const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear)
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
let str = this.checkboxList.join();
return str;
}
},
mounted: function () {
//
this.fullYear = Number(new Date().getFullYear());
this.cycle01 = this.fullYear
this.average01 = this.fullYear
}
}
name: 'CrontabYear',
props: ['check', 'month', 'cron'],
data() {
return {
fullYear: 0,
radioValue: 1,
cycle01: 0,
cycle02: 0,
average01: 0,
average02: 1,
checkboxList: [],
checkNum: this.$options.propsData.check
};
},
computed: {
//
cycleTotal: function () {
const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098);
const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099);
return cycle01 + '-' + cycle02;
},
//
averageTotal: function () {
const average01 = this.checkNum(this.average01, this.fullYear, 2098);
const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear);
return average01 + '/' + average02;
},
// checkbox
checkboxString: function () {
const str = this.checkboxList.join();
return str;
}
},
watch: {
radioValue: 'radioChange',
cycleTotal: 'cycleChange',
averageTotal: 'averageChange',
checkboxString: 'checkboxChange'
},
mounted: function () {
//
this.fullYear = Number(new Date().getFullYear());
this.cycle01 = this.fullYear;
this.average01 = this.fullYear;
},
methods: {
//
radioChange() {
switch (this.radioValue) {
case 1:
this.$emit('update', 'year', '');
break;
case 2:
this.$emit('update', 'year', '*');
break;
case 3:
this.$emit('update', 'year', this.cycleTotal);
break;
case 4:
this.$emit('update', 'year', this.averageTotal);
break;
case 5:
this.$emit('update', 'year', this.checkboxString);
break;
}
},
//
cycleChange() {
if (this.radioValue == '3') {
this.$emit('update', 'year', this.cycleTotal);
}
},
//
averageChange() {
if (this.radioValue == '4') {
this.$emit('update', 'year', this.averageTotal);
}
},
// checkbox
checkboxChange() {
if (this.radioValue == '5') {
this.$emit('update', 'year', this.checkboxString);
}
}
}
};
</script>

@ -83,17 +83,17 @@
</template>
<script>
import draggable from 'vuedraggable'
import draggable from 'vuedraggable';
export default {
components: { draggable },
props: {
tableList: {
type: Array,
default: () => [],
default: () => []
},
tableLoading: {
type: Boolean,
default: false,
default: false
},
queryParams: {
required: true,
@ -101,18 +101,18 @@ export default {
default: () => ({
pageNum: 1,
pageSize: 10,
total: 0,
}),
total: 0
})
},
//
tableBtns: {
type: Array,
default: () => [],
default: () => []
},
//
selectable: {
type: Boolean,
default: false,
default: false
},
/**
* 接口访问得到的所有表格列/或者写死的表格列格
@ -121,7 +121,7 @@ export default {
tableAllFields: {
required: true,
type: Array,
default: () => [],
default: () => []
},
/**
* 默认表格列
@ -129,27 +129,27 @@ export default {
*/
defaultColumns: {
type: Array,
default: () => [],
default: () => []
},
tablename: {
type: String,
default: '',
default: ''
},
//
clickColumns: {
type: Array,
default: () => [],
default: () => []
},
//
btnShowValid: {
type: Array,
default: () => [],
default: () => []
},
//
sortableColumns: {
type: Array,
default: () => [],
},
default: () => []
}
},
data() {
return {
@ -158,102 +158,92 @@ export default {
dialogSelectColumn: [],
name: this.tablename || this.$route.name,
customColumns: [], //
tableColumns: [], //
}
tableColumns: [] //
};
},
watch: {
tableAllFields: {
handler(val) {
const localStr = localStorage.getItem(this.name)
const arr = localStr ? localStr.split(',') : []
const localStr = localStorage.getItem(this.name);
const arr = localStr ? localStr.split(',') : [];
if (this.isNullOrEmpty(arr)) {
this.tableColumns = val
.filter((item) => this.defaultColumns.includes(item.prop))
.sort(
(a, b) =>
this.defaultColumns.indexOf(a.prop) -
this.defaultColumns.indexOf(b.prop)
)
this.customColumns = this.defaultColumns
.sort((a, b) => this.defaultColumns.indexOf(a.prop) - this.defaultColumns.indexOf(b.prop));
this.customColumns = this.defaultColumns;
} else {
this.tableColumns = val
.filter((item) => arr.includes(item.prop))
.sort((a, b) => arr.indexOf(a.prop) - arr.indexOf(b.prop))
this.tableColumns = val.filter((item) => arr.includes(item.prop)).sort((a, b) => arr.indexOf(a.prop) - arr.indexOf(b.prop));
}
},
immediate: true,
deep: true,
},
deep: true
}
},
created() {
if (this.isNullOrEmpty(this.customColumns)) {
const localStr = localStorage.getItem(this.name)
this.customColumns = localStr ? localStr.split(',') : []
const localStr = localStorage.getItem(this.name);
this.customColumns = localStr ? localStr.split(',') : [];
}
},
methods: {
showCustomClick() {
this.columnsetDialogShow = true
this.dialogSelectColumn = [...this.customColumns]
this.columnsetDialogShow = true;
this.dialogSelectColumn = [...this.customColumns];
},
handleChangeColumns() {
this.customColumns = this.dialogSelectColumn
this.customColumns = this.dialogSelectColumn;
this.tableColumns = this.tableAllFields
.filter((item) => this.customColumns.includes(item.prop))
.sort(
(a, b) =>
this.customColumns.indexOf(a.prop) -
this.customColumns.indexOf(b.prop)
)
localStorage.setItem(this.name, this.customColumns.join(','))
this.columnsetDialogShow = false
.sort((a, b) => this.customColumns.indexOf(a.prop) - this.customColumns.indexOf(b.prop));
localStorage.setItem(this.name, this.customColumns.join(','));
this.columnsetDialogShow = false;
},
_getTableList() {
this.$emit('update:queryParams', this.queryParams)
this.$emit('getlist')
this.$emit('update:queryParams', this.queryParams);
this.$emit('getlist');
},
handleSelectionChange(row) {
this.selectable && this.$emit('selectRow', row)
this.selectable && this.$emit('selectRow', row);
},
changeSort(val) {
this.$emit('changeSort', val)
this.$emit('changeSort', val);
},
handleRowClick(row) {
this.$emit('clickRow', row)
this.$emit('clickRow', row);
},
call(funcName, row) {
this.$emit('callFunc', funcName, row)
this.$emit('callFunc', funcName, row);
},
getOpearateWidth() {
let width = 30
let width = 30;
for (let index = 0; index < this.tableBtns.length; index++) {
if (index < 2) {
const column = this.tableBtns[index]
width += column.buttonName.length * 15
column.buttonColor !== 'text' && (width += 30)
const column = this.tableBtns[index];
width += column.buttonName.length * 15;
column.buttonColor !== 'text' && (width += 30);
} else {
width += 70 //
break
width += 70; //
break;
}
}
return width
return width;
},
btnShow(row, btn) {
if (this.isNullOrEmpty(this.btnShowValid)) {
return true
return true;
} else {
let show = true
let show = true;
for (let i = 0; i < this.btnShowValid.length; i++) {
const valid = this.btnShowValid[i]
const valid = this.btnShowValid[i];
if (row[valid.key] === valid.value) {
show = btn.buttonName !== valid.btnName
show = btn.buttonName !== valid.btnName;
}
}
return show
return show;
}
},
},
}
}
}
};
</script>
<style scoped>

@ -1,20 +1,20 @@
import Vue from 'vue'
import store from '@/store'
import DataDict from '@/utils/dict'
import { getDicts as getDicts } from '@/api/system/dict/data'
import Vue from 'vue';
import store from '@/store';
import DataDict from '@/utils/dict';
import { getDicts as getDicts } from '@/api/system/dict/data';
function searchDictByKey(dict, key) {
if (key == null && key == "") {
return null
if (key == null && key == '') {
return null;
}
try {
for (let i = 0; i < dict.length; i++) {
if (dict[i].key == key) {
return dict[i].value
return dict[i].value;
}
}
} catch (e) {
return null
return null;
}
}
@ -25,25 +25,29 @@ function install() {
labelField: 'dictLabel',
valueField: 'dictValue',
request(dictMeta) {
const storeDict = searchDictByKey(store.getters.dict, dictMeta.type)
const storeDict = searchDictByKey(store.getters.dict, dictMeta.type);
if (storeDict) {
return new Promise(resolve => { resolve(storeDict) })
return new Promise((resolve) => {
resolve(storeDict);
});
} else {
return new Promise((resolve, reject) => {
getDicts(dictMeta.type).then(res => {
store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data })
resolve(res.data)
}).catch(error => {
reject(error)
})
})
getDicts(dictMeta.type)
.then((res) => {
store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data });
resolve(res.data);
})
.catch((error) => {
reject(error);
});
});
}
},
},
},
})
}
}
}
});
}
export default {
install,
}
install
};

@ -2,21 +2,8 @@
<div>
<template v-for="(item, index) in options">
<template v-if="values.includes(item.value)">
<span
v-if="item.raw.listClass == 'default' || item.raw.listClass == ''"
:key="item.value"
:index="index"
:class="item.raw.cssClass"
>{{ item.label }}</span
>
<el-tag
v-else
:disable-transitions="true"
:key="item.value"
:index="index"
:type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
:class="item.raw.cssClass"
>
<span v-if="item.raw.listClass == 'default' || item.raw.listClass == ''" :key="item.value" :index="index" :class="item.raw.cssClass">{{ item.label }}</span>
<el-tag v-else :key="item.value" :disable-transitions="true" :index="index" :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass" :class="item.raw.cssClass">
{{ item.label }}
</el-tag>
</template>
@ -26,13 +13,13 @@
<script>
export default {
name: "DictTag",
name: 'DictTag',
props: {
options: {
type: Array,
default: null,
default: null
},
value: [Number, String, Array],
value: [Number, String, Array]
},
computed: {
values() {
@ -41,12 +28,12 @@ export default {
} else {
return [];
}
},
},
}
}
};
</script>
<style scoped>
.el-tag + .el-tag {
margin-left: 10px;
}
</style>
</style>

@ -1,98 +1,86 @@
<template>
<div>
<el-upload
:action="uploadUrl"
:before-upload="handleBeforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
name="file"
:show-file-list="false"
:headers="headers"
style="display: none"
ref="upload"
v-if="this.type == 'url'"
>
</el-upload>
<div class="editor" ref="editor" :style="styles"></div>
<el-upload v-if="type == 'url'" ref="upload" :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess" :on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" style="display: none" />
<div ref="editor" class="editor" :style="styles" />
</div>
</template>
<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { getToken } from "@/utils/auth";
import Quill from 'quill';
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import { getToken } from '@/utils/auth';
export default {
name: "Editor",
name: 'Editor',
props: {
/* 编辑器的内容 */
value: {
type: String,
default: "",
default: ''
},
/* 高度 */
height: {
type: Number,
default: null,
default: null
},
/* 最小高度 */
minHeight: {
type: Number,
default: null,
default: null
},
/* 只读 */
readOnly: {
type: Boolean,
default: false,
default: false
},
// (MB)
fileSize: {
type: Number,
default: 5,
default: 5
},
/* 类型(base64格式、url格式) */
type: {
type: String,
default: "url",
default: 'url'
}
},
data() {
return {
uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
uploadUrl: process.env.VUE_APP_BASE_API + '/common/upload', //
headers: {
Authorization: "Bearer " + getToken()
Authorization: 'Bearer ' + getToken()
},
Quill: null,
currentValue: "",
currentValue: '',
options: {
theme: "snow",
theme: 'snow',
bounds: document.body,
debug: "warn",
debug: 'warn',
modules: {
//
toolbar: [
["bold", "italic", "underline", "strike"], // 线 线
["blockquote", "code-block"], //
[{ list: "ordered" }, { list: "bullet" }], //
[{ indent: "-1" }, { indent: "+1" }], //
[{ size: ["small", false, "large", "huge"] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], //
[{ align: [] }], //
["clean"], //
["link", "image", "video"] //
],
['bold', 'italic', 'underline', 'strike'], // 线 线
['blockquote', 'code-block'], //
[{ list: 'ordered' }, { list: 'bullet' }], //
[{ indent: '-1' }, { indent: '+1' }], //
[{ size: ['small', false, 'large', 'huge'] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], //
[{ align: [] }], //
['clean'], //
['link', 'image', 'video'] //
]
},
placeholder: "请输入内容",
readOnly: this.readOnly,
},
placeholder: '请输入内容',
readOnly: this.readOnly
}
};
},
computed: {
styles() {
let style = {};
const style = {};
if (this.minHeight) {
style.minHeight = `${this.minHeight}px`;
}
@ -100,20 +88,20 @@ export default {
style.height = `${this.height}px`;
}
return style;
},
}
},
watch: {
value: {
handler(val) {
if (val !== this.currentValue) {
this.currentValue = val === null ? "" : val;
this.currentValue = val === null ? '' : val;
if (this.Quill) {
this.Quill.pasteHTML(this.currentValue);
}
}
},
immediate: true,
},
immediate: true
}
},
mounted() {
this.init();
@ -127,33 +115,33 @@ export default {
this.Quill = new Quill(editor, this.options);
//
if (this.type == 'url') {
let toolbar = this.Quill.getModule("toolbar");
toolbar.addHandler("image", (value) => {
this.uploadType = "image";
const toolbar = this.Quill.getModule('toolbar');
toolbar.addHandler('image', (value) => {
this.uploadType = 'image';
if (value) {
this.$refs.upload.$children[0].$refs.input.click();
} else {
this.quill.format("image", false);
this.quill.format('image', false);
}
});
}
this.Quill.pasteHTML(this.currentValue);
this.Quill.on("text-change", (delta, oldDelta, source) => {
this.Quill.on('text-change', (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML;
const text = this.Quill.getText();
const quill = this.Quill;
this.currentValue = html;
this.$emit("input", html);
this.$emit("on-change", { html, text, quill });
this.$emit('input', html);
this.$emit('on-change', { html, text, quill });
});
this.Quill.on("text-change", (delta, oldDelta, source) => {
this.$emit("on-text-change", delta, oldDelta, source);
this.Quill.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source);
});
this.Quill.on("selection-change", (range, oldRange, source) => {
this.$emit("on-selection-change", range, oldRange, source);
this.Quill.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source);
});
this.Quill.on("editor-change", (eventName, ...args) => {
this.$emit("on-editor-change", eventName, ...args);
this.Quill.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args);
});
},
//
@ -170,103 +158,104 @@ export default {
},
handleUploadSuccess(res, file) {
//
let quill = this.Quill;
const quill = this.Quill;
//
if (res.code == 200) {
//
let length = quill.getSelection().index;
const length = quill.getSelection().index;
// res.url
quill.insertEmbed(length, "image", process.env.VUE_APP_BASE_API + res.fileName);
quill.insertEmbed(length, 'image', process.env.VUE_APP_BASE_API + res.fileName);
//
quill.setSelection(length + 1);
} else {
this.$message.error("图片插入失败");
this.$message.error('图片插入失败');
}
},
handleUploadError() {
this.$message.error("图片插入失败");
},
},
this.$message.error('图片插入失败');
}
}
};
</script>
<style>
.editor, .ql-toolbar {
.editor,
.ql-toolbar {
white-space: pre-wrap !important;
line-height: normal !important;
}
.quill-img {
display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
content: "请输入链接地址:";
.ql-snow .ql-tooltip[data-mode='link']::before {
content: '请输入链接地址:';
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px;
content: "保存";
content: '保存';
padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
content: "请输入视频地址:";
.ql-snow .ql-tooltip[data-mode='video']::before {
content: '请输入视频地址:';
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: "14px";
content: '14px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
content: "10px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before {
content: '10px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
content: "18px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before {
content: '18px';
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
content: "32px";
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before {
content: '32px';
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: "文本";
content: '文本';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: "标题1";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: "标题2";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
content: '标题2';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: "标题3";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
content: '标题3';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: "标题4";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
content: '标题4';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: "标题5";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
content: "标题6";
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
content: '标题6';
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "标准字体";
content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
content: "衬线字体";
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: "等宽字体";
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
content: '等宽字体';
}
</style>

@ -1,23 +1,10 @@
<template>
<div class="upload-file">
<el-upload
multiple
:action="uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:show-file-list="false"
:headers="headers"
class="upload-file-uploader"
ref="fileUpload"
>
<el-upload ref="fileUpload" multiple :action="uploadFileUrl" :before-upload="handleBeforeUpload" :file-list="fileList" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" :on-success="handleUploadSuccess" :show-file-list="false" :headers="headers" class="upload-file-uploader">
<!-- 上传按钮 -->
<el-button size="mini" type="primary">选取文件</el-button>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
<div v-if="showTip" slot="tip" class="el-upload__tip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
@ -27,12 +14,12 @@
<!-- 文件列表 -->
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
<li v-for="(file, index) in fileList" :key="file.url" class="el-upload-list__item ele-upload-list__item-content">
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link>
<div class="ele-upload-list__item-content-action">
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
<el-link :underline="false" type="danger" @click="handleDelete(index)">删除</el-link>
</div>
</li>
</transition-group>
@ -40,27 +27,27 @@
</template>
<script>
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth';
export default {
name: "FileUpload",
name: 'FileUpload',
props: {
//
value: [String, Object, Array],
//
limit: {
type: Number,
default: 5,
default: 5
},
// (MB)
fileSize: {
type: Number,
default: 5,
default: 5
},
// , ['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["doc", "xls", "ppt", "txt", "pdf"],
default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf']
},
//
isShowTip: {
@ -73,13 +60,19 @@ export default {
number: 0,
uploadList: [],
baseUrl: process.env.VUE_APP_BASE_API,
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
uploadFileUrl: process.env.VUE_APP_BASE_API + '/common/upload', //
headers: {
Authorization: "Bearer " + getToken(),
Authorization: 'Bearer ' + getToken()
},
fileList: [],
fileList: []
};
},
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
}
},
watch: {
value: {
handler(val) {
@ -88,8 +81,8 @@ export default {
//
const list = Array.isArray(val) ? val : this.value.split(',');
//
this.fileList = list.map(item => {
if (typeof item === "string") {
this.fileList = list.map((item) => {
if (typeof item === 'string') {
item = { name: item, url: item };
}
item.uid = item.uid || new Date().getTime() + temp++;
@ -104,12 +97,6 @@ export default {
immediate: true
}
},
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
},
},
methods: {
//
handleBeforeUpload(file) {
@ -119,7 +106,7 @@ export default {
const fileExt = fileName[fileName.length - 1];
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`);
return false;
}
}
@ -131,7 +118,7 @@ export default {
return false;
}
}
this.$modal.loading("正在上传文件,请稍候...");
this.$modal.loading('正在上传文件,请稍候...');
this.number++;
return true;
},
@ -140,9 +127,9 @@ export default {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
},
//
handleUploadError(err) {
this.$modal.msgError("上传文件失败,请重试");
this.$modal.closeLoading()
handleUploadError() {
this.$modal.msgError('上传文件失败,请重试');
this.$modal.closeLoading();
},
//
handleUploadSuccess(res, file) {
@ -160,7 +147,7 @@ export default {
//
handleDelete(index) {
this.fileList.splice(index, 1);
this.$emit("input", this.listToString(this.fileList));
this.$emit('input', this.listToString(this.fileList));
},
//
uploadedSuccessfully() {
@ -168,23 +155,23 @@ export default {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$emit('input', this.listToString(this.fileList));
this.$modal.closeLoading();
}
},
//
getFileName(name) {
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1);
if (name.lastIndexOf('/') > -1) {
return name.slice(name.lastIndexOf('/') + 1);
} else {
return "";
return '';
}
},
//
listToString(list, separator) {
let strs = "";
separator = separator || ",";
for (let i in list) {
let strs = '';
separator = separator || ',';
for (const i in list) {
strs += list[i].url + separator;
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';

@ -1,13 +1,6 @@
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<svg :class="{'is-active':isActive}" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
@ -24,10 +17,10 @@ export default {
},
methods: {
toggleClick() {
this.$emit('toggleClick')
this.$emit('toggleClick');
}
}
}
};
</script>
<style scoped>

@ -1,17 +1,7 @@
<template>
<div :class="{'show':show}" class="header-search">
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
<el-select
ref="headerSearchSelect"
v-model="search"
:remote-method="querySearch"
filterable
default-first-option
remote
placeholder="Search"
class="header-search-select"
@change="change"
>
<el-select ref="headerSearchSelect" v-model="search" :remote-method="querySearch" filterable default-first-option remote placeholder="Search" class="header-search-select" @change="change">
<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
</el-select>
</div>
@ -20,8 +10,8 @@
<script>
// fuse is a lightweight fuzzy-search module
// make search results more in line with expectations
import Fuse from 'fuse.js/dist/fuse.min.js'
import path from 'path'
import Fuse from 'fuse.js/dist/fuse.min.js';
import path from 'path';
export default {
name: 'HeaderSearch',
@ -32,57 +22,57 @@ export default {
searchPool: [],
show: false,
fuse: undefined
}
};
},
computed: {
routes() {
return this.$store.getters.permission_routes
return this.$store.getters.permission_routes;
}
},
watch: {
routes() {
this.searchPool = this.generateRoutes(this.routes)
this.searchPool = this.generateRoutes(this.routes);
},
searchPool(list) {
this.initFuse(list)
this.initFuse(list);
},
show(value) {
if (value) {
document.body.addEventListener('click', this.close)
document.body.addEventListener('click', this.close);
} else {
document.body.removeEventListener('click', this.close)
document.body.removeEventListener('click', this.close);
}
}
},
mounted() {
this.searchPool = this.generateRoutes(this.routes)
this.searchPool = this.generateRoutes(this.routes);
},
methods: {
click() {
this.show = !this.show
this.show = !this.show;
if (this.show) {
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus()
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus();
}
},
close() {
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur()
this.options = []
this.show = false
this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur();
this.options = [];
this.show = false;
},
change(val) {
const path = val.path;
if(this.ishttp(val.path)) {
if (this.ishttp(val.path)) {
// http(s)://
const pindex = path.indexOf("http");
window.open(path.substr(pindex, path.length), "_blank");
const pindex = path.indexOf('http');
window.open(path.substr(pindex, path.length), '_blank');
} else {
this.$router.push(val.path)
this.$router.push(val.path);
}
this.search = ''
this.options = []
this.search = '';
this.options = [];
this.$nextTick(() => {
this.show = false
})
this.show = false;
});
},
initFuse(list) {
this.fuse = new Fuse(list, {
@ -92,61 +82,66 @@ export default {
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: [{
name: 'title',
weight: 0.7
}, {
name: 'path',
weight: 0.3
}]
})
keys: [
{
name: 'title',
weight: 0.7
},
{
name: 'path',
weight: 0.3
}
]
});
},
// Filter out the routes that can be displayed in the sidebar
// And generate the internationalized title
generateRoutes(routes, basePath = '/', prefixTitle = []) {
let res = []
let res = [];
for (const router of routes) {
// skip hidden router
if (router.hidden) { continue }
if (router.hidden) {
continue;
}
const data = {
path: !this.ishttp(router.path) ? path.resolve(basePath, router.path) : router.path,
title: [...prefixTitle]
}
};
if (router.meta && router.meta.title) {
data.title = [...data.title, router.meta.title]
data.title = [...data.title, router.meta.title];
if (router.redirect !== 'noRedirect') {
// only push the routes with title
// special case: need to exclude parent router without redirect
res.push(data)
res.push(data);
}
}
// recursive child routes
if (router.children) {
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
const tempRoutes = this.generateRoutes(router.children, data.path, data.title);
if (tempRoutes.length >= 1) {
res = [...res, ...tempRoutes]
res = [...res, ...tempRoutes];
}
}
}
return res
return res;
},
querySearch(query) {
if (query !== '') {
this.options = this.fuse.search(query)
this.options = this.fuse.search(query);
} else {
this.options = []
this.options = [];
}
},
ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
}
}
}
};
</script>
<style lang="scss" scoped>

@ -14,55 +14,55 @@
</template>
<script>
import icons from './requireIcons'
import icons from './requireIcons';
export default {
name: 'IconSelect',
data() {
return {
name: '',
iconList: icons
}
};
},
methods: {
filterIcons() {
this.iconList = icons
this.iconList = icons;
if (this.name) {
this.iconList = this.iconList.filter(item => item.includes(this.name))
this.iconList = this.iconList.filter((item) => item.includes(this.name));
}
},
selectedIcon(name) {
this.$emit('selected', name)
document.body.click()
this.$emit('selected', name);
document.body.click();
},
reset() {
this.name = ''
this.iconList = icons
this.name = '';
this.iconList = icons;
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.icon-body {
width: 100%;
padding: 10px;
.icon-list {
height: 200px;
overflow-y: scroll;
div {
height: 30px;
line-height: 30px;
margin-bottom: -5px;
cursor: pointer;
width: 33%;
float: left;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.icon-body {
width: 100%;
padding: 10px;
.icon-list {
height: 200px;
overflow-y: scroll;
div {
height: 30px;
line-height: 30px;
margin-bottom: -5px;
cursor: pointer;
width: 33%;
float: left;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
}
}
</style>

@ -1,11 +1,10 @@
const req = require.context('../../assets/icons/svg', false, /\.svg$/);
const requireAll = (requireContext) => requireContext.keys();
const req = require.context('../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/;
const re = /\.\/(.*)\.svg/
const icons = requireAll(req).map((i) => {
return i.match(re)[1];
});
const icons = requireAll(req).map(i => {
return i.match(re)[1]
})
export default icons
export default icons;

@ -1,33 +1,28 @@
<template>
<el-image
:src="`${realSrc}`"
fit="cover"
:style="`width:${realWidth};height:${realHeight};`"
:preview-src-list="realSrcList"
>
<el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
<i class="el-icon-picture-outline" />
</div>
</el-image>
</template>
<script>
import { isExternal } from "@/utils/validate";
import { isExternal } from '@/utils/validate';
export default {
name: "ImagePreview",
name: 'ImagePreview',
props: {
src: {
type: String,
default: ""
default: ''
},
width: {
type: [Number, String],
default: ""
default: ''
},
height: {
type: [Number, String],
default: ""
default: ''
}
},
computed: {
@ -35,7 +30,7 @@ export default {
if (!this.src) {
return;
}
let real_src = this.src.split(",")[0];
const real_src = this.src.split(',')[0];
if (isExternal(real_src)) {
return real_src;
}
@ -45,9 +40,9 @@ export default {
if (!this.src) {
return;
}
let real_src_list = this.src.split(",");
let srcList = [];
real_src_list.forEach(item => {
const real_src_list = this.src.split(',');
const srcList = [];
real_src_list.forEach((item) => {
if (isExternal(item)) {
return srcList.push(item);
}
@ -56,12 +51,12 @@ export default {
return srcList;
},
realWidth() {
return typeof this.width == "string" ? this.width : `${this.width}px`;
return typeof this.width == 'string' ? this.width : `${this.width}px`;
},
realHeight() {
return typeof this.height == "string" ? this.height : `${this.height}px`;
return typeof this.height == 'string' ? this.height : `${this.height}px`;
}
},
}
};
</script>

@ -1,49 +1,25 @@
<template>
<div class="component-upload-image">
<el-upload
multiple
:action="uploadImgUrl"
list-type="picture-card"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
ref="imageUpload"
:on-remove="handleDelete"
:show-file-list="true"
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{hide: this.fileList.length >= this.limit}"
>
<i class="el-icon-plus"></i>
<el-upload ref="imageUpload" multiple :action="uploadImgUrl" list-type="picture-card" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" :on-remove="handleDelete" :show-file-list="true" :headers="headers" :file-list="fileList" :on-preview="handlePictureCardPreview" :class="{hide: fileList.length >= limit}">
<i class="el-icon-plus" />
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
<div v-if="showTip" slot="tip" class="el-upload__tip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
的文件
</div>
<el-dialog
:visible.sync="dialogVisible"
title="预览"
width="800"
append-to-body
>
<img
:src="dialogImageUrl"
style="display: block; max-width: 100%; margin: 0 auto"
/>
<el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
<img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto">
</el-dialog>
</div>
</template>
<script>
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth';
export default {
props: {
@ -51,17 +27,17 @@ export default {
//
limit: {
type: Number,
default: 5,
default: 5
},
// (MB)
fileSize: {
type: Number,
default: 5,
type: Number,
default: 5
},
// , ['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["png", "jpg", "jpeg"],
default: () => ['png', 'jpg', 'jpeg']
},
//
isShowTip: {
@ -73,17 +49,23 @@ export default {
return {
number: 0,
uploadList: [],
dialogImageUrl: "",
dialogImageUrl: '',
dialogVisible: false,
hideUpload: false,
baseUrl: process.env.VUE_APP_BASE_API,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
uploadImgUrl: process.env.VUE_APP_BASE_API + '/common/upload', //
headers: {
Authorization: "Bearer " + getToken(),
Authorization: 'Bearer ' + getToken()
},
fileList: []
};
},
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
}
},
watch: {
value: {
handler(val) {
@ -91,12 +73,12 @@ export default {
//
const list = Array.isArray(val) ? val : this.value.split(',');
//
this.fileList = list.map(item => {
if (typeof item === "string") {
this.fileList = list.map((item) => {
if (typeof item === 'string') {
if (item.indexOf(this.baseUrl) === -1) {
item = { name: this.baseUrl + item, url: this.baseUrl + item };
item = { name: this.baseUrl + item, url: this.baseUrl + item };
} else {
item = { name: item, url: item };
item = { name: item, url: item };
}
}
return item;
@ -110,32 +92,26 @@ export default {
immediate: true
}
},
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
},
},
methods: {
// loading
handleBeforeUpload(file) {
let isImg = false;
if (this.fileType.length) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
let fileExtension = '';
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1);
}
isImg = this.fileType.some(type => {
isImg = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
} else {
isImg = file.type.indexOf("image") > -1;
isImg = file.type.indexOf('image') > -1;
}
if (!isImg) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`);
return false;
}
if (this.fileSize) {
@ -145,7 +121,7 @@ export default {
return false;
}
}
this.$modal.loading("正在上传图片,请稍候...");
this.$modal.loading('正在上传图片,请稍候...');
this.number++;
},
//
@ -167,15 +143,15 @@ export default {
},
//
handleDelete(file) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
if(findex > -1) {
const findex = this.fileList.map((f) => f.name).indexOf(file.name);
if (findex > -1) {
this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
this.$emit('input', this.listToString(this.fileList));
}
},
//
handleUploadError() {
this.$modal.msgError("上传图片失败,请重试");
this.$modal.msgError('上传图片失败,请重试');
this.$modal.closeLoading();
},
//
@ -184,7 +160,7 @@ export default {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$emit('input', this.listToString(this.fileList));
this.$modal.closeLoading();
}
},
@ -195,11 +171,11 @@ export default {
},
//
listToString(list, separator) {
let strs = "";
separator = separator || ",";
for (let i in list) {
let strs = '';
separator = separator || ',';
for (const i in list) {
if (list[i].url) {
strs += list[i].url.replace(this.baseUrl, "") + separator;
strs += list[i].url.replace(this.baseUrl, '') + separator;
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
@ -210,17 +186,18 @@ export default {
<style scoped lang="scss">
// .el-upload--picture-card
::v-deep.hide .el-upload--picture-card {
display: none;
display: none;
}
//
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
transition: all 0s;
}
::v-deep .el-list-enter, .el-list-leave-active {
opacity: 0;
transform: translateY(0);
::v-deep .el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: translateY(0);
}
</style>

@ -1,22 +1,11 @@
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:pager-count="pagerCount"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<el-pagination :background="background" :current-page.sync="currentPage" :page-size.sync="pageSize" :layout="layout" :page-sizes="pageSizes" :pager-count="pagerCount" :total="total" v-bind="$attrs" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to'
import { scrollTo } from '@/utils/scroll-to';
export default {
name: 'Pagination',
@ -36,7 +25,7 @@ export default {
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
return [10, 20, 30, 50];
}
},
// 5
@ -62,45 +51,44 @@ export default {
}
},
data() {
return {
};
return {};
},
computed: {
currentPage: {
get() {
return this.page
return this.page;
},
set(val) {
this.$emit('update:page', val)
this.$emit('update:page', val);
}
},
pageSize: {
get() {
return this.limit
return this.limit;
},
set(val) {
this.$emit('update:limit', val)
this.$emit('update:limit', val);
}
}
},
methods: {
handleSizeChange(val) {
if (this.currentPage * val > this.total) {
this.currentPage = 1
this.currentPage = 1;
}
this.$emit('pagination', { page: this.currentPage, limit: val })
this.$emit('pagination', { page: this.currentPage, limit: val });
if (this.autoScroll) {
scrollTo(0, 800)
scrollTo(0, 800);
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
this.$emit('pagination', { page: val, limit: this.pageSize });
if (this.autoScroll) {
scrollTo(0, 800)
scrollTo(0, 800);
}
}
}
}
};
</script>
<style scoped>

@ -31,7 +31,7 @@ export default {
default: '150px'
}
}
}
};
</script>
<style scoped>

@ -1,3 +1,3 @@
<template >
<template>
<router-view />
</template>

@ -21,49 +21,49 @@ export default {
computed: {
show: {
get() {
return this.$store.state.settings.showSettings
return this.$store.state.settings.showSettings;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val
})
});
}
}
},
watch: {
show(value) {
if (value && !this.clickNotClose) {
this.addEventClick()
this.addEventClick();
}
}
},
mounted() {
this.insertToBody()
this.addEventClick()
this.insertToBody();
this.addEventClick();
},
beforeDestroy() {
const elx = this.$refs.rightPanel
elx.remove()
const elx = this.$refs.rightPanel;
elx.remove();
},
methods: {
addEventClick() {
window.addEventListener('click', this.closeSidebar)
window.addEventListener('click', this.closeSidebar);
},
closeSidebar(evt) {
const parent = evt.target.closest('.el-drawer__body')
const parent = evt.target.closest('.el-drawer__body');
if (!parent) {
this.show = false
window.removeEventListener('click', this.closeSidebar)
this.show = false;
window.removeEventListener('click', this.closeSidebar);
}
},
insertToBody() {
const elx = this.$refs.rightPanel
const body = document.querySelector('body')
body.insertBefore(elx, body.firstChild)
const elx = this.$refs.rightPanel;
const body = document.querySelector('body');
body.insertBefore(elx, body.firstChild);
}
}
}
};
</script>
<style lang="scss" scoped>
@ -72,8 +72,8 @@ export default {
top: 0;
left: 0;
opacity: 0;
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
background: rgba(0, 0, 0, .2);
transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
background: rgba(0, 0, 0, 0.2);
z-index: -1;
}
@ -84,8 +84,8 @@ export default {
position: fixed;
top: 0;
right: 0;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
transition: all .25s cubic-bezier(.7, .3, .1, 1);
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.05);
transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
transform: translate(100%);
background: #fff;
z-index: 40000;

@ -1,55 +1,51 @@
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-tooltip v-if="search" class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top">
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
<el-tooltip v-if="columns" class="item" effect="dark" content="显隐列" placement="top">
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
</el-tooltip>
</el-row>
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-transfer
:titles="['显示', '隐藏']"
v-model="value"
:data="columns"
@change="dataChange"
></el-transfer>
<el-transfer v-model="value" :titles="['显示', '隐藏']" :data="columns" @change="dataChange" />
</el-dialog>
</div>
</template>
<script>
export default {
name: "RightToolbar",
data() {
return {
//
value: [],
//
title: "显示/隐藏",
//
open: false,
};
},
name: 'RightToolbar',
props: {
showSearch: {
type: Boolean,
default: true,
default: true
},
columns: {
type: Array,
default: () => []
},
search: {
type: Boolean,
default: true,
default: true
},
gutter: {
type: Number,
default: 10,
},
default: 10
}
},
data() {
return {
//
value: [],
//
title: '显示/隐藏',
//
open: false
};
},
computed: {
style() {
@ -62,7 +58,7 @@ export default {
},
created() {
//
for (let item in this.columns) {
for (const item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item));
}
@ -71,24 +67,25 @@ export default {
methods: {
//
toggleSearch() {
this.$emit("update:showSearch", !this.showSearch);
this.$emit('update:showSearch', !this.showSearch);
},
//
refresh() {
this.$emit("queryTable");
this.$emit('queryTable');
},
//
dataChange(data) {
for (let item in this.columns) {
for (const item in this.columns) {
const key = this.columns[item].key;
// eslint-disable-next-line vue/no-mutating-props
this.columns[item].visible = !data.includes(key);
}
},
// dialog
showColumn() {
this.open = true;
},
},
}
}
};
</script>
<style lang="scss" scoped>

@ -1,21 +0,0 @@
<template>
<div>
<svg-icon icon-class="question" @click="goto" />
</div>
</template>
<script>
export default {
name: 'RuoYiDoc',
data() {
return {
url: 'http://doc.ruoyi.vip/ruoyi-vue'
}
},
methods: {
goto() {
window.open(this.url)
}
}
}
</script>

@ -1,21 +0,0 @@
<template>
<div>
<svg-icon icon-class="github" @click="goto" />
</div>
</template>
<script>
export default {
name: 'RuoYiGit',
data() {
return {
url: 'https://gitee.com/y_project/RuoYi-Vue'
}
},
methods: {
goto() {
window.open(this.url)
}
}
}
</script>

@ -5,51 +5,51 @@
</template>
<script>
import screenfull from 'screenfull'
import screenfull from 'screenfull';
export default {
name: 'Screenfull',
data() {
return {
isFullscreen: false
}
};
},
mounted() {
this.init()
this.init();
},
beforeDestroy() {
this.destroy()
this.destroy();
},
methods: {
click() {
if (!screenfull.isEnabled) {
this.$message({ message: '你的浏览器不支持全屏', type: 'warning' })
return false
this.$message({ message: '你的浏览器不支持全屏', type: 'warning' });
return false;
}
screenfull.toggle()
screenfull.toggle();
},
change() {
this.isFullscreen = screenfull.isFullscreen
this.isFullscreen = screenfull.isFullscreen;
},
init() {
if (screenfull.isEnabled) {
screenfull.on('change', this.change)
screenfull.on('change', this.change);
}
},
destroy() {
if (screenfull.isEnabled) {
screenfull.off('change', this.change)
screenfull.off('change', this.change);
}
}
}
}
};
</script>
<style scoped>
.screenfull-svg {
display: inline-block;
cursor: pointer;
fill: #5a5e66;;
fill: #5a5e66;
width: 20px;
height: 20px;
vertical-align: 10px;

@ -21,36 +21,35 @@ export default {
{ label: 'Small', value: 'small' },
{ label: 'Mini', value: 'mini' }
]
}
};
},
computed: {
size() {
return this.$store.getters.size
return this.$store.getters.size;
}
},
methods: {
handleSetSize(size) {
this.$ELEMENT.size = size
this.$store.dispatch('app/setSize', size)
this.refreshView()
this.$ELEMENT.size = size;
this.$store.dispatch('app/setSize', size);
this.refreshView();
this.$message({
message: 'Switch Size Success',
type: 'success'
})
});
},
refreshView() {
// In order to make the cached page re-rendered
this.$store.dispatch('tagsView/delAllCachedViews', this.$route)
this.$store.dispatch('tagsView/delAllCachedViews', this.$route);
const { fullPath } = this.$route
const { fullPath } = this.$route;
this.$nextTick(() => {
this.$router.replace({
path: '/redirect' + fullPath
})
})
});
});
}
}
}
};
</script>

@ -6,7 +6,7 @@
</template>
<script>
import { isExternal } from '@/utils/validate'
import { isExternal } from '@/utils/validate';
export default {
name: 'SvgIcon',
@ -22,26 +22,26 @@ export default {
},
computed: {
isExternal() {
return isExternal(this.iconClass)
return isExternal(this.iconClass);
},
iconName() {
return `#icon-${this.iconClass}`
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
return 'svg-icon ' + this.className;
} else {
return 'svg-icon'
return 'svg-icon';
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
};
}
}
}
};
</script>
<style scoped>
@ -55,7 +55,7 @@ export default {
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
mask-size: cover !important;
display: inline-block;
}
</style>

@ -1,158 +1,153 @@
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
<el-color-picker v-model="theme" :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" class="theme-picker" popper-class="theme-picker-dropdown" />
</template>
<script>
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
const version = require('element-ui/package.json').version; // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF'; // default color
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
};
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
return this.$store.state.settings.theme;
}
},
watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
handler: function (val, oldVal) {
this.theme = val;
},
immediate: true
},
async theme(val) {
await this.setTheme(val)
await this.setTheme(val);
}
},
created() {
if(this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme)
if (this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme);
}
},
methods: {
async setTheme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME;
if (typeof val !== 'string') return;
const themeCluster = this.getThemeCluster(val.replace('#', ''));
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''));
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''));
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster);
let styleTag = document.getElementById(id)
let styleTag = document.getElementById(id);
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
styleTag = document.createElement('style');
styleTag.setAttribute('id', id);
document.head.appendChild(styleTag);
}
styleTag.innerText = newStyle
}
}
styleTag.innerText = newStyle;
};
};
if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`;
await this.getCSSString(url, 'chalk');
}
const chalkHandler = getHandler('chalk', 'chalk-style')
const chalkHandler = getHandler('chalk', 'chalk-style');
chalkHandler()
chalkHandler();
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
const styles = [].slice.call(document.querySelectorAll('style')).filter((style) => {
const text = style.innerText;
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text);
});
styles.forEach((style) => {
const { innerText } = style;
if (typeof innerText !== 'string') return;
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster);
});
this.$emit('change', val)
this.$emit('change', val);
},
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
let newStyle = style;
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]);
});
return newStyle;
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '');
resolve();
}
}
xhr.open('GET', url)
xhr.send()
})
};
xhr.open('GET', url);
xhr.send();
});
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
if (tint === 0) {
// when primary color is in its rgb space
return [red, green, blue].join(',');
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red += Math.round(tint * (255 - red));
green += Math.round(tint * (255 - green));
blue += Math.round(tint * (255 - blue));
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${red}${green}${blue}`
return `#${red}${green}${blue}`;
}
}
};
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = Math.round((1 - shade) * red);
green = Math.round((1 - shade) * green);
blue = Math.round((1 - shade) * blue);
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${red}${green}${blue}`
}
return `#${red}${green}${blue}`;
};
const clusters = [theme]
const clusters = [theme];
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))));
}
clusters.push(shadeColor(theme, 0.1))
return clusters
clusters.push(shadeColor(theme, 0.1));
return clusters;
}
}
}
};
</script>
<style>

@ -1,34 +1,23 @@
<template>
<el-menu
:default-active="activeMenu"
mode="horizontal"
@select="handleSelect"
>
<el-menu :default-active="activeMenu" mode="horizontal" @select="handleSelect">
<template v-for="(item, index) in topMenus">
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
><svg-icon :icon-class="item.meta.icon" />
{{ item.meta.title }}</el-menu-item
>
<el-menu-item v-if="index < visibleNumber" :key="index" :style="{'--theme': theme}" :index="item.path"><svg-icon :icon-class="item.meta.icon" />
{{ item.meta.title }}</el-menu-item>
</template>
<!-- 顶部菜单超出数量折叠 -->
<el-submenu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
<el-submenu v-if="topMenus.length > visibleNumber" :style="{'--theme': theme}" index="more">
<template slot="title">更多菜单</template>
<template v-for="(item, index) in topMenus">
<el-menu-item
:index="item.path"
:key="index"
v-if="index >= visibleNumber"
><svg-icon :icon-class="item.meta.icon" />
{{ item.meta.title }}</el-menu-item
>
<el-menu-item v-if="index >= visibleNumber" :key="index" :index="item.path"><svg-icon :icon-class="item.meta.icon" />
{{ item.meta.title }}</el-menu-item>
</template>
</el-submenu>
</el-menu>
</template>
<script>
import { constantRoutes } from "@/router";
import { constantRoutes } from '@/router';
//
const hideList = ['/index', '/user/profile'];
@ -48,14 +37,14 @@ export default {
},
//
topMenus() {
let topMenus = [];
const topMenus = [];
this.routers.map((menu) => {
if (menu.hidden !== true) {
//
if (menu.path === "/") {
topMenus.push(menu.children[0]);
if (menu.path === '/') {
topMenus.push(menu.children[0]);
} else {
topMenus.push(menu);
topMenus.push(menu);
}
}
});
@ -71,11 +60,11 @@ export default {
this.routers.map((router) => {
for (var item in router.children) {
if (router.children[item].parentPath === undefined) {
if(router.path === "/") {
router.children[item].path = "/" + router.children[item].path;
if (router.path === '/') {
router.children[item].path = '/' + router.children[item].path;
} else {
if(!this.ishttp(router.children[item].path)) {
router.children[item].path = router.path + "/" + router.children[item].path;
if (!this.ishttp(router.children[item].path)) {
router.children[item].path = router.path + '/' + router.children[item].path;
}
}
router.children[item].parentPath = router.path;
@ -89,23 +78,23 @@ export default {
activeMenu() {
const path = this.$route.path;
let activePath = path;
if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) {
if (path !== undefined && path.lastIndexOf('/') > 0 && hideList.indexOf(path) === -1) {
const tmpPath = path.substring(1, path.length);
activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/"));
activePath = '/' + tmpPath.substring(0, tmpPath.indexOf('/'));
this.$store.dispatch('app/toggleSideBarHide', false);
} else if(!this.$route.children) {
} else if (!this.$route.children) {
activePath = path;
this.$store.dispatch('app/toggleSideBarHide', true);
}
this.activeRoutes(activePath);
return activePath;
},
}
},
beforeMount() {
window.addEventListener('resize', this.setVisibleNumber)
window.addEventListener('resize', this.setVisibleNumber);
},
beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber)
window.removeEventListener('resize', this.setVisibleNumber);
},
mounted() {
this.setVisibleNumber();
@ -119,10 +108,10 @@ export default {
//
handleSelect(key, keyPath) {
this.currentIndex = key;
const route = this.routers.find(item => item.path === key);
const route = this.routers.find((item) => item.path === key);
if (this.ishttp(key)) {
// http(s)://
window.open(key, "_blank");
window.open(key, '_blank');
} else if (!route || !route.children) {
//
this.$router.push({ path: key });
@ -138,19 +127,19 @@ export default {
var routes = [];
if (this.childrenMenus && this.childrenMenus.length > 0) {
this.childrenMenus.map((item) => {
if (key == item.parentPath || (key == "index" && "" == item.path)) {
if (key == item.parentPath || (key == 'index' && item.path == '')) {
routes.push(item);
}
});
}
if(routes.length > 0) {
this.$store.commit("SET_SIDEBAR_ROUTERS", routes);
if (routes.length > 0) {
this.$store.commit('SET_SIDEBAR_ROUTERS', routes);
}
},
ishttp(url) {
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1;
}
},
}
};
</script>
@ -164,7 +153,8 @@ export default {
margin: 0 10px !important;
}
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active,
.el-menu--horizontal > .el-submenu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133;
}

@ -1,11 +1,6 @@
<template>
<div v-loading="loading" :style="'height:' + height">
<iframe
:src="src"
frameborder="no"
style="width: 100%; height: 100%"
scrolling="auto"
/>
<iframe :src="src" frameborder="no" style="width: 100%; height: 100%" scrolling="auto" />
</div>
</template>
<script>
@ -14,11 +9,11 @@ export default {
src: {
type: String,
required: true
},
}
},
data() {
return {
height: document.documentElement.clientHeight - 94.5 + "px;",
height: document.documentElement.clientHeight - 94.5 + 'px;',
loading: true,
url: this.src
};
@ -29,7 +24,7 @@ export default {
}, 300);
const that = this;
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 94.5 + "px;";
that.height = document.documentElement.clientHeight - 94.5 + 'px;';
};
}
};

@ -1,8 +1,8 @@
import { throttleTime } from "@/global/global";
import { throttleTime } from '@/global/global';
export default {
inserted: function (el, binding) {
el.addEventListener("click", () => {
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true;
@ -11,5 +11,5 @@ export default {
}, binding.value || throttleTime);
}
});
},
}
};

@ -1,12 +1,12 @@
/**
* v-dialogDrag 弹窗拖拽
* Copyright (c) 2019 ruoyi
*/
* v-dialogDrag 弹窗拖拽
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el, binding, vnode, oldVnode) {
const value = binding.value
if (value == false) return
const value = binding.value;
if (!value) return;
// 获取拖拽内容头部
const dialogHeaderEl = el.querySelector('.el-dialog__header');
const dragDom = el.querySelector('.el-dialog');
@ -38,7 +38,7 @@ export default {
} else {
styL = +sty.left.replace(/\px/g, '');
styT = +sty.top.replace(/\px/g, '');
};
}
// 鼠标拖拽事件
document.onmousemove = function (e) {
@ -46,19 +46,18 @@ export default {
const l = e.clientX - disX;
const t = e.clientY - disY;
let finallyL = l + styL
let finallyT = t + styT
const finallyL = l + styL;
const finallyT = t + styT;
// 移动当前元素
dragDom.style.left = `${finallyL}px`;
dragDom.style.top = `${finallyT}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
};
}
};
};

@ -1,34 +1,38 @@
/**
* v-dialogDragWidth 可拖动弹窗高度右下角
* Copyright (c) 2019 ruoyi
*/
* v-dialogDragWidth 可拖动弹窗高度右下角
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
lineEl.addEventListener('mousedown',
function(e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
const disY = e.clientY - el.offsetTop;
// 当前宽度 高度
const curWidth = dragDom.offsetWidth;
const curHeight = dragDom.offsetHeight;
document.onmousemove = function(e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const xl = e.clientX - disX;
const yl = e.clientY - disY
dragDom.style.width = `${curWidth + xl}px`;
dragDom.style.height = `${curHeight + yl}px`;
};
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
}
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style =
'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
lineEl.addEventListener(
'mousedown',
function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
const disY = e.clientY - el.offsetTop;
// 当前宽度 高度
const curWidth = dragDom.offsetWidth;
const curHeight = dragDom.offsetHeight;
document.onmousemove = function (e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const xl = e.clientX - disX;
const yl = e.clientY - disY;
dragDom.style.width = `${curWidth + xl}px`;
dragDom.style.height = `${curHeight + yl}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
},
false
);
dragDom.appendChild(lineEl);
}
};

@ -1,30 +1,34 @@
/**
* v-dialogDragWidth 可拖动弹窗宽度右侧边
* Copyright (c) 2019 ruoyi
*/
* v-dialogDragWidth 可拖动弹窗宽度右侧边
* Copyright (c) 2019 ruoyi
*/
export default {
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
lineEl.addEventListener('mousedown',
function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
// 当前宽度
const curWidth = dragDom.offsetWidth;
document.onmousemove = function (e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const l = e.clientX - disX;
dragDom.style.width = `${curWidth + l}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}, false);
dragDom.appendChild(lineEl);
}
}
bind(el) {
const dragDom = el.querySelector('.el-dialog');
const lineEl = document.createElement('div');
lineEl.style =
'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
lineEl.addEventListener(
'mousedown',
function (e) {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - el.offsetLeft;
// 当前宽度
const curWidth = dragDom.offsetWidth;
document.onmousemove = function (e) {
e.preventDefault(); // 移动时禁用默认事件
// 通过事件委托,计算移动的距离
const l = e.clientX - disX;
dragDom.style.width = `${curWidth + l}px`;
};
document.onmouseup = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
},
false
);
dragDom.appendChild(lineEl);
}
};

@ -1,28 +1,28 @@
import hasRole from "./permission/hasRole";
import hasPermi from "./permission/hasPermi";
import dialogDrag from "./dialog/drag";
import dialogDragWidth from "./dialog/dragWidth";
import dialogDragHeight from "./dialog/dragHeight";
import clipboard from "./module/clipboard";
import phone from "./input/phone";
import trim from "./input/trim";
import throttle from "./click/throttle";
import hasRole from './permission/hasRole';
import hasPermi from './permission/hasPermi';
import dialogDrag from './dialog/drag';
import dialogDragWidth from './dialog/dragWidth';
import dialogDragHeight from './dialog/dragHeight';
import clipboard from './module/clipboard';
import phone from './input/phone';
import trim from './input/trim';
import throttle from './click/throttle';
const install = function (Vue) {
Vue.directive("hasRole", hasRole);
Vue.directive("hasPermi", hasPermi);
Vue.directive("clipboard", clipboard);
Vue.directive("dialogDrag", dialogDrag);
Vue.directive("dialogDragWidth", dialogDragWidth);
Vue.directive("dialogDragHeight", dialogDragHeight);
Vue.directive("phone", phone);
Vue.directive("jtrim", trim); // 禁止输入空格
Vue.directive("jclick", throttle); // 节流只支持Button按钮
Vue.directive('hasRole', hasRole);
Vue.directive('hasPermi', hasPermi);
Vue.directive('clipboard', clipboard);
Vue.directive('dialogDrag', dialogDrag);
Vue.directive('dialogDragWidth', dialogDragWidth);
Vue.directive('dialogDragHeight', dialogDragHeight);
Vue.directive('phone', phone);
Vue.directive('jtrim', trim); // 禁止输入空格
Vue.directive('jclick', throttle); // 节流只支持Button按钮
};
if (window.Vue) {
window["hasRole"] = hasRole;
window["hasPermi"] = hasPermi;
window['hasRole'] = hasRole;
window['hasPermi'] = hasPermi;
Vue.use(install); // eslint-disable-line
}

@ -1,3 +1,4 @@
/* eslint-disable indent */
/*
* @Author: riverQiu
* @Date: 2022-11-04
@ -9,25 +10,27 @@
export default {
inserted(el, bind, vnode, prevVnode) {
const input =
el.nodeName.toLowerCase() === "input"
el.nodeName.toLowerCase() === 'input'
? el
: el.getElementsByTagName("input")[0] ? el.getElementsByTagName("input")[0] : el.getElementsByTagName("textarea")[0];
: el.getElementsByTagName('input')[0]
? el.getElementsByTagName('input')[0]
: el.getElementsByTagName('textarea')[0];
// 改变值过后,需要主动触发input时间,组件绑定的值才会改变
let triggerBySelf = false;
if (input) {
input.addEventListener("input", () => {
input.addEventListener('input', () => {
if (triggerBySelf) {
triggerBySelf = false;
return;
}
let val = input.value.replace(/[ ]/g, "");
if (val === "") {
input.value = "";
const val = input.value.replace(/[ ]/g, '');
if (val === '') {
input.value = '';
return;
}
try {
// 改变值过后,需要主动触发input时间,组件绑定的值才会改变
const ev = new Event("input", { bubbles: true });
const ev = new Event('input', { bubbles: true });
input.value = val;
triggerBySelf = true;
input.dispatchEvent(ev);
@ -37,5 +40,5 @@ export default {
}
});
}
},
}
};

@ -1,9 +1,9 @@
/**
* v-clipboard 文字复制剪贴
* Copyright (c) 2021 ruoyi
*/
* v-clipboard 文字复制剪贴
* Copyright (c) 2021 ruoyi
*/
import Clipboard from 'clipboard'
import Clipboard from 'clipboard';
export default {
bind(el, binding, vnode) {
switch (binding.arg) {
@ -16,13 +16,13 @@ export default {
default: {
const clipboard = new Clipboard(el, {
text: () => binding.value,
action: () => binding.arg === 'cut' ? 'cut' : 'copy'
action: () => (binding.arg === 'cut' ? 'cut' : 'copy')
});
clipboard.on('success', e => {
clipboard.on('success', (e) => {
const callback = el._vClipBoard_success;
callback && callback(e);
});
clipboard.on('error', e => {
clipboard.on('error', (e) => {
const callback = el._vClipBoard_error;
callback && callback(e);
});
@ -36,12 +36,14 @@ export default {
} else if (binding.arg === 'error') {
el._vClipBoard_error = binding.value;
} else {
el._vClipBoard.text = function () { return binding.value; };
el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy';
el._vClipBoard.text = function () {
return binding.value;
};
el._vClipBoard.action = () => (binding.arg === 'cut' ? 'cut' : 'copy');
}
},
unbind(el, binding) {
if (!el._vClipboard) return
if (!el._vClipboard) return;
if (binding.arg === 'success') {
delete el._vClipBoard_success;
} else if (binding.arg === 'error') {
@ -51,4 +53,4 @@ export default {
delete el._vClipBoard;
}
}
}
};

@ -1,28 +1,28 @@
/**
/**
* v-hasPermi 操作权限处理
* Copyright (c) 2019 ruoyi
*/
import store from '@/store'
import store from '@/store';
export default {
inserted(el, binding, vnode) {
const { value } = binding
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
const { value } = binding;
const all_permission = '*:*:*';
const permissions = store.getters && store.getters.permissions;
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const permissionFlag = value;
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
const hasPermissions = permissions.some((permission) => {
return all_permission === permission || permissionFlag.includes(permission);
});
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
el.parentNode && el.parentNode.removeChild(el);
}
} else {
throw new Error(`请设置操作权限标签值`)
throw new Error(`请设置操作权限标签值`);
}
}
}
};

@ -1,28 +1,28 @@
/**
/**
* v-hasRole 角色权限处理
* Copyright (c) 2019 ruoyi
*/
import store from '@/store'
import store from '@/store';
export default {
inserted(el, binding, vnode) {
const { value } = binding
const super_admin = "admin";
const roles = store.getters && store.getters.roles
const { value } = binding;
const super_admin = 'admin';
const roles = store.getters && store.getters.roles;
if (value && value instanceof Array && value.length > 0) {
const roleFlag = value
const roleFlag = value;
const hasRole = roles.some(role => {
return super_admin === role || roleFlag.includes(role)
})
const hasRole = roles.some((role) => {
return super_admin === role || roleFlag.includes(role);
});
if (!hasRole) {
el.parentNode && el.parentNode.removeChild(el)
el.parentNode && el.parentNode.removeChild(el);
}
} else {
throw new Error(`请设置角色权限标签值"`)
throw new Error(`请设置角色权限标签值"`);
}
}
}
};

@ -1,28 +1,28 @@
import Vue from "vue";
import Vue from 'vue';
// 分页组件
import Pagination from "@/components/Pagination";
import Pagination from '@/components/Pagination';
// 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar";
import RightToolbar from '@/components/RightToolbar';
// 富文本组件
import Editor from "@/components/Editor";
import Editor from '@/components/Editor';
// 文件上传组件
import FileUpload from "@/components/FileUpload";
import FileUpload from '@/components/FileUpload';
// 图片上传组件
import ImageUpload from "@/components/ImageUpload";
import ImageUpload from '@/components/ImageUpload';
// 图片预览组件
import ImagePreview from "@/components/ImagePreview";
import ImagePreview from '@/components/ImagePreview';
// 字典标签组件
import DictTag from "@/components/DictTag";
import DictTag from '@/components/DictTag';
// 字典数据组件
import DictData from '@/components/DictData'
import DictData from '@/components/DictData';
// 全局组件挂载
Vue.component("DictTag", DictTag);
Vue.component("Pagination", Pagination);
Vue.component("RightToolbar", RightToolbar);
Vue.component("Editor", Editor);
Vue.component("FileUpload", FileUpload);
Vue.component("ImageUpload", ImageUpload);
Vue.component("ImagePreview", ImagePreview);
Vue.component('DictTag', DictTag);
Vue.component('Pagination', Pagination);
Vue.component('RightToolbar', RightToolbar);
Vue.component('Editor', Editor);
Vue.component('FileUpload', FileUpload);
Vue.component('ImageUpload', ImageUpload);
Vue.component('ImagePreview', ImagePreview);
DictData.install()
DictData.install();

@ -1,8 +1,9 @@
import Vue from "vue";
import Vue from 'vue';
import { parseTime, resetForm, handleTree } from "@/utils/ruoyi";
import { deepClone } from "@/utils/index";
import { download } from "@/utils/request";
import { parseTime, resetForm, handleTree, addDateRange } from '@/utils/ruoyi';
import { deepClone } from '@/utils/index';
import { download } from '@/utils/request';
import { getConfigKey } from '@/api/system/config';
// 全局方法挂载
Vue.prototype.parseTime = parseTime;
@ -10,3 +11,5 @@ Vue.prototype.resetForm = resetForm;
Vue.prototype.download = download;
Vue.prototype.handleTree = handleTree;
Vue.prototype.deepClone = deepClone;
Vue.prototype.addDateRange = addDateRange;
Vue.prototype.getConfigKey = getConfigKey;

@ -13,5 +13,5 @@ Vue.prototype.$global = {
clientHeight: document.body.clientHeight,
defaultPageSize: 10,
successCode: successCode,
STORAGE_KEY: 'jslx'
STORAGE_KEY: 'duima'
};

@ -1,4 +1,4 @@
import "./global";
import "./element";
import "./components";
import "./func";
import './global';
import './element';
import './components';
import './func';

@ -1,24 +1,18 @@
<template>
<transition-group name="fade-transform" mode="out-in">
<inner-link
v-for="(item, index) in iframeViews"
:key="item.path"
:iframeId="'iframe' + index"
v-show="$route.path === item.path"
:src="item.meta.link"
></inner-link>
<inner-link v-for="(item, index) in iframeViews" v-show="$route.path === item.path" :key="item.path" :iframe-id="'iframe' + index" :src="item.meta.link" />
</transition-group>
</template>
<script>
import InnerLink from "../InnerLink/index"
import InnerLink from '../InnerLink/index';
export default {
components: { InnerLink },
computed: {
iframeViews() {
return this.$store.state.tagsView.iframeViews
return this.$store.state.tagsView.iframeViews;
}
}
}
};
</script>

@ -1,11 +1,6 @@
<template>
<div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
<iframe
:id="iframeId"
style="width: 100%; height: 100%"
:src="src"
frameborder="no"
></iframe>
<div v-loading="loading" :style="'height:' + height" element-loading-text="正在加载页面,请稍候!">
<iframe :id="iframeId" style="width: 100%; height: 100%" :src="src" frameborder="no" />
</div>
</template>
@ -14,26 +9,27 @@ export default {
props: {
src: {
type: String,
default: "/"
default: '/'
},
iframeId: {
type: String
type: String,
default: ''
}
},
data() {
return {
loading: false,
height: document.documentElement.clientHeight - 94.5 + "px;"
height: document.documentElement.clientHeight - 94.5 + 'px;'
};
},
mounted() {
var _this = this;
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
const iframeId = ('#' + this.iframeId).replace(/\//g, '\\/');
const iframe = document.querySelector(iframeId);
// iframeloading
if (iframe.attachEvent) {
this.loading = true;
iframe.attachEvent("onload", function () {
iframe.attachEvent('onload', function () {
_this.loading = false;
});
} else {

@ -8,7 +8,7 @@
<div class="right-menu">
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<img :src="avatar" class="user-avatar" />
<img :src="avatar" class="user-avatar">
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">

@ -12,7 +12,7 @@
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
<i aria-label="图标: check" class="anticon anticon-check">
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
</svg>
</i>
</div>
@ -22,7 +22,7 @@
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
<i aria-label="图标: check" class="anticon anticon-check">
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class="">
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/>
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
</svg>
</i>
</div>
@ -35,10 +35,10 @@
</div>
</div>
<el-divider/>
<el-divider />
<h3 class="drawer-title">系统布局配置</h3>
<div class="drawer-item">
<span>开启 TopNav</span>
<el-switch v-model="topNav" class="drawer-switch" />
@ -64,7 +64,7 @@
<el-switch v-model="dynamicTitle" class="drawer-switch" />
</div>
<el-divider/>
<el-divider />
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
<el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button>
@ -74,7 +74,7 @@
</template>
<script>
import ThemePicker from '@/components/ThemePicker'
import ThemePicker from '@/components/ThemePicker';
export default {
components: { ThemePicker },
@ -87,88 +87,88 @@ export default {
computed: {
visible: {
get() {
return this.$store.state.settings.showSettings
return this.$store.state.settings.showSettings;
}
},
fixedHeader: {
get() {
return this.$store.state.settings.fixedHeader
return this.$store.state.settings.fixedHeader;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'fixedHeader',
value: val
})
});
}
},
topNav: {
get() {
return this.$store.state.settings.topNav
return this.$store.state.settings.topNav;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'topNav',
value: val
})
});
if (!val) {
this.$store.dispatch('app/toggleSideBarHide', false);
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
this.$store.commit('SET_SIDEBAR_ROUTERS', this.$store.state.permission.defaultRoutes);
}
}
},
tagsView: {
get() {
return this.$store.state.settings.tagsView
return this.$store.state.settings.tagsView;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'tagsView',
value: val
})
});
}
},
sidebarLogo: {
get() {
return this.$store.state.settings.sidebarLogo
return this.$store.state.settings.sidebarLogo;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'sidebarLogo',
value: val
})
});
}
},
dynamicTitle: {
get() {
return this.$store.state.settings.dynamicTitle
return this.$store.state.settings.dynamicTitle;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'dynamicTitle',
value: val
})
});
}
},
}
},
methods: {
themeChange(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'theme',
value: val
})
});
this.theme = val;
},
handleTheme(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'sideTheme',
value: val
})
});
this.sideTheme = val;
},
saveSetting() {
this.$modal.loading("正在保存到本地,请稍候...");
this.$modal.loading('正在保存到本地,请稍候...');
this.$cache.local.set(
"layout-setting",
'layout-setting',
`{
"topNav":${this.topNav},
"tagsView":${this.tagsView},
@ -179,82 +179,82 @@ export default {
"theme":"${this.theme}"
}`
);
setTimeout(this.$modal.closeLoading(), 1000)
setTimeout(this.$modal.closeLoading(), 1000);
},
resetSetting() {
this.$modal.loading("正在清除设置缓存并刷新,请稍候...");
this.$cache.local.remove("layout-setting")
setTimeout("window.location.reload()", 1000)
this.$modal.loading('正在清除设置缓存并刷新,请稍候...');
this.$cache.local.remove('layout-setting');
// setTimeout('window.location.reload()', 1000);
}
}
}
};
</script>
<style lang="scss" scoped>
.setting-drawer-content {
.setting-drawer-title {
margin-bottom: 12px;
color: rgba(0, 0, 0, .85);
font-size: 14px;
line-height: 22px;
font-weight: bold;
}
.setting-drawer-content {
.setting-drawer-title {
margin-bottom: 12px;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
line-height: 22px;
font-weight: bold;
}
.setting-drawer-block-checbox {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
margin-bottom: 20px;
.setting-drawer-block-checbox {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
margin-bottom: 20px;
.setting-drawer-block-checbox-item {
position: relative;
margin-right: 16px;
border-radius: 2px;
cursor: pointer;
.setting-drawer-block-checbox-item {
position: relative;
margin-right: 16px;
border-radius: 2px;
cursor: pointer;
img {
width: 48px;
height: 48px;
}
img {
width: 48px;
height: 48px;
}
.setting-drawer-block-checbox-selectIcon {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
padding-top: 15px;
padding-left: 24px;
color: #1890ff;
font-weight: 700;
font-size: 14px;
}
.setting-drawer-block-checbox-selectIcon {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
padding-top: 15px;
padding-left: 24px;
color: #1890ff;
font-weight: 700;
font-size: 14px;
}
}
}
}
.drawer-container {
padding: 20px;
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
.drawer-container {
padding: 20px;
font-size: 14px;
line-height: 1.5;
word-wrap: break-word;
.drawer-title {
margin-bottom: 12px;
color: rgba(0, 0, 0, .85);
font-size: 14px;
line-height: 22px;
}
.drawer-title {
margin-bottom: 12px;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
line-height: 22px;
}
.drawer-item {
color: rgba(0, 0, 0, .65);
font-size: 14px;
padding: 12px 0;
}
.drawer-item {
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
padding: 12px 0;
}
.drawer-switch {
float: right
}
.drawer-switch {
float: right;
}
}
</style>

@ -1,25 +1,25 @@
export default {
computed: {
device() {
return this.$store.state.app.device
return this.$store.state.app.device;
}
},
mounted() {
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
this.fixBugIniOS()
this.fixBugIniOS();
},
methods: {
fixBugIniOS() {
const $subMenu = this.$refs.subMenu
const $subMenu = this.$refs.subMenu;
if ($subMenu) {
const handleMouseleave = $subMenu.handleMouseleave
const handleMouseleave = $subMenu.handleMouseleave;
$subMenu.handleMouseleave = (e) => {
if (this.device === 'mobile') {
return
return;
}
handleMouseleave(e)
}
handleMouseleave(e);
};
}
}
}
}
};

@ -1,3 +1,4 @@
<!-- eslint-disable jsx-quotes -->
<script>
export default {
name: 'MenuItem',
@ -13,21 +14,25 @@ export default {
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
const { icon, title } = context.props;
const vnodes = [];
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
vnodes.push(<svg-icon icon-class={icon} />);
}
if (title) {
if (title.length > 5) {
vnodes.push(<span slot='title' title={(title)}>{(title)}</span>)
vnodes.push(
<span slot="title" title={title}>
{title}
</span>
);
} else {
vnodes.push(<span slot='title'>{(title)}</span>)
vnodes.push(<span slot="title">{title}</span>);
}
}
return vnodes
return vnodes;
}
}
};
</script>

@ -5,7 +5,7 @@
</template>
<script>
import { isExternal } from '@/utils/validate'
import { isExternal } from '@/utils/validate';
export default {
props: {
@ -16,13 +16,13 @@ export default {
},
computed: {
isExternal() {
return isExternal(this.to)
return isExternal(this.to);
},
type() {
if (this.isExternal) {
return 'a'
return 'a';
}
return 'router-link'
return 'router-link';
}
},
methods: {
@ -32,12 +32,12 @@ export default {
href: to,
target: '_blank',
rel: 'noopener'
}
};
}
return {
to: to
}
};
}
}
}
};
</script>

@ -12,24 +12,17 @@
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
<sidebar-item v-for="child in item.children" :key="child.path" :is-nest="true" :item="child" :base-path="resolvePath(child.path)" class="nest-menu" />
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
import path from 'path';
import { isExternal } from '@/utils/validate';
import Item from './Item';
import AppLink from './Link';
import FixiOSBug from './FixiOSBug';
export default {
name: 'SidebarItem',
@ -51,50 +44,50 @@ export default {
}
},
data() {
this.onlyOneChild = null
return {}
this.onlyOneChild = null;
return {};
},
methods: {
hasOneShowingChild(children = [], parent) {
if (!children) {
children = [];
}
const showingChildren = children.filter(item => {
const showingChildren = children.filter((item) => {
if (item.hidden) {
return false
return false;
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
this.onlyOneChild = item;
return true;
}
})
});
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
return true;
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
this.onlyOneChild = { ...parent, path: '', noShowingChildren: true };
return true;
}
return false
return false;
},
resolvePath(routePath, routeQuery) {
if (isExternal(routePath)) {
return routePath
return routePath;
}
if (isExternal(this.basePath)) {
return this.basePath
return this.basePath;
}
if (routeQuery) {
let query = JSON.parse(routeQuery);
return { path: path.resolve(this.basePath, routePath), query: query }
const query = JSON.parse(routeQuery);
return { path: path.resolve(this.basePath, routePath), query: query };
}
return path.resolve(this.basePath, routePath)
return path.resolve(this.basePath, routePath);
}
}
}
};
</script>

@ -1,57 +1,43 @@
<template>
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
:text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
:unique-opened="true"
:active-text-color="settings.theme"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
v-for="(route, index) in sidebarRouters"
:key="route.path + index"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
<div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper">
<el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground" :text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor" :unique-opened="true" :active-text-color="settings.theme" :collapse-transition="false" mode="vertical">
<sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import Logo from "./Logo";
import SidebarItem from "./SidebarItem";
import variables from "@/assets/styles/variables.scss";
import { mapGetters, mapState } from 'vuex';
import Logo from './Logo';
import SidebarItem from './SidebarItem';
import variables from '@/assets/styles/variables.scss';
export default {
components: { SidebarItem, Logo },
computed: {
...mapState(["settings"]),
...mapGetters(["sidebarRouters", "sidebar"]),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
}
components: { SidebarItem, Logo },
computed: {
...mapState(['settings']),
...mapGetters(['sidebarRouters', 'sidebar']),
activeMenu() {
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu;
}
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables;
},
isCollapse() {
return !this.sidebar.opened;
}
}
};
</script>

@ -5,75 +5,75 @@
</template>
<script>
const tagAndTagSpacing = 4 // tagAndTagSpacing
const tagAndTagSpacing = 4; // tagAndTagSpacing
export default {
name: 'ScrollPane',
data() {
return {
left: 0
}
};
},
computed: {
scrollWrapper() {
return this.$refs.scrollContainer.$refs.wrap
return this.$refs.scrollContainer.$refs.wrap;
}
},
mounted() {
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true);
},
beforeDestroy() {
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
this.scrollWrapper.removeEventListener('scroll', this.emitScroll);
},
methods: {
handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 40
const $scrollWrapper = this.scrollWrapper
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
const eventDelta = e.wheelDelta || -e.deltaY * 40;
const $scrollWrapper = this.scrollWrapper;
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4;
},
emitScroll() {
this.$emit('scroll')
this.$emit('scroll');
},
moveToTarget(currentTag) {
const $container = this.$refs.scrollContainer.$el
const $containerWidth = $container.offsetWidth
const $scrollWrapper = this.scrollWrapper
const tagList = this.$parent.$refs.tag
const $container = this.$refs.scrollContainer.$el;
const $containerWidth = $container.offsetWidth;
const $scrollWrapper = this.scrollWrapper;
const tagList = this.$parent.$refs.tag;
let firstTag = null
let lastTag = null
let firstTag = null;
let lastTag = null;
// find first tag and last tag
if (tagList.length > 0) {
firstTag = tagList[0]
lastTag = tagList[tagList.length - 1]
firstTag = tagList[0];
lastTag = tagList[tagList.length - 1];
}
if (firstTag === currentTag) {
$scrollWrapper.scrollLeft = 0
$scrollWrapper.scrollLeft = 0;
} else if (lastTag === currentTag) {
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth;
} else {
// find preTag and nextTag
const currentIndex = tagList.findIndex(item => item === currentTag)
const prevTag = tagList[currentIndex - 1]
const nextTag = tagList[currentIndex + 1]
const currentIndex = tagList.findIndex((item) => item === currentTag);
const prevTag = tagList[currentIndex - 1];
const nextTag = tagList[currentIndex + 1];
// the tag's offsetLeft after of nextTag
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing;
// the tag's offsetLeft before of prevTag
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing;
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth;
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft;
}
}
}
}
}
};
</script>
<style lang="scss" scoped>

@ -1,36 +1,25 @@
<template>
<div id="tags-view-container" class="tags-view-container">
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
<router-link
v-for="tag in visitedViews"
ref="tag"
:key="tag.path"
:class="isActive(tag)?'active':''"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
:style="activeStyle(tag)"
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
<router-link v-for="tag in visitedViews" ref="tag" :key="tag.path" :class="isActive(tag)?'active':''" :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" tag="span" class="tags-view-item" :style="activeStyle(tag)" @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" @contextmenu.prevent.native="openMenu(tag,$event)">
{{ tag.title }}
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right" /> 刷新页面</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close" /> 关闭当前</li>
<li @click="closeOthersTags"><i class="el-icon-circle-close" /> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back" /> 关闭左侧</li>
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right" /> 关闭右侧</li>
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close" /> 全部关闭</li>
</ul>
</div>
</template>
<script>
import ScrollPane from './ScrollPane'
import path from 'path'
import ScrollPane from './ScrollPane';
import path from 'path';
export default {
components: { ScrollPane },
@ -41,14 +30,14 @@ export default {
left: 0,
selectedTag: {},
affixTags: []
}
};
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
return this.$store.state.tagsView.visitedViews;
},
routes() {
return this.$store.state.permission.routes
return this.$store.state.permission.routes;
},
theme() {
return this.$store.state.settings.theme;
@ -56,185 +45,185 @@ export default {
},
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
this.addTags();
this.moveToCurrentTag();
},
visible(value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
document.body.addEventListener('click', this.closeMenu);
} else {
document.body.removeEventListener('click', this.closeMenu)
document.body.removeEventListener('click', this.closeMenu);
}
}
},
mounted() {
this.initTags()
this.addTags()
this.initTags();
this.addTags();
},
methods: {
isActive(route) {
return route.path === this.$route.path
return route.path === this.$route.path;
},
activeStyle(tag) {
if (!this.isActive(tag)) return {};
return {
"background-color": this.theme,
"border-color": this.theme
'background-color': this.theme,
'border-color': this.theme
};
},
isAffix(tag) {
return tag.meta && tag.meta.affix
return tag.meta && tag.meta.affix;
},
isFirstView() {
try {
return this.selectedTag.fullPath === this.visitedViews[1].fullPath || this.selectedTag.fullPath === '/index'
return this.selectedTag.fullPath === this.visitedViews[1].fullPath || this.selectedTag.fullPath === '/index';
} catch (err) {
return false
return false;
}
},
isLastView() {
try {
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath;
} catch (err) {
return false
return false;
}
},
filterAffixTags(routes, basePath = '/') {
let tags = []
routes.forEach(route => {
let tags = [];
routes.forEach((route) => {
if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path)
const tagPath = path.resolve(basePath, route.path);
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta }
})
});
}
if (route.children) {
const tempTags = this.filterAffixTags(route.children, route.path)
const tempTags = this.filterAffixTags(route.children, route.path);
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
tags = [...tags, ...tempTags];
}
}
})
return tags
});
return tags;
},
initTags() {
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
const affixTags = (this.affixTags = this.filterAffixTags(this.routes));
for (const tag of affixTags) {
// Must have tag name
if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag)
this.$store.dispatch('tagsView/addVisitedView', tag);
}
}
},
addTags() {
const { name } = this.$route
const { name } = this.$route;
if (name) {
this.$store.dispatch('tagsView/addView', this.$route)
this.$store.dispatch('tagsView/addView', this.$route);
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/addIframeView', this.$route)
this.$store.dispatch('tagsView/addIframeView', this.$route);
}
}
return false
return false;
},
moveToCurrentTag() {
const tags = this.$refs.tag
const tags = this.$refs.tag;
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag)
this.$refs.scrollPane.moveToTarget(tag);
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
this.$store.dispatch('tagsView/updateVisitedView', this.$route);
}
break
break;
}
}
})
});
},
refreshSelectedTag(view) {
this.$tab.refreshPage(view);
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/delIframeView', this.$route)
this.$store.dispatch('tagsView/delIframeView', this.$route);
}
},
closeSelectedTag(view) {
this.$tab.closePage(view).then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
this.toLastView(visitedViews, view);
}
})
});
},
closeRightTags() {
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
this.$tab.closeRightPage(this.selectedTag).then((visitedViews) => {
if (!visitedViews.find((i) => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews);
}
})
});
},
closeLeftTags() {
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
this.$tab.closeLeftPage(this.selectedTag).then((visitedViews) => {
if (!visitedViews.find((i) => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews);
}
})
});
},
closeOthersTags() {
this.$router.push(this.selectedTag).catch(()=>{});
this.$router.push(this.selectedTag).catch(() => {});
this.$tab.closeOtherPage(this.selectedTag).then(() => {
this.moveToCurrentTag()
})
this.moveToCurrentTag();
});
},
closeAllTags(view) {
this.$tab.closeAllPage().then(({ visitedViews }) => {
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
return
if (this.affixTags.some((tag) => tag.path === this.$route.path)) {
return;
}
this.toLastView(visitedViews, view)
})
this.toLastView(visitedViews, view);
});
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
const latestView = visitedViews.slice(-1)[0];
if (latestView) {
this.$router.push(latestView.fullPath)
this.$router.push(latestView.fullPath);
} else {
// now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs.
if (view.name === 'Dashboard') {
// to reload home page
this.$router.replace({ path: '/redirect' + view.fullPath })
this.$router.replace({ path: '/redirect' + view.fullPath });
} else {
this.$router.push('/')
this.$router.push('/');
}
}
},
openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
const offsetWidth = this.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const left = e.clientX - offsetLeft + 15 // 15: margin right
const menuMinWidth = 105;
const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
const offsetWidth = this.$el.offsetWidth; // container width
const maxLeft = offsetWidth - menuMinWidth; // left boundary
const left = e.clientX - offsetLeft + 15; // 15: margin right
if (left > maxLeft) {
this.left = maxLeft
this.left = maxLeft;
} else {
this.left = left
this.left = left;
}
this.top = e.clientY
this.visible = true
this.selectedTag = tag
this.top = e.clientY;
this.visible = true;
this.selectedTag = tag;
},
closeMenu() {
this.visible = false
this.visible = false;
},
handleScroll() {
this.closeMenu()
this.closeMenu();
}
}
}
};
</script>
<style lang="scss" scoped>
@ -243,7 +232,7 @@ export default {
width: 100%;
background: #fff;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
@ -292,7 +281,7 @@ export default {
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
li {
margin: 0;
padding: 7px 16px;
@ -315,10 +304,10 @@ export default {
vertical-align: 2px;
border-radius: 50%;
text-align: center;
transition: all .3s cubic-bezier(.645, .045, .355, 1);
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
transform-origin: 100% 50%;
&:before {
transform: scale(.6);
transform: scale(0.6);
display: inline-block;
vertical-align: -3px;
}

@ -1,5 +1,5 @@
export { default as AppMain } from './AppMain'
export { default as Navbar } from './Navbar'
export { default as Settings } from './Settings'
export { default as Sidebar } from './Sidebar/index.vue'
export { default as TagsView } from './TagsView/index.vue'
export { default as AppMain } from './AppMain';
export { default as Navbar } from './Navbar';
export { default as Settings } from './Settings';
export { default as Sidebar } from './Sidebar/index.vue';
export { default as TagsView } from './TagsView/index.vue';

@ -1,6 +1,6 @@
<template>
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
<div :class="{'fixed-header':fixedHeader}">
@ -16,11 +16,11 @@
</template>
<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import variables from '@/assets/styles/variables.scss'
import RightPanel from '@/components/RightPanel';
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components';
import ResizeMixin from './mixin/ResizeHandler';
import { mapState } from 'vuex';
import variables from '@/assets/styles/variables.scss';
export default {
name: 'Layout',
@ -35,12 +35,12 @@ export default {
mixins: [ResizeMixin],
computed: {
...mapState({
theme: state => state.settings.theme,
sideTheme: state => state.settings.sideTheme,
sidebar: state => state.app.sidebar,
device: state => state.app.device,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader
theme: (state) => state.settings.theme,
sideTheme: (state) => state.settings.sideTheme,
sidebar: (state) => state.app.sidebar,
device: (state) => state.app.device,
needTagsView: (state) => state.settings.tagsView,
fixedHeader: (state) => state.settings.fixedHeader
}),
classObj() {
return {
@ -48,7 +48,7 @@ export default {
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
};
},
variables() {
return variables;
@ -56,56 +56,56 @@ export default {
},
methods: {
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false });
}
}
}
};
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/mixin.scss";
@import "~@/assets/styles/variables.scss";
@import '~@/assets/styles/mixin.scss';
@import '~@/assets/styles/variables.scss';
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
&.mobile.openSidebar {
position: fixed;
top: 0;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.fixed-header {
&.mobile.openSidebar {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$base-sidebar-width});
transition: width 0.28s;
}
}
.hideSidebar .fixed-header {
width: calc(100% - 54px);
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.sidebarHide .fixed-header {
width: 100%;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$base-sidebar-width});
transition: width 0.28s;
}
.mobile .fixed-header {
width: 100%;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px);
}
.sidebarHide .fixed-header {
width: 100%;
}
.mobile .fixed-header {
width: 100%;
}
</style>

@ -1,45 +1,45 @@
import store from '@/store'
import store from '@/store';
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
const { body } = document;
const WIDTH = 992; // refer to Bootstrap's responsive design
export default {
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('app/closeSideBar', { withoutAnimation: false })
store.dispatch('app/closeSideBar', { withoutAnimation: false });
}
}
},
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
window.addEventListener('resize', this.$_resizeHandler);
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
window.removeEventListener('resize', this.$_resizeHandler);
},
mounted() {
const isMobile = this.$_isMobile()
const isMobile = this.$_isMobile();
if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
store.dispatch('app/toggleDevice', 'mobile');
store.dispatch('app/closeSideBar', { withoutAnimation: true });
}
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
const rect = body.getBoundingClientRect();
return rect.width - 1 < WIDTH;
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
const isMobile = this.$_isMobile();
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop');
if (isMobile) {
store.dispatch('app/closeSideBar', { withoutAnimation: true })
store.dispatch('app/closeSideBar', { withoutAnimation: true });
}
}
}
}
}
};

@ -19,38 +19,9 @@ import './global';
import './assets/icons'; // icon
import './permission'; // permission control
import {
download
} from '@/utils/request'
import {
getDicts
} from "@/api/system/dict/data";
import {
getConfigKey
} from "@/api/system/config";
import {
parseTime,
resetForm,
addDateRange,
selectDictLabel,
selectDictLabels,
handleTree
} from "@/utils/ruoyi";
// 头部标签组件
import VueMeta from 'vue-meta';
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
import Mixin from './mixins/Mixin';
Vue.mixin(Mixin);

@ -1,69 +1,69 @@
const sessionCache = {
set (key, value) {
set(key, value) {
if (!sessionStorage) {
return
return;
}
if (key != null && value != null) {
sessionStorage.setItem(key, value)
sessionStorage.setItem(key, value);
}
},
get (key) {
get(key) {
if (!sessionStorage) {
return null
return null;
}
if (key == null) {
return null
return null;
}
return sessionStorage.getItem(key)
return sessionStorage.getItem(key);
},
setJSON (key, jsonValue) {
setJSON(key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
this.set(key, JSON.stringify(jsonValue));
}
},
getJSON (key) {
const value = this.get(key)
getJSON(key) {
const value = this.get(key);
if (value != null) {
return JSON.parse(value)
return JSON.parse(value);
}
},
remove (key) {
remove(key) {
sessionStorage.removeItem(key);
}
}
};
const localCache = {
set (key, value) {
set(key, value) {
if (!localStorage) {
return
return;
}
if (key != null && value != null) {
localStorage.setItem(key, value)
localStorage.setItem(key, value);
}
},
get (key) {
get(key) {
if (!localStorage) {
return null
return null;
}
if (key == null) {
return null
return null;
}
return localStorage.getItem(key)
return localStorage.getItem(key);
},
setJSON (key, jsonValue) {
setJSON(key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
this.set(key, JSON.stringify(jsonValue));
}
},
getJSON (key) {
const value = this.get(key)
getJSON(key) {
const value = this.get(key);
if (value != null) {
return JSON.parse(value)
return JSON.parse(value);
}
},
remove (key) {
remove(key) {
localStorage.removeItem(key);
}
}
};
export default {
/**
@ -74,4 +74,4 @@ export default {
* 本地缓存
*/
local: localCache
}
};

@ -1,43 +1,43 @@
import { Message, MessageBox, Notification, Loading } from 'element-ui'
import { Message, MessageBox, Notification, Loading } from 'element-ui';
let loadingInstance;
export default {
// 消息提示
msg(content) {
Message.info(content)
Message.info(content);
},
// 错误消息
msgError(content) {
Message.error(content)
Message.error(content);
},
// 成功消息
msgSuccess(content) {
Message.success(content)
Message.success(content);
},
// 警告消息
msgWarning(content) {
Message.warning(content)
Message.warning(content);
},
// 弹出提示
alert(content) {
MessageBox.alert(content, "系统提示")
MessageBox.alert(content, '系统提示');
},
// 错误提示
alertError(content) {
MessageBox.alert(content, "系统提示", { type: 'error' })
MessageBox.alert(content, '系统提示', { type: 'error' });
},
// 成功提示
alertSuccess(content) {
MessageBox.alert(content, "系统提示", { type: 'success' })
MessageBox.alert(content, '系统提示', { type: 'success' });
},
// 警告提示
alertWarning(content) {
MessageBox.alert(content, "系统提示", { type: 'warning' })
MessageBox.alert(content, '系统提示', { type: 'warning' });
},
// 通知提示
notify(content) {
Notification.info(content)
Notification.info(content);
},
// 错误通知
notifyError(content) {
@ -45,39 +45,39 @@ export default {
},
// 成功通知
notifySuccess(content) {
Notification.success(content)
Notification.success(content);
},
// 警告通知
notifyWarning(content) {
Notification.warning(content)
Notification.warning(content);
},
// 确认窗体
confirm(content) {
return MessageBox.confirm(content, "系统提示", {
return MessageBox.confirm(content, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
type: 'warning'
});
},
// 提交内容
prompt(content) {
return MessageBox.prompt(content, "系统提示", {
return MessageBox.prompt(content, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
type: 'warning'
});
},
// 打开遮罩层
loading(content) {
loadingInstance = Loading.service({
lock: true,
text: content,
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
},
// 关闭遮罩层
closeLoading() {
loadingInstance.close();
}
}
};

@ -1,4 +1,4 @@
import store from '@/store'
import store from '@/store';
import router from '@/router';
export default {
@ -15,16 +15,16 @@ export default {
});
}
return store.dispatch('tagsView/delCachedView', obj).then(() => {
const { path, query } = obj
const { path, query } = obj;
router.replace({
path: '/redirect' + path,
query: query
})
})
});
});
},
// 关闭当前tab页签,打开新页签
closeOpenPage(obj) {
store.dispatch("tagsView/delView", router.currentRoute);
store.dispatch('tagsView/delView', router.currentRoute);
if (obj !== undefined) {
return router.push(obj);
}
@ -56,7 +56,12 @@ export default {
},
// 添加tab页签
openPage(title, url, params) {
var obj = { path: url, meta: { title: title } }
var obj = {
path: url,
meta: {
title: title
}
};
store.dispatch('tagsView/addView', obj);
return router.push({ path: url, query: params });
},
@ -64,4 +69,4 @@ export default {
updatePage(obj) {
return store.dispatch('tagsView/updateVisitedView', obj);
}
}
};

@ -29,14 +29,17 @@ import Layout from '@/layout';
*/
// 公共路由
export const constantRoutes = [{
export const constantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect')
}]
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect')
}
]
},
{
path: '/login',
@ -62,16 +65,18 @@ export const constantRoutes = [{
path: '',
component: Layout,
redirect: 'index',
children: [{
path: 'index',
component: () => import('@/views/index'),
name: 'Index',
meta: {
title: '首页',
icon: 'dashboard',
affix: true
children: [
{
path: 'index',
component: () => import('@/views/index'),
name: 'Index',
meta: {
title: '首页',
icon: 'dashboard',
affix: true
}
}
}]
]
},
// {
// path: '/demo',
@ -106,78 +111,89 @@ export const constantRoutes = [{
component: Layout,
hidden: true,
redirect: 'noredirect',
children: [{
path: 'profile',
component: () => import('@/views/system/user/profile/index'),
name: 'Profile',
meta: {
title: '个人中心',
icon: 'user'
children: [
{
path: 'profile',
component: () => import('@/views/system/user/profile/index'),
name: 'Profile',
meta: {
title: '个人中心',
icon: 'user'
}
}
}]
]
}
];
// 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [{
export const dynamicRoutes = [
{
path: '/system/user-auth',
component: Layout,
hidden: true,
permissions: ['system:user:edit'],
children: [{
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'),
name: 'AuthRole',
meta: {
title: '分配角色',
activeMenu: '/system/user'
children: [
{
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'),
name: 'AuthRole',
meta: {
title: '分配角色',
activeMenu: '/system/user'
}
}
}]
]
},
{
path: '/system/role-auth',
component: Layout,
hidden: true,
permissions: ['system:role:edit'],
children: [{
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'),
name: 'AuthUser',
meta: {
title: '分配用户',
activeMenu: '/system/role'
children: [
{
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'),
name: 'AuthUser',
meta: {
title: '分配用户',
activeMenu: '/system/role'
}
}
}]
]
},
{
path: '/system/dict-data',
component: Layout,
hidden: true,
permissions: ['system:dict:list'],
children: [{
path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data'),
name: 'Data',
meta: {
title: '字典数据',
activeMenu: '/system/dict'
children: [
{
path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data'),
name: 'Data',
meta: {
title: '字典数据',
activeMenu: '/system/dict'
}
}
}]
]
},
{
path: '/monitor/job-log',
component: Layout,
hidden: true,
permissions: ['monitor:job:list'],
children: [{
path: 'index',
component: () => import('@/views/monitor/job/log'),
name: 'JobLog',
meta: {
title: '调度日志',
activeMenu: '/monitor/job'
children: [
{
path: 'index',
component: () => import('@/views/monitor/job/log'),
name: 'JobLog',
meta: {
title: '调度日志',
activeMenu: '/monitor/job'
}
}
}]
]
}
];

@ -41,4 +41,4 @@ module.exports = {
* If you want to also use it in dev, you can pass ['production', 'development']
*/
errorLog: 'production'
}
};

@ -1,4 +1,4 @@
import Cookies from 'js-cookie'
import Cookies from 'js-cookie';
const state = {
sidebar: {
@ -8,59 +8,59 @@ const state = {
},
device: 'desktop',
size: Cookies.get('size') || 'medium'
}
};
const mutations = {
TOGGLE_SIDEBAR: state => {
TOGGLE_SIDEBAR: (state) => {
if (state.sidebar.hide) {
return false;
}
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
state.sidebar.opened = !state.sidebar.opened;
state.sidebar.withoutAnimation = false;
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
Cookies.set('sidebarStatus', 1);
} else {
Cookies.set('sidebarStatus', 0)
Cookies.set('sidebarStatus', 0);
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
Cookies.set('sidebarStatus', 0);
state.sidebar.opened = false;
state.sidebar.withoutAnimation = withoutAnimation;
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
state.device = device;
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
state.size = size;
Cookies.set('size', size);
},
SET_SIDEBAR_HIDE: (state, status) => {
state.sidebar.hide = status
state.sidebar.hide = status;
}
}
};
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
commit('TOGGLE_SIDEBAR');
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
commit('CLOSE_SIDEBAR', withoutAnimation);
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
commit('TOGGLE_DEVICE', device);
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
commit('SET_SIZE', size);
},
toggleSideBarHide({ commit }, status) {
commit('SET_SIDEBAR_HIDE', status)
commit('SET_SIDEBAR_HIDE', status);
}
}
};
export default {
namespaced: true,
state,
mutations,
actions
}
};

@ -1,50 +1,50 @@
const state = {
dict: new Array()
}
dict: []
};
const mutations = {
SET_DICT: (state, { key, value }) => {
if (key !== null && key !== "") {
if (key !== null && key !== '') {
state.dict.push({
key: key,
value: value
})
});
}
},
REMOVE_DICT: (state, key) => {
try {
for (let i = 0; i < state.dict.length; i++) {
if (state.dict[i].key == key) {
state.dict.splice(i, i)
return true
if (state.dict[i].key === key) {
state.dict.splice(i, i);
return true;
}
}
} catch (e) {
console.log(e);
}
},
CLEAN_DICT: (state) => {
state.dict = new Array()
state.dict = [];
}
}
};
const actions = {
// 设置字典
setDict({ commit }, data) {
commit('SET_DICT', data)
commit('SET_DICT', data);
},
// 删除字典
removeDict({ commit }, key) {
commit('REMOVE_DICT', key)
commit('REMOVE_DICT', key);
},
// 清空字典
cleanDict({ commit }) {
commit('CLEAN_DICT')
commit('CLEAN_DICT');
}
}
};
export default {
namespaced: true,
state,
mutations,
actions
}
};

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

Loading…
Cancel
Save