优化
This commit is contained in:
parent
dd585c62bc
commit
49cd58ad89
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use Closure;
|
||||
|
||||
|
@ -93,7 +93,11 @@ class User extends AbstractModel
|
||||
*/
|
||||
public function getUserimgAttribute($value)
|
||||
{
|
||||
return $value ? Base::fillUrl($value) : url('images/other/avatar.png');
|
||||
if ($value) {
|
||||
return Base::fillUrl($value);
|
||||
}
|
||||
$name = ($this->userid - 1) % 21 + 1;
|
||||
return url("images/avatar/default_{$name}.png");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,7 @@ namespace App\Module;
|
||||
|
||||
use Exception;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
class Ihttp
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\WebSocket;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace App\Tasks;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Module\Base;
|
||||
use App\Module\Ihttp;
|
||||
|
@ -4,7 +4,7 @@ namespace App\Tasks;
|
||||
|
||||
use App\Models\WebSocket;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace App\Tasks;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Models\WebSocket;
|
||||
use App\Models\WebSocketTmpMsg;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Tasks;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE);
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\WebSocketDialog;
|
||||
|
6
cmd
6
cmd
@ -33,12 +33,12 @@ supervisorctl_restart() {
|
||||
}
|
||||
|
||||
check_docker() {
|
||||
docker --help &> /dev/null
|
||||
docker --version &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${Error} ${RedBG} 未安装 Docker!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
docker-compose --help &> /dev/null
|
||||
docker-compose --version &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${Error} ${RedBG} 未安装 Docker-compose!${Font}"
|
||||
exit 1
|
||||
@ -46,7 +46,7 @@ check_docker() {
|
||||
}
|
||||
|
||||
check_node() {
|
||||
npm --help &> /dev/null
|
||||
npm --version > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${Error} ${RedBG} 未安装nodejs!${Font}"
|
||||
exit 1
|
||||
|
@ -2,10 +2,10 @@
|
||||
directory=/var/www
|
||||
|
||||
# 生产环境
|
||||
command=php bin/laravels start -i
|
||||
#command=php bin/laravels start -i
|
||||
|
||||
# 开发环境
|
||||
#command=./bin/inotify ./app
|
||||
command=./bin/inotify ./app
|
||||
|
||||
numprocs=1
|
||||
autostart=true
|
||||
|
26
package.json
26
package.json
@ -13,6 +13,9 @@
|
||||
"axios": "^0.21",
|
||||
"cross-env": "^7.0.2",
|
||||
"css-loader": "^5.2.6",
|
||||
"echarts": "^5.1.1",
|
||||
"electron": "^13.1.6",
|
||||
"element-ui": "^2.15.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"inquirer": "^8.1.1",
|
||||
"internal-ip": "^6.2.0",
|
||||
@ -24,33 +27,28 @@
|
||||
"moment": "^2.29.1",
|
||||
"nativefier": "^44.0.4",
|
||||
"node-sass": "^4.11.0",
|
||||
"notification-koro1": "^1.1.1",
|
||||
"postcss": "^8.1.14",
|
||||
"resolve-url-loader": "^4.0.0",
|
||||
"sass": "^1.34.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-router": "^3.4.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuex": "^3.6.2",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-cli": "^4.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"echarts": "^5.1.1",
|
||||
"electron": "^13.1.6",
|
||||
"element-ui": "^2.15.2",
|
||||
"notification-koro1": "^1.1.1",
|
||||
"tinymce": "^5.8.1",
|
||||
"tui-calendar-hi": "^1.13.0-5",
|
||||
"view-design-hi": "^4.6.1-2",
|
||||
"view-design-hi": "^4.6.1-9",
|
||||
"vue": "^2.6.12",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-emoji-picker": "^1.0.1",
|
||||
"vue-kityminder-gg": "^1.3.6",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-resize-observer": "^1.0.37",
|
||||
"vue-router": "^3.4.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuex": "^3.6.2",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-cli": "^4.7.0",
|
||||
"xlsx": "^0.17.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<ETooltip
|
||||
:content="text"
|
||||
:content="tipText"
|
||||
:placement="placement"
|
||||
:theme="tooltipTheme"
|
||||
:effect="tooltipTheme"
|
||||
:delay="delay"
|
||||
:disabled="!showTooltip"
|
||||
:max-width="tooltipMaxWidth"
|
||||
transfer>
|
||||
<span ref="content" @mouseenter="handleTooltipIn" class="common-auto-tip" @click="onClick">
|
||||
<template v-if="existSlot"><slot/></template>
|
||||
<template v-else>{{text}}</template>
|
||||
<template v-else>{{content}}</template>
|
||||
</span>
|
||||
</ETooltip>
|
||||
</template>
|
||||
@ -40,44 +40,22 @@
|
||||
|
||||
data() {
|
||||
return {
|
||||
slotText: '',
|
||||
showTooltip: false // 鼠标滑过overflow文本时,再检查是否需要显示
|
||||
showTooltip: false, // 鼠标滑过overflow文本时,再检查是否需要显示
|
||||
tooltipContent: '',
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.updateConetne()
|
||||
},
|
||||
|
||||
beforeUpdate () {
|
||||
this.updateConetne()
|
||||
},
|
||||
|
||||
activated() {
|
||||
this.updateConetne()
|
||||
},
|
||||
|
||||
computed: {
|
||||
text() {
|
||||
const {content, slotText} = this;
|
||||
if (content) {
|
||||
return content;
|
||||
}
|
||||
if (typeof slotText === 'undefined' || slotText.length < 1 || typeof slotText[0].text !== 'string') {
|
||||
return '';
|
||||
}
|
||||
return slotText[0].text;
|
||||
tipText() {
|
||||
const {content, tooltipContent} = this;
|
||||
return content || tooltipContent || "";
|
||||
},
|
||||
existSlot() {
|
||||
const {slotText} = this;
|
||||
return !(typeof slotText === 'undefined' || slotText.length < 1);
|
||||
return !(typeof this.$slots.default === 'undefined' || this.$slots.default.length < 1);
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateConetne () {
|
||||
this.slotText = this.$slots.default;
|
||||
},
|
||||
handleTooltipIn () {
|
||||
const $content = this.$refs.content;
|
||||
let range = document.createRange();
|
||||
@ -85,6 +63,14 @@
|
||||
range.setEnd($content, $content.childNodes.length);
|
||||
const rangeWidth = range.getBoundingClientRect().width;
|
||||
this.showTooltip = Math.floor(rangeWidth) > Math.floor($content.offsetWidth);
|
||||
if (this.showTooltip && this.existSlot) {
|
||||
const tmpArray = this.$slots.default.map((e) => {
|
||||
if (e.text) return e.text
|
||||
if (e.elm.innerText) return e.elm.innerText
|
||||
return ""
|
||||
})
|
||||
this.tooltipContent = tmpArray.join("");
|
||||
}
|
||||
range = null;
|
||||
},
|
||||
onClick(e) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div :class="['drawer-overlay', placement, value ? 'overlay-visible' : 'overlay-hide']" @click="mask">
|
||||
<div :class="['drawer-overlay', placement, value ? 'overlay-visible' : 'overlay-hide']">
|
||||
<div class="overlay-mask" @click="mask"></div>
|
||||
<div class="overlay-body" :style="bodyStyle">
|
||||
<div class="overlay-close">
|
||||
<a href="javascript:void(0)" @click.stop="close">
|
||||
@ -8,9 +9,7 @@
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="overlay-content" @click.stop="">
|
||||
<slot/>
|
||||
</div>
|
||||
<div class="overlay-content"><slot/></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -87,7 +86,12 @@
|
||||
escClose(e) {
|
||||
if (this.value && this.escClosable) {
|
||||
if (e.keyCode === 27) {
|
||||
this.close()
|
||||
let show = false;
|
||||
$A(".ivu-modal").each((i, e) => {
|
||||
show = $(e).is(":visible");
|
||||
return !show;
|
||||
})
|
||||
!show && this.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@
|
||||
if (typeof items === 'string') {
|
||||
items = [{'url': items}];
|
||||
}
|
||||
let lists = [];
|
||||
let list = [];
|
||||
$A.each(items, (index, item)=>{
|
||||
if (typeof item === 'string') item = {'url': item};
|
||||
if (item.url) {
|
||||
@ -208,10 +208,10 @@
|
||||
item.status = 'finished';
|
||||
if (typeof item.path === 'undefined') item.path = item.url;
|
||||
if (typeof item.thumb === 'undefined') item.thumb = item.url;
|
||||
lists.push(item);
|
||||
list.push(item);
|
||||
}
|
||||
});
|
||||
return lists;
|
||||
return list;
|
||||
},
|
||||
handleView (item) {
|
||||
//查看
|
||||
|
@ -1,9 +1,19 @@
|
||||
<template>
|
||||
<svg viewBox="25 25 50 50" class="common-loading"><circle cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10" class="common-path"></circle></svg>
|
||||
<ETooltip :disabled="content == ''" :content="content">
|
||||
<svg viewBox="25 25 50 50" class="common-loading">
|
||||
<circle cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10" class="common-path"></circle>
|
||||
</svg>
|
||||
</ETooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Loading',
|
||||
props: {
|
||||
content: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="quick-edit">
|
||||
<div v-if="isEdit" class="quick-input">
|
||||
<Input ref="input" v-model="content" :disabled="isLoad" @on-blur="onBlur" @on-enter="onEnter"/>
|
||||
<div class="quick-edit" :class="[alwaysIcon ? 'quick-always' : '']">
|
||||
<div v-if="isEdit" v-clickoutside="onEnter" class="quick-input">
|
||||
<TagInput v-if="isTag" ref="input" v-model="content" :disabled="isLoad" @on-enter="onEnter"/>
|
||||
<Input v-else ref="input" v-model="content" :disabled="isLoad" @on-enter="onEnter"/>
|
||||
<div v-if="isLoad" class="quick-loading"><Loading/></div>
|
||||
</div>
|
||||
<template v-else>
|
||||
@ -12,8 +13,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clickoutside from "../directives/clickoutside";
|
||||
|
||||
export default {
|
||||
name: 'QuickEdit',
|
||||
directives: {clickoutside},
|
||||
props: {
|
||||
value: {
|
||||
|
||||
@ -21,6 +25,14 @@ export default {
|
||||
autoEdit: {
|
||||
|
||||
},
|
||||
isTag: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
alwaysIcon: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -59,10 +71,6 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
onBlur() {
|
||||
this.onEnter();
|
||||
},
|
||||
|
||||
onEnter() {
|
||||
if (this.content == this.value) {
|
||||
this.isEdit = false;
|
||||
@ -77,7 +85,7 @@ export default {
|
||||
this.isEdit = false;
|
||||
this.isLoad = false;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,6 +1,46 @@
|
||||
<template>
|
||||
<div class="td-action" :style="tdStyle">
|
||||
<div ref="action" @mouseenter="handleIn" class="td-action-container" v-resize="onResize"><slot></slot></div>
|
||||
<div class="td-action" :style="tdStyle" :data-width="width" :data-height="height">
|
||||
<div
|
||||
ref="action"
|
||||
class="td-action-container"
|
||||
:class="{'td-action-menu':menu.length > 0}"
|
||||
@mouseenter="handleIn"
|
||||
v-resize="onResize">
|
||||
<slot></slot>
|
||||
<ETooltip
|
||||
v-for="(item, key) in menu"
|
||||
placement="top"
|
||||
:key="key"
|
||||
:disabled="!item.title"
|
||||
:content="item.title"
|
||||
:enterable="false"
|
||||
:open-delay="600">
|
||||
<EDropdown
|
||||
v-if="item.children && item.children.length > 0"
|
||||
size="medium"
|
||||
trigger="click"
|
||||
class="menu-dropdown"
|
||||
@command="onClick">
|
||||
<i class="aliicon menu-icon" v-html="item.icon" :style="item.style || {}"></i>
|
||||
<EDropdownMenu slot="dropdown">
|
||||
<EDropdownItem
|
||||
v-for="(d, k) in item.children"
|
||||
:key="k"
|
||||
:command="d.action"
|
||||
:divided="!!d.divided"
|
||||
:style="d.style || {}">
|
||||
<div>{{d.title}}</div>
|
||||
</EDropdownItem>
|
||||
</EDropdownMenu>
|
||||
</EDropdown>
|
||||
<i
|
||||
v-else
|
||||
class="aliicon menu-icon"
|
||||
v-html="item.icon"
|
||||
:style="item.style || {}"
|
||||
@click="onClick(item.action)"></i>
|
||||
</ETooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -18,6 +58,10 @@ Vue.use(VueResizeObserver);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
autoWidth: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
minWidth: {
|
||||
type: Number,
|
||||
default: 80
|
||||
@ -26,6 +70,12 @@ Vue.use(VueResizeObserver);
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
menu: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -46,8 +96,16 @@ Vue.use(VueResizeObserver);
|
||||
tdStyle() {
|
||||
const style = {};
|
||||
const {align} = this;
|
||||
if (['left', 'center', 'right'].includes(align.toLowerCase())) {
|
||||
style.textAlign = align;
|
||||
switch (align.toLowerCase()) {
|
||||
case 'left':
|
||||
style.justifyContent = 'flex-start';
|
||||
break;
|
||||
case 'center':
|
||||
style.justifyContent = 'center';
|
||||
break;
|
||||
case 'right':
|
||||
style.justifyContent = 'flex-end';
|
||||
break;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
@ -65,6 +123,9 @@ Vue.use(VueResizeObserver);
|
||||
})
|
||||
},
|
||||
onResize({ width, height }) {
|
||||
if (!this.autoWidth) {
|
||||
return;
|
||||
}
|
||||
$A(".ivu-table-column-" + this.column.__id).each((index, el) => {
|
||||
let action = $A(el).find(".td-action-container")
|
||||
if (action.length > 0) {
|
||||
@ -81,7 +142,14 @@ Vue.use(VueResizeObserver);
|
||||
if (this.column.maxWidth) {
|
||||
newWidth = Math.min(this.column.maxWidth, newWidth);
|
||||
}
|
||||
newWidth != this.column.width && this.$set(this.column, 'width', newWidth)
|
||||
if (newWidth != this.column.width) {
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.column, 'width', newWidth);
|
||||
})
|
||||
}
|
||||
},
|
||||
onClick(action) {
|
||||
this.$emit("action", action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,22 @@
|
||||
<template>
|
||||
<div class="common-tag-input" @paste="pasteText($event)" @click="clickWrap">
|
||||
<div class="common-tag-input" :class="{focus:isFocus}" @paste="pasteText($event)" @click="focus">
|
||||
<div class="tags-item" v-for="(text, index) in disSource">
|
||||
<span class="tags-content" @click.stop="">{{text}}</span><span class="tags-del" @click.stop="delTag(index)">×</span>
|
||||
</div>
|
||||
<textarea ref="myTextarea" class="tags-input" :style="{ minWidth: minWidth + 'px' }" :placeholder="tis || placeholder"
|
||||
v-model="content" @keydown.enter="downEnter($event)" @keyup="addTag($event, content)"
|
||||
@blur="addTag(false, content)" @keydown.delete="delTag(false)" :disabled="disabled" :readonly="readonly"></textarea>
|
||||
<span ref="myPlaceholder" v-if="showPlaceholder || tis !== ''" class="tags-placeholder">{{tis || placeholder}}</span>
|
||||
<textarea
|
||||
ref="myTextarea"
|
||||
class="tags-input"
|
||||
v-model="content"
|
||||
:style="{ minWidth: minWidth + 'px' }"
|
||||
:placeholder="tis || placeholderText"
|
||||
@keydown.enter="downEnter($event)"
|
||||
@keydown.delete="delTag(false)"
|
||||
@keyup="addTag($event, content)"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"/>
|
||||
<span ref="myPlaceholder" v-if="showPlaceholder || tis !== ''" class="tags-placeholder">{{tis || placeholderText}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -53,6 +63,8 @@
|
||||
content: '',
|
||||
|
||||
disSource: disSource,
|
||||
|
||||
isFocus: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -82,9 +94,36 @@
|
||||
temp += item;
|
||||
});
|
||||
this.$emit('input', temp);
|
||||
this.$emit('on-change');
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeholderText() {
|
||||
if (this.disSource.length > 0) {
|
||||
return ""
|
||||
}
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
focus(option) {
|
||||
const $el = this.$refs.myTextarea;
|
||||
$el.focus(option);
|
||||
const { cursor } = option || {};
|
||||
if (cursor) {
|
||||
const len = $el.value.length;
|
||||
switch (cursor) {
|
||||
case 'start':
|
||||
$el.setSelectionRange(0, 0);
|
||||
break;
|
||||
case 'end':
|
||||
$el.setSelectionRange(len, len);
|
||||
break;
|
||||
default:
|
||||
$el.setSelectionRange(0, len);
|
||||
}
|
||||
}
|
||||
},
|
||||
wayMinWidth() {
|
||||
this.showPlaceholder = true;
|
||||
this.$nextTick(() => {
|
||||
@ -107,35 +146,46 @@
|
||||
let content = (e.clipboardData || window.clipboardData).getData('text');
|
||||
this.addTag(false, content)
|
||||
},
|
||||
clickWrap() {
|
||||
this.$refs.myTextarea.focus();
|
||||
},
|
||||
downEnter(e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
onFocus() {
|
||||
this.isFocus = true;
|
||||
},
|
||||
onBlur() {
|
||||
this.isFocus = false;
|
||||
this.addTag(false, this.content)
|
||||
},
|
||||
addTag(e, content) {
|
||||
if (e.keyCode === 13 || e === false) {
|
||||
|
||||
if (e === false || e.keyCode === 13) {
|
||||
if (content.trim() != '' && this.disSource.indexOf(content.trim()) === -1) {
|
||||
this.disSource.push(content.trim());
|
||||
}
|
||||
this.content = '';
|
||||
} else {
|
||||
if (this.max > 0 && this.disSource.length >= this.max) {
|
||||
this.content = '';
|
||||
this.tis = '最多只能添加' + this.max + '个';
|
||||
clearInterval(this.tisTimeout);
|
||||
this.tisTimeout = setTimeout(() => { this.tis = ''; }, 2000);
|
||||
return;
|
||||
//
|
||||
if (e.keyCode === 13) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit("on-enter", e)
|
||||
})
|
||||
}
|
||||
let temp = content.trim();
|
||||
let cutPos = temp.length - this.cut.length;
|
||||
if (temp != '' && temp.substring(cutPos) === this.cut) {
|
||||
temp = temp.substring(0, cutPos);
|
||||
if (temp.trim() != '' && this.disSource.indexOf(temp.trim()) === -1) {
|
||||
this.disSource.push(temp.trim());
|
||||
}
|
||||
this.content = '';
|
||||
return;
|
||||
}
|
||||
if (this.max > 0 && this.disSource.length >= this.max) {
|
||||
this.content = '';
|
||||
this.tis = '最多只能添加' + this.max + '个';
|
||||
clearInterval(this.tisTimeout);
|
||||
this.tisTimeout = setTimeout(() => { this.tis = ''; }, 2000);
|
||||
return;
|
||||
}
|
||||
let temp = content.trim();
|
||||
let cutPos = temp.length - this.cut.length;
|
||||
if (temp != '' && temp.substring(cutPos) === this.cut) {
|
||||
temp = temp.substring(0, cutPos);
|
||||
if (temp.trim() != '' && this.disSource.indexOf(temp.trim()) === -1) {
|
||||
this.disSource.push(temp.trim());
|
||||
}
|
||||
this.content = '';
|
||||
}
|
||||
},
|
||||
delTag(index) {
|
||||
@ -145,7 +195,8 @@
|
||||
}
|
||||
index = this.disSource.length - 1;
|
||||
}
|
||||
this.disSource.splice(index, 1)
|
||||
this.disSource.splice(index, 1);
|
||||
this.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
<template>
|
||||
<ETooltip v-if="user"
|
||||
class="common-avatar"
|
||||
:open-delay="600"
|
||||
:disabled="tooltipDisabled">
|
||||
<ETooltip
|
||||
v-if="user"
|
||||
class="common-avatar"
|
||||
:open-delay="600"
|
||||
:disabled="tooltipDisabled"
|
||||
:placement="tooltipPlacement">
|
||||
<div slot="content" class="common-avatar-transfer">
|
||||
<slot/>
|
||||
<p>{{$L('昵称')}}: {{user.nickname}}</p>
|
||||
@ -14,7 +16,7 @@
|
||||
<div class="avatar-wrapper">
|
||||
<div v-if="showIcon" :class="['avatar-box', userId === userid || user.online ? 'online' : '']" :style="boxStyle">
|
||||
<em :style="spotStyle"></em>
|
||||
<EAvatar v-if="showImg" :src="user.userimg" :size="avatarSize"/>
|
||||
<EAvatar v-if="showImg" :class="{'avatar-default':isDefault}" :src="user.userimg" :size="avatarSize"/>
|
||||
<EAvatar v-else :size="avatarSize" class="avatar-text">
|
||||
<span :style="spotStyle">{{nickname}}</span>
|
||||
</EAvatar>
|
||||
@ -53,6 +55,10 @@
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
tooltipPlacement: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
borderWitdh: {
|
||||
type: Number,
|
||||
default: 0
|
||||
@ -123,6 +129,11 @@
|
||||
return !$A.rightExists(userimg, '/avatar.png');
|
||||
},
|
||||
|
||||
isDefault() {
|
||||
const {userimg} = this.user
|
||||
return $A.strExists(userimg, '/avatar/default_');
|
||||
},
|
||||
|
||||
nickname() {
|
||||
const {nickname} = this.user;
|
||||
if (!nickname) {
|
||||
|
@ -18,7 +18,7 @@
|
||||
@on-set-default-options="setDefaultOptions">
|
||||
<div v-if="multipleMax" slot="drop-prepend" class="user-drop-prepend">{{$L('最多只能选择' + multipleMax + '个')}}</div>
|
||||
<Option
|
||||
v-for="(item, key) in lists"
|
||||
v-for="(item, key) in list"
|
||||
:value="item.userid"
|
||||
:key="key"
|
||||
:label="item.nickname"
|
||||
@ -85,7 +85,7 @@
|
||||
loading: false,
|
||||
openLoad: false,
|
||||
values: [],
|
||||
lists: []
|
||||
list: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -121,7 +121,7 @@
|
||||
openChange(show) {
|
||||
if (show && !this.openLoad) {
|
||||
this.openLoad = true;
|
||||
if (this.lists.length == this.values.length || this.lists.length <= 1) {
|
||||
if (this.list.length == this.values.length || this.list.length <= 1) {
|
||||
this.$nextTick(this.searchUser);
|
||||
}
|
||||
}
|
||||
@ -130,7 +130,7 @@
|
||||
setDefaultOptions(options) {
|
||||
const userids = [];
|
||||
options.forEach(({value, label}) => {
|
||||
this.lists.push({
|
||||
this.list.push({
|
||||
userid: value,
|
||||
nickname: label,
|
||||
});
|
||||
@ -148,9 +148,9 @@
|
||||
this.$set(option, 'label', user.nickname)
|
||||
this.$set(option, 'avatar', user.userimg)
|
||||
}
|
||||
this.lists.some((item, index) => {
|
||||
this.list.some((item, index) => {
|
||||
if (item.userid == user.userid) {
|
||||
this.$set(this.lists, index, Object.assign(item, user));
|
||||
this.$set(this.list, index, Object.assign(item, user));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -172,14 +172,14 @@
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.loading = false;
|
||||
this.lists = data;
|
||||
this.list = data;
|
||||
}).catch(({msg}) => {
|
||||
this.loading = false;
|
||||
this.lists = [];
|
||||
this.list = [];
|
||||
$A.messageWarning(msg);
|
||||
});
|
||||
} else {
|
||||
this.lists = [];
|
||||
this.list = [];
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -250,7 +250,7 @@
|
||||
<Col span="3"></Col>
|
||||
<Col span="3"></Col>
|
||||
</Row>
|
||||
<TaskRow v-if="tablePanel('showMy')" :list="myList" open-key="my" @command="dropTask" fast-add-task/>
|
||||
<TaskRow v-if="tablePanel('showMy')" :list="myList" open-key="my" @command="dropTask" @on-priority="addTaskOpen" fast-add-task/>
|
||||
</div>
|
||||
<!--未完成任务-->
|
||||
<div v-if="projectData.task_num > 0" :class="['project-table-body', !tablePanel('showUndone') ? 'project-table-hide' : '']">
|
||||
@ -265,7 +265,7 @@
|
||||
<Col span="3"></Col>
|
||||
<Col span="3"></Col>
|
||||
</Row>
|
||||
<TaskRow v-if="tablePanel('showUndone')" :list="undoneList" open-key="undone" @command="dropTask"/>
|
||||
<TaskRow v-if="tablePanel('showUndone')" :list="undoneList" open-key="undone" @command="dropTask" @on-priority="addTaskOpen"/>
|
||||
</div>
|
||||
<!--已完成任务-->
|
||||
<div v-if="projectData.task_num > 0" :class="['project-table-body', !tablePanel('showCompleted') ? 'project-table-hide' : '']">
|
||||
@ -280,7 +280,7 @@
|
||||
<Col span="3"></Col>
|
||||
<Col span="3"></Col>
|
||||
</Row>
|
||||
<TaskRow v-if="tablePanel('showCompleted')" :list="completedList" open-key="completed" @command="dropTask"/>
|
||||
<TaskRow v-if="tablePanel('showCompleted')" :list="completedList" open-key="completed" @command="dropTask" @on-priority="addTaskOpen"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -131,7 +131,7 @@
|
||||
:open-key="openKey"
|
||||
@command="dropTask"/>
|
||||
</div>
|
||||
<TaskAddSimple v-if="fastAddTask || parentId > 0" :parent-id="parentId" row-mode/>
|
||||
<TaskAddSimple v-if="fastAddTask || parentId > 0" :parent-id="parentId" row-mode @on-priority="onPriority"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -218,6 +218,10 @@ export default {
|
||||
this.$emit("command", task, command)
|
||||
},
|
||||
|
||||
onPriority(data) {
|
||||
this.$emit("on-priority", data)
|
||||
},
|
||||
|
||||
getSublist(task) {
|
||||
if (this.taskOpen[task.id] === true) {
|
||||
this.$set(this.taskOpen, task.id, false);
|
||||
|
@ -13,9 +13,8 @@
|
||||
<ul>
|
||||
<li
|
||||
v-for="(item, key) in menu"
|
||||
v-if="!item.admin||userIsAdmin"
|
||||
:key="key"
|
||||
:class="classNameRoute(item.path)"
|
||||
:class="classNameRoute(item.path, item.divided)"
|
||||
@click="toggleRoute(item.path)">{{$L(item.name)}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -34,13 +33,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
curPath: this.$route.path,
|
||||
|
||||
menu: [
|
||||
{path: 'personal', admin: false, name: '个人设置'},
|
||||
{path: 'password', admin: false, name: '密码设置'},
|
||||
{path: 'system', admin: true, name: '系统设置'},
|
||||
{path: 'priority', admin: true, name: '任务等级'},
|
||||
],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -49,6 +41,20 @@ export default {
|
||||
computed: {
|
||||
...mapState(['userInfo', 'userIsAdmin']),
|
||||
|
||||
menu() {
|
||||
let menu = [
|
||||
{path: 'personal', name: '个人设置'},
|
||||
{path: 'password', name: '密码设置'},
|
||||
]
|
||||
if (this.userIsAdmin) {
|
||||
menu.push(...[
|
||||
{path: 'system', name: '系统设置', divided: true},
|
||||
{path: 'priority', name: '任务等级'},
|
||||
])
|
||||
}
|
||||
return menu;
|
||||
},
|
||||
|
||||
titleNameRoute() {
|
||||
const {curPath, menu} = this;
|
||||
let name = '';
|
||||
@ -71,9 +77,10 @@ export default {
|
||||
this.goForward({path: '/manage/setting/' + path});
|
||||
},
|
||||
|
||||
classNameRoute(path) {
|
||||
classNameRoute(path, divided) {
|
||||
return {
|
||||
"active": $A.leftExists(this.curPath, '/manage/setting/' + path)
|
||||
"active": $A.leftExists(this.curPath, '/manage/setting/' + path),
|
||||
"divided": !!divided
|
||||
};
|
||||
},
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<div class="setting-item submit">
|
||||
<Form ref="formDatum" :model="formDatum" :rules="ruleDatum" label-width="auto" @submit.native.prevent>
|
||||
<Form ref="formData" :model="formData" :rules="ruleData" label-width="auto" @submit.native.prevent>
|
||||
<FormItem :label="$L('头像')" prop="userimg">
|
||||
<ImgUpload v-model="formDatum.userimg" :num="1"></ImgUpload>
|
||||
<ImgUpload v-model="formData.userimg" :num="1"></ImgUpload>
|
||||
<span class="form-tip">{{$L('建议尺寸:200x200')}}</span>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('邮箱')">
|
||||
<Input v-model="userInfo.email" disabled></Input>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('昵称')" prop="nickname">
|
||||
<Input v-model="formDatum.nickname" :maxlength="20"></Input>
|
||||
<Input v-model="formData.nickname" :maxlength="20"></Input>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('职位/职称')" prop="profession">
|
||||
<Input v-model="formDatum.profession" :maxlength="20"></Input>
|
||||
<Input v-model="formData.profession" :maxlength="20"></Input>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div class="setting-footer">
|
||||
@ -31,13 +31,13 @@ export default {
|
||||
return {
|
||||
loadIng: 0,
|
||||
|
||||
formDatum: {
|
||||
formData: {
|
||||
userimg: '',
|
||||
nickname: '',
|
||||
profession: ''
|
||||
},
|
||||
|
||||
ruleDatum: { },
|
||||
ruleData: { },
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -53,7 +53,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
initLanguage() {
|
||||
this.ruleDatum = {
|
||||
this.ruleData = {
|
||||
nickname: [
|
||||
{required: true, message: this.$L('请输入昵称!'), trigger: 'change'},
|
||||
{type: 'string', min: 2, message: this.$L('昵称长度至少2位!'), trigger: 'change'}
|
||||
@ -62,16 +62,18 @@ export default {
|
||||
},
|
||||
|
||||
initData() {
|
||||
this.$set(this.formDatum, 'userimg', this.userInfo.userimg);
|
||||
this.$set(this.formDatum, 'nickname', this.userInfo.nickname);
|
||||
this.$set(this.formDatum, 'profession', this.userInfo.profession);
|
||||
this.formDatum_bak = $A.cloneJSON(this.formDatum);
|
||||
if (!$A.strExists(this.userInfo.userimg, '/avatar/default_')) {
|
||||
this.$set(this.formData, 'userimg', this.userInfo.userimg);
|
||||
}
|
||||
this.$set(this.formData, 'nickname', this.userInfo.nickname);
|
||||
this.$set(this.formData, 'profession', this.userInfo.profession);
|
||||
this.formData_bak = $A.cloneJSON(this.formData);
|
||||
},
|
||||
|
||||
submitForm() {
|
||||
this.$refs.formDatum.validate((valid) => {
|
||||
this.$refs.formData.validate((valid) => {
|
||||
if (valid) {
|
||||
let data = $A.cloneJSON(this.formDatum);
|
||||
let data = $A.cloneJSON(this.formData);
|
||||
if ($A.count(data.userimg) == 0) data.userimg = "";
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
@ -90,7 +92,7 @@ export default {
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.formDatum = $A.cloneJSON(this.formDatum_bak);
|
||||
this.formData = $A.cloneJSON(this.formData_bak);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,15 @@
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
|
||||
.overlay-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.overlay-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -21,6 +30,7 @@
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
z-index: 2;
|
||||
|
||||
.overlay-close {
|
||||
flex-shrink: 0;
|
||||
@ -71,6 +81,8 @@
|
||||
}
|
||||
|
||||
&.overlay-hide {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: opacity 0.2s ease;
|
||||
.overlay-body {
|
||||
.overlay-content {
|
||||
|
17
resources/assets/sass/components/quick-edit.scss
vendored
17
resources/assets/sass/components/quick-edit.scss
vendored
@ -4,6 +4,7 @@
|
||||
max-width: 100%;
|
||||
.quick-input {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
position: relative;
|
||||
.quick-loading {
|
||||
position: absolute;
|
||||
@ -33,9 +34,25 @@
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
&.quick-always {
|
||||
.quick-icon {
|
||||
display: inline-block;
|
||||
opacity: 0.3;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.quick-icon {
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ivu-table-row-hover {
|
||||
.quick-edit {
|
||||
.quick-icon {
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
resources/assets/sass/components/tag-input.scss
vendored
26
resources/assets/sass/components/tag-input.scss
vendored
@ -11,8 +11,16 @@
|
||||
cursor: text;
|
||||
vertical-align: middle;
|
||||
line-height: normal;
|
||||
-webkit-transition: border .2s ease-in-out, background .2s ease-in-out, -webkit-box-shadow .2s ease-in-out;
|
||||
transition: border .2s ease-in-out, background .2s ease-in-out, -webkit-box-shadow .2s ease-in-out;
|
||||
transition: all .2s;
|
||||
|
||||
&:hover {
|
||||
border-color: #a2d98d;
|
||||
}
|
||||
|
||||
&.focus {
|
||||
border-color: #a2d98d;
|
||||
box-shadow: 0 0 0 2px rgba(139,207,112,.2)
|
||||
}
|
||||
|
||||
.tags-item, .tags-input {
|
||||
position: relative;
|
||||
@ -62,7 +70,7 @@
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
color: #ffffff00;
|
||||
color: rgba(255, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
.common-tag-input::after {
|
||||
@ -71,3 +79,15 @@
|
||||
height: 0;
|
||||
clear: both;
|
||||
}
|
||||
.ivu-form-item-error {
|
||||
.common-tag-input {
|
||||
border-color: #ed4014;
|
||||
&:hover {
|
||||
border-color: #ed4014;
|
||||
}
|
||||
&.focus {
|
||||
border-color: #ed4014;
|
||||
box-shadow: 0 0 0 2px rgba(237,64,20,.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.avatar-default {
|
||||
background-color: transparent;
|
||||
}
|
||||
.avatar-text {
|
||||
background-color: $primary-color;
|
||||
> span {
|
||||
@ -23,7 +26,7 @@
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: #ff0000;
|
||||
background-color: #ff9900;
|
||||
border: 1px solid #ffffff;
|
||||
transform-origin: right bottom;
|
||||
z-index: 1;
|
||||
|
21
resources/assets/sass/pages/common.scss
vendored
21
resources/assets/sass/pages/common.scss
vendored
@ -104,16 +104,27 @@ body {
|
||||
}
|
||||
.td-action {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.td-action-container {
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
a {
|
||||
font-size: 12px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
&.td-action-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.menu-dropdown {
|
||||
display: flex;
|
||||
}
|
||||
.menu-icon {
|
||||
cursor: pointer;
|
||||
font-size: 21px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.ivu-table-row-hover {
|
||||
|
27
resources/assets/sass/pages/page-setting.scss
vendored
27
resources/assets/sass/pages/page-setting.scss
vendored
@ -40,10 +40,37 @@
|
||||
padding: 0 20px;
|
||||
margin: 5px 0;
|
||||
position: relative;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background-color: #F4F5F7;
|
||||
}
|
||||
|
||||
&.divided {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
height: 1px;
|
||||
background-color: #F4F4F5;
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
height: 9px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user