Compare commits
No commits in common. "master" and "v0.9.83" have entirely different histories.
@ -70,7 +70,11 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
public function getPercentageAttribute()
|
||||
{
|
||||
if (!isset($this->appendattrs['percentage'])) {
|
||||
$this->generatePercentage();
|
||||
if ($this->read > $this->send || empty($this->send)) {
|
||||
$this->appendattrs['percentage'] = 100;
|
||||
} else {
|
||||
$this->appendattrs['percentage'] = intval($this->read / $this->send * 100);
|
||||
}
|
||||
}
|
||||
return $this->appendattrs['percentage'];
|
||||
}
|
||||
@ -94,22 +98,6 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取占比
|
||||
* @param bool $increment 是否新增阅读数
|
||||
* @return int
|
||||
*/
|
||||
public function generatePercentage($increment = false) {
|
||||
if ($increment) {
|
||||
$this->increment('read');
|
||||
}
|
||||
if ($this->read > $this->send || empty($this->send)) {
|
||||
return $this->appendattrs['percentage'] = 100;
|
||||
} else {
|
||||
return $this->appendattrs['percentage'] = intval($this->read / $this->send * 100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记已送达 同时 告诉发送人已送达
|
||||
* @param $userid
|
||||
@ -139,17 +127,13 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
if (!$msgRead->read_at) {
|
||||
$msgRead->read_at = Carbon::now();
|
||||
$msgRead->save();
|
||||
$this->generatePercentage(true);
|
||||
$this->increment('read');
|
||||
PushTask::push([
|
||||
'userid' => $this->userid,
|
||||
'msg' => [
|
||||
'type' => 'dialog',
|
||||
'mode' => 'readed',
|
||||
'data' => [
|
||||
'id' => $this->id,
|
||||
'read' => $this->read,
|
||||
'percentage' => $this->percentage,
|
||||
],
|
||||
'mode' => 'update',
|
||||
'data' => $this->toArray(),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
@ -342,15 +342,19 @@ class Base
|
||||
{
|
||||
if (strtolower($charset) == 'utf-8') {
|
||||
if (Base::getStrlen($string) <= $length) return $string;
|
||||
$strcut = Base::utf8Substr($string, $length, $start);
|
||||
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
|
||||
$strcut = Base::utf8Substr($strcut, $length, $start);
|
||||
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);
|
||||
return $strcut . $dot;
|
||||
} else {
|
||||
$length = $length * 2;
|
||||
if (strlen($string) <= $length) return $string;
|
||||
$string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
|
||||
$strcut = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
|
||||
}
|
||||
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);
|
||||
}
|
||||
return $strcut . $dot;
|
||||
}
|
||||
|
@ -127,11 +127,9 @@ class WebSocketService implements WebSocketHandlerInterface
|
||||
case 'readMsg':
|
||||
$ids = is_array($data['id']) ? $data['id'] : [$data['id']];
|
||||
$userid = $this->getUserid($frame->fd);
|
||||
WebSocketDialogMsg::whereIn('id', $ids)->chunkById(20, function($list) use ($userid) {
|
||||
/** @var WebSocketDialogMsg $item */
|
||||
foreach ($list as $item) {
|
||||
$item->readSuccess($userid);
|
||||
}
|
||||
$list = WebSocketDialogMsg::whereIn('id', $ids)->get();
|
||||
$list->transform(function(WebSocketDialogMsg $item) use ($userid) {
|
||||
$item->readSuccess($userid);
|
||||
});
|
||||
return;
|
||||
|
||||
|
35
cmd
35
cmd
@ -13,7 +13,6 @@ Error="${Red}[错误]${Font}"
|
||||
|
||||
cur_path="$(pwd)"
|
||||
cur_arg=$@
|
||||
COMPOSE="docker-compose"
|
||||
|
||||
judge() {
|
||||
if [[ 0 -eq $? ]]; then
|
||||
@ -58,22 +57,18 @@ check_docker() {
|
||||
fi
|
||||
docker-compose version &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
docker compose version &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${Error} ${RedBG} 未安装 Docker-compose!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
COMPOSE="docker compose"
|
||||
echo -e "${Error} ${RedBG} 未安装 Docker-compose!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n `$COMPOSE version | grep -E "\sv*1"` ]]; then
|
||||
$COMPOSE version
|
||||
if [[ -n `docker-compose version | grep "docker-compose" | grep -E "\sv*1"` ]]; then
|
||||
docker-compose version
|
||||
echo -e "${Error} ${RedBG} Docker-compose 版本过低,请升级至v2+!${Font}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_node() {
|
||||
npm --version &> /dev/null
|
||||
npm --version > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${Error} ${RedBG} 未安装nodejs!${Font}"
|
||||
exit 1
|
||||
@ -81,7 +76,7 @@ check_node() {
|
||||
}
|
||||
|
||||
docker_name() {
|
||||
echo `$COMPOSE ps | awk '{print $1}' | grep "\-$1\-"`
|
||||
echo `docker-compose ps | awk '{print $1}' | grep "\-$1\-"`
|
||||
}
|
||||
|
||||
run_compile() {
|
||||
@ -277,7 +272,7 @@ if [ $# -gt 0 ]; then
|
||||
chmod -R 775 "${cur_path}/docker/mysql/data"
|
||||
# 启动容器
|
||||
[[ "$(arg_get port)" -gt 0 ]] && env_set APP_PORT "$(arg_get port)"
|
||||
$COMPOSE up php -d
|
||||
docker-compose up php -d
|
||||
# 安装composer依赖
|
||||
run_exec php "composer install"
|
||||
if [ ! -f "${cur_path}/vendor/autoload.php" ]; then
|
||||
@ -305,7 +300,7 @@ if [ $# -gt 0 ]; then
|
||||
run_exec php "php artisan migrate --seed"
|
||||
# 设置初始化密码
|
||||
res=`run_exec mariadb "sh /etc/mysql/repassword.sh"`
|
||||
$COMPOSE up -d
|
||||
docker-compose up -d
|
||||
supervisorctl_restart php
|
||||
echo -e "${OK} ${GreenBG} 安装完成 ${Font}"
|
||||
echo -e "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
|
||||
@ -319,7 +314,7 @@ if [ $# -gt 0 ]; then
|
||||
run_exec php "composer update"
|
||||
run_exec php "php artisan migrate"
|
||||
supervisorctl_restart php
|
||||
$COMPOSE up -d
|
||||
docker-compose up -d
|
||||
elif [[ "$1" == "uninstall" ]]; then
|
||||
shift 1
|
||||
read -rp "确定要卸载(含:删除容器、数据库、日志)吗?(y/n): " uninstall
|
||||
@ -333,7 +328,7 @@ if [ $# -gt 0 ]; then
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
$COMPOSE down
|
||||
docker-compose down
|
||||
rm -rf "./docker/mysql/data"
|
||||
rm -rf "./docker/log/supervisor"
|
||||
find "./storage/logs" -name "*.log" | xargs rm -rf
|
||||
@ -346,7 +341,7 @@ if [ $# -gt 0 ]; then
|
||||
elif [[ "$1" == "port" ]]; then
|
||||
shift 1
|
||||
env_set APP_PORT "$1"
|
||||
$COMPOSE up -d
|
||||
docker-compose up -d
|
||||
echo -e "${OK} ${GreenBG} 修改成功 ${Font}"
|
||||
echo -e "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
|
||||
elif [[ "$1" == "repassword" ]]; then
|
||||
@ -419,11 +414,11 @@ if [ $# -gt 0 ]; then
|
||||
e="./vendor/bin/phpunit $@" && run_exec php "$e"
|
||||
elif [[ "$1" == "restart" ]]; then
|
||||
shift 1
|
||||
$COMPOSE stop "$@"
|
||||
$COMPOSE start "$@"
|
||||
docker-compose stop "$@"
|
||||
docker-compose start "$@"
|
||||
else
|
||||
$COMPOSE "$@"
|
||||
docker-compose "$@"
|
||||
fi
|
||||
else
|
||||
$COMPOSE ps
|
||||
docker-compose ps
|
||||
fi
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.10.5",
|
||||
"version": "0.9.83",
|
||||
"description": "DooTask is task management system.",
|
||||
"main": "electron.js",
|
||||
"license": "MIT",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.10.5",
|
||||
"version": "0.9.83",
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
"start": "./cmd dev",
|
||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/189.js
vendored
2
public/js/build/189.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/206.js
vendored
2
public/js/build/206.js
vendored
File diff suppressed because one or more lines are too long
@ -257,7 +257,7 @@
|
||||
/** @license
|
||||
*
|
||||
* jsPDF - PDF Document creation from JavaScript
|
||||
* Version 2.5.0 Built on 2021-12-21T09:44:51.866Z
|
||||
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
|
||||
* CommitID 00000000
|
||||
*
|
||||
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
|
||||
|
File diff suppressed because one or more lines are too long
2
public/js/build/304.js
vendored
2
public/js/build/304.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/400.js
vendored
2
public/js/build/400.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/422.js
vendored
1
public/js/build/422.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/486.js
vendored
2
public/js/build/486.js
vendored
File diff suppressed because one or more lines are too long
@ -257,7 +257,7 @@
|
||||
/** @license
|
||||
*
|
||||
* jsPDF - PDF Document creation from JavaScript
|
||||
* Version 2.5.0 Built on 2021-12-21T09:44:51.866Z
|
||||
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
|
||||
* CommitID 00000000
|
||||
*
|
||||
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
|
||||
|
2
public/js/build/494.js
vendored
2
public/js/build/494.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/build/510.js
vendored
Normal file
2
public/js/build/510.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* clipboard.js v2.0.8
|
||||
* clipboard.js v2.0.10
|
||||
* https://clipboardjs.com/
|
||||
*
|
||||
* Licensed MIT © Zeno Rocha
|
2
public/js/build/528.js
vendored
2
public/js/build/528.js
vendored
File diff suppressed because one or more lines are too long
@ -257,7 +257,7 @@
|
||||
/** @license
|
||||
*
|
||||
* jsPDF - PDF Document creation from JavaScript
|
||||
* Version 2.5.0 Built on 2021-12-21T09:44:51.866Z
|
||||
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
|
||||
* CommitID 00000000
|
||||
*
|
||||
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
|
||||
|
1
public/js/build/540.js
vendored
Normal file
1
public/js/build/540.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/js/build/544.js
vendored
2
public/js/build/544.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/601.js
vendored
2
public/js/build/601.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/747.js
vendored
2
public/js/build/747.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/836.js
vendored
2
public/js/build/836.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/856.js
vendored
2
public/js/build/856.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
/*! @license DOMPurify 2.3.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.4/LICENSE */
|
||||
/*! @license DOMPurify 2.3.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.6/LICENSE */
|
||||
|
2
public/js/build/889.js
vendored
2
public/js/build/889.js
vendored
File diff suppressed because one or more lines are too long
@ -257,7 +257,7 @@
|
||||
/** @license
|
||||
*
|
||||
* jsPDF - PDF Document creation from JavaScript
|
||||
* Version 2.5.0 Built on 2021-12-21T09:44:51.866Z
|
||||
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
|
||||
* CommitID 00000000
|
||||
*
|
||||
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
|
||||
|
2
public/js/build/954.js
vendored
2
public/js/build/954.js
vendored
File diff suppressed because one or more lines are too long
@ -257,7 +257,7 @@
|
||||
/** @license
|
||||
*
|
||||
* jsPDF - PDF Document creation from JavaScript
|
||||
* Version 2.5.0 Built on 2021-12-21T09:44:51.866Z
|
||||
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
|
||||
* CommitID 00000000
|
||||
*
|
||||
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
|
||||
|
2
public/js/build/956.js
vendored
Normal file
2
public/js/build/956.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* clipboard.js v2.0.8
|
||||
* clipboard.js v2.0.10
|
||||
* https://clipboardjs.com/
|
||||
*
|
||||
* Licensed MIT © Zeno Rocha
|
@ -21,7 +21,6 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
tocObj.reset()
|
||||
this.init();
|
||||
this.createEditor();
|
||||
},
|
||||
|
@ -1,20 +1,8 @@
|
||||
<template>
|
||||
<div class="quick-edit" :class="[alwaysIcon ? 'quick-always' : '']">
|
||||
<div v-if="isEdit" v-clickoutside="onClickOut" class="quick-input">
|
||||
<TagInput
|
||||
v-if="isTag"
|
||||
ref="input"
|
||||
v-model="content"
|
||||
:disabled="isLoad"
|
||||
@on-keyup="onKeyup"
|
||||
@on-blur="onBlur"/>
|
||||
<Input
|
||||
v-else
|
||||
ref="input"
|
||||
v-model="content"
|
||||
:disabled="isLoad"
|
||||
@on-keyup="onKeyup"
|
||||
@on-blur="onBlur"/>
|
||||
<TagInput v-if="isTag" ref="input" v-model="content" :disabled="isLoad" @on-enter="onEnter" @on-blur="onBlur"/>
|
||||
<Input v-else ref="input" v-model="content" :disabled="isLoad" @on-enter="onEnter" @on-blur="onBlur"/>
|
||||
<div v-if="isLoad" class="quick-loading"><Loading/></div>
|
||||
</div>
|
||||
<template v-else>
|
||||
@ -66,6 +54,9 @@ export default {
|
||||
},
|
||||
|
||||
watch: {
|
||||
isEdit(val) {
|
||||
this.$emit("on-edit-change", val);
|
||||
},
|
||||
autoEdit(val) {
|
||||
if (val === true) {
|
||||
setTimeout(this.onEdit, 0)
|
||||
@ -74,14 +65,9 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
onEditChange(val) {
|
||||
this.isEdit = val;
|
||||
this.$emit("on-edit-change", val);
|
||||
},
|
||||
|
||||
onEdit() {
|
||||
this.content = this.value;
|
||||
this.onEditChange(true);
|
||||
this.isEdit = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input.focus({
|
||||
cursor: 'all'
|
||||
@ -89,18 +75,9 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
onKeyup(e) {
|
||||
if (e.keyCode === 13) {
|
||||
this.onEnter();
|
||||
} else if (e.keyCode === 27) {
|
||||
this.isEdit = false;
|
||||
this.isLoad = false;
|
||||
}
|
||||
},
|
||||
|
||||
onEnter() {
|
||||
if (this.content == this.value) {
|
||||
this.onEditChange(false);
|
||||
this.isEdit = false;
|
||||
return;
|
||||
}
|
||||
if (this.isLoad) {
|
||||
@ -109,7 +86,7 @@ export default {
|
||||
this.isLoad = true;
|
||||
this.$emit("input", this.content);
|
||||
this.$emit("on-update", this.content, () => {
|
||||
this.onEditChange(false);
|
||||
this.isEdit = false;
|
||||
this.isLoad = false;
|
||||
})
|
||||
},
|
||||
@ -122,7 +99,7 @@ export default {
|
||||
},
|
||||
|
||||
onBlur() {
|
||||
if (this.clickOutSide || !this.isEdit) {
|
||||
if (this.clickOutSide) {
|
||||
return;
|
||||
}
|
||||
this.onEnter();
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="teditor-wrapper">
|
||||
<div class="teditor-box" :class="[!inline && spinShow ? 'teditor-loadstyle' : 'teditor-loadedstyle']">
|
||||
<template v-if="inline">
|
||||
<div ref="myTextarea" :id="id" v-html="spinShow ? '' : content"></div>
|
||||
<div ref="myTextarea" :id="id" v-html="content"></div>
|
||||
<Icon v-if="spinShow" type="ios-loading" :size="18" class="icon-loading icon-inline"></Icon>
|
||||
</template>
|
||||
<template v-else>
|
||||
@ -181,7 +181,11 @@
|
||||
newValue = "";
|
||||
}
|
||||
if (!this.isTyping) {
|
||||
this.setContent(newValue);
|
||||
if (this.getEditor() !== null) {
|
||||
this.getEditor().setContent(newValue);
|
||||
} else{
|
||||
this.content = newValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
readOnly(value) {
|
||||
@ -455,14 +459,6 @@
|
||||
return this.getEditor().getContent();
|
||||
},
|
||||
|
||||
setContent(content) {
|
||||
if (this.getEditor() === null) {
|
||||
this.content = content;
|
||||
} else if (content != this.getEditor().getContent()){
|
||||
this.getEditor().setContent(content);
|
||||
}
|
||||
},
|
||||
|
||||
insertImage(src) {
|
||||
this.insertContent('<img src="' + src + '">');
|
||||
},
|
||||
|
@ -11,7 +11,7 @@
|
||||
:placeholder="tis || placeholderText"
|
||||
@keydown.enter="downEnter($event)"
|
||||
@keydown.delete="delTag(false)"
|
||||
@keyup="onKeyup"
|
||||
@keyup="addTag($event, content)"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
:disabled="disabled"
|
||||
@ -158,22 +158,19 @@
|
||||
this.addTag(false, this.content)
|
||||
this.$emit("on-blur", e)
|
||||
},
|
||||
onKeyup(e) {
|
||||
this.addTag(e, this.content);
|
||||
//
|
||||
this.$emit("on-keyup", e)
|
||||
if (e.keyCode === 13) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit("on-enter", e)
|
||||
})
|
||||
}
|
||||
},
|
||||
addTag(e, content) {
|
||||
|
||||
if (e === false || e.keyCode === 13) {
|
||||
if (content.trim() != '' && this.disSource.indexOf(content.trim()) === -1) {
|
||||
this.disSource.push(content.trim());
|
||||
}
|
||||
this.content = '';
|
||||
//
|
||||
if (e.keyCode === 13) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit("on-enter", e)
|
||||
})
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this.max > 0 && this.disSource.length >= this.max) {
|
||||
|
6
resources/assets/js/functions/web.js
vendored
6
resources/assets/js/functions/web.js
vendored
@ -102,7 +102,7 @@
|
||||
* @returns {*|string}
|
||||
*/
|
||||
formatTime(date) {
|
||||
let time = $A.Date(date, true),
|
||||
let time = Math.round($A.Date(date).getTime() / 1000),
|
||||
string = '';
|
||||
if ($A.formatDate('Ymd') === $A.formatDate('Ymd', time)) {
|
||||
string = $A.formatDate('H:i', time)
|
||||
@ -157,10 +157,8 @@
|
||||
let time = Math.round(this.Date(date).getTime() / 1000) - nowTime;
|
||||
if (time < 86400 * 7 && time > 0 ) {
|
||||
return this.formatSeconds(time);
|
||||
} else if (time < 0) {
|
||||
} else if (time <= 0) {
|
||||
return '-' + this.formatSeconds(time * -1);
|
||||
} else if (time == 0) {
|
||||
return 0 + 's';
|
||||
}
|
||||
return this.formatTime(date)
|
||||
},
|
||||
|
@ -37,7 +37,7 @@
|
||||
<i class="taskfont"></i>
|
||||
</div>
|
||||
<Dropdown-menu slot="list" class="login-setting-menu">
|
||||
<Dropdown placement="right" @on-click="setTheme">
|
||||
<Dropdown placement="right-start" @on-click="setTheme">
|
||||
<DropdownItem>
|
||||
<div class="login-setting-item">
|
||||
{{$L('主题皮肤')}}
|
||||
@ -48,7 +48,7 @@
|
||||
<Dropdown-item v-for="(item, key) in themeList" :key="key" :name="item.value" :selected="themeMode === item.value">{{$L(item.name)}}</Dropdown-item>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
<Dropdown placement="right" @on-click="setLanguage">
|
||||
<Dropdown placement="right-start" @on-click="setLanguage">
|
||||
<DropdownItem divided>
|
||||
<div class="login-setting-item">
|
||||
{{currentLanguage}}
|
||||
@ -114,9 +114,6 @@ export default {
|
||||
this.subscribe = null;
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.loginType = 'login'
|
||||
},
|
||||
deactivated() {
|
||||
this.loginJump = false;
|
||||
this.password = "";
|
||||
|
@ -103,9 +103,7 @@
|
||||
<li @click="toggleRoute('dashboard')" :class="classNameRoute('dashboard')">
|
||||
<i class="taskfont"></i>
|
||||
<div class="menu-title">{{$L('仪表盘')}}</div>
|
||||
<Badge v-if="dashboardTask.overdue.length > 0" class="menu-badge" type="error" :count="dashboardTask.overdue.length"/>
|
||||
<Badge v-else-if="dashboardTask.today.length > 0" class="menu-badge" type="info" :count="dashboardTask.today.length"/>
|
||||
<Badge v-else-if="dashboardTask.all.length > 0" class="menu-badge" type="primary" :count="dashboardTask.all.length"/>
|
||||
<Badge class="menu-badge" :type="dashboardTask.overdue.length > 0 ? 'error' : 'primary'" :count="dashboardTotal"></Badge>
|
||||
</li>
|
||||
<li @click="toggleRoute('calendar')" :class="classNameRoute('calendar')">
|
||||
<i class="taskfont"></i>
|
||||
@ -114,7 +112,7 @@
|
||||
<li @click="toggleRoute('messenger')" :class="classNameRoute('messenger')">
|
||||
<i class="taskfont"></i>
|
||||
<div class="menu-title">{{$L('消息')}}</div>
|
||||
<Badge class="menu-badge" :count="msgAllUnread"/>
|
||||
<Badge class="menu-badge" :count="msgAllUnread"></Badge>
|
||||
</li>
|
||||
<li @click="toggleRoute('file')" :class="classNameRoute('file')">
|
||||
<i class="taskfont"></i>
|
||||
@ -258,15 +256,15 @@
|
||||
<!--任务详情-->
|
||||
<Modal
|
||||
:value="taskId > 0"
|
||||
:mask-closable="false"
|
||||
:styles="{
|
||||
width: '90%',
|
||||
maxWidth: taskData.dialog_id ? '1200px' : '700px'
|
||||
}"
|
||||
:mask-closable="false"
|
||||
:footer-hide="true"
|
||||
@on-visible-change="taskVisibleChange">
|
||||
@on-visible-change="taskVisibleChange"
|
||||
footer-hide>
|
||||
<div class="page-manage-task-modal" :style="taskStyle">
|
||||
<TaskDetail ref="taskDetail" :task-id="taskId" :open-task="taskData"/>
|
||||
<TaskDetail :task-id="taskId" :open-task="taskData"/>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@ -465,8 +463,12 @@ export default {
|
||||
return num;
|
||||
},
|
||||
|
||||
dashboardTotal() {
|
||||
return this.dashboardTask.today.length + this.dashboardTask.overdue.length
|
||||
},
|
||||
|
||||
unreadTotal() {
|
||||
return this.msgAllUnread + this.dashboardTask.overdue.length + this.reportUnreadNumber;
|
||||
return this.msgAllUnread + this.dashboardTotal + this.reportUnreadNumber;
|
||||
},
|
||||
|
||||
currentLanguage() {
|
||||
@ -785,13 +787,10 @@ export default {
|
||||
},
|
||||
|
||||
shortcutEvent(e) {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
if (e.keyCode === 75 || e.keyCode === 78) {
|
||||
if (e.keyCode === 75 || e.keyCode === 78) {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
this.onAddTask(0)
|
||||
} else if (e.keyCode === 83 && this.taskId > 0) {
|
||||
e.preventDefault();
|
||||
this.$refs.taskDetail.checkUpdate(true)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -46,7 +46,6 @@
|
||||
<div class="time" :title="msgData.created_at">{{$A.formatTime(msgData.created_at)}}</div>
|
||||
<Poptip
|
||||
v-if="msgData.send > 1 || dialogType == 'group'"
|
||||
ref="percent"
|
||||
class="percent"
|
||||
placement="left-end"
|
||||
transfer
|
||||
@ -135,13 +134,13 @@ export default {
|
||||
}
|
||||
this.msgData._r = true;
|
||||
//
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
if (!this.$el.offsetParent) {
|
||||
this.msgData._r = false;
|
||||
return
|
||||
}
|
||||
this.$store.dispatch("dialogMsgRead", this.msgData);
|
||||
}, 50)
|
||||
})
|
||||
},
|
||||
|
||||
popperShow() {
|
||||
@ -152,7 +151,6 @@ export default {
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.read_list = data;
|
||||
this.$refs.percent.updatePopper();
|
||||
}).catch(() => {
|
||||
this.read_list = [];
|
||||
});
|
||||
|
@ -238,7 +238,7 @@ export default {
|
||||
const {times} = this.addData;
|
||||
let temp = $A.date2string(times, "Y-m-d H:i");
|
||||
if (temp[0] && temp[1]) {
|
||||
let d = Math.ceil(($A.Date(temp[1], true) - $A.Date(temp[0], true)) / 86400);
|
||||
let d = Math.ceil(($A.Date(temp[1]).getTime() - $A.Date(temp[0]).getTime()) / 86400000);
|
||||
if (d > 0) {
|
||||
return d;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
<li v-if="ready && taskDetail.parent_id > 0">
|
||||
<div class="subtask-icon">
|
||||
<TaskMenu
|
||||
v-if="taskId > 0"
|
||||
:ref="`taskMenu_${taskDetail.id}`"
|
||||
:task="taskDetail"
|
||||
:load-status="taskDetail.loading === true"
|
||||
@ -73,7 +72,6 @@
|
||||
<div v-show="taskDetail.id > 0" class="task-info">
|
||||
<div class="head">
|
||||
<TaskMenu
|
||||
v-if="taskId > 0"
|
||||
:ref="`taskMenu_${taskDetail.id}`"
|
||||
:task="taskDetail"
|
||||
class="icon"
|
||||
@ -123,7 +121,6 @@
|
||||
</ETooltip>
|
||||
<div class="menu">
|
||||
<TaskMenu
|
||||
v-if="taskId > 0"
|
||||
:task="taskDetail"
|
||||
icon="ios-more"
|
||||
completed-icon="ios-more"
|
||||
@ -153,6 +150,7 @@
|
||||
:option-full="taskOptionFull"
|
||||
:placeholder="$L('详细描述...')"
|
||||
@on-blur="updateData('content')"
|
||||
@editorSave="updateData('content')"
|
||||
inline/>
|
||||
</div>
|
||||
<Form class="items" label-position="left" label-width="auto" @submit.native.prevent>
|
||||
@ -263,7 +261,7 @@
|
||||
<div @click="openTime" class="time">{{taskDetail.end_at ? cutTime : '--'}}</div>
|
||||
<template v-if="!taskDetail.complete_at && taskDetail.end_at">
|
||||
<Tag v-if="within24Hours(taskDetail.end_at)" color="blue"><i class="taskfont"></i>{{expiresFormat(taskDetail.end_at)}}</Tag>
|
||||
<Tag v-if="isOverdue(taskDetail)" color="red">{{$L('超期未完成')}}</Tag>
|
||||
<Tag v-if="taskDetail.overdue" color="red">{{$L('超期未完成')}}</Tag>
|
||||
</template>
|
||||
</div>
|
||||
</DatePicker>
|
||||
@ -309,13 +307,7 @@
|
||||
<i class="taskfont"></i>{{$L('子任务')}}
|
||||
</div>
|
||||
<ul class="item-content subtask">
|
||||
<TaskDetail
|
||||
v-for="(task, key) in subList"
|
||||
:ref="`subTask_${task.id}`"
|
||||
:key="key"
|
||||
:task-id="task.id"
|
||||
:open-task="task"
|
||||
:main-end-at="taskDetail.end_at"/>
|
||||
<TaskDetail v-for="(task, key) in subList" :key="key" :task-id="task.id" :open-task="task" :main-end-at="taskDetail.end_at"/>
|
||||
</ul>
|
||||
<ul :class="['item-content', subList.length === 0 ? 'nosub' : '']">
|
||||
<li>
|
||||
@ -624,8 +616,8 @@ export default {
|
||||
|
||||
cutTime() {
|
||||
const {taskDetail} = this;
|
||||
let start_at = $A.Date(taskDetail.start_at, true);
|
||||
let end_at = $A.Date(taskDetail.end_at, true);
|
||||
let start_at = Math.round($A.Date(taskDetail.start_at).getTime() / 1000);
|
||||
let end_at = Math.round($A.Date(taskDetail.end_at).getTime() / 1000);
|
||||
let string = "";
|
||||
if ($A.formatDate('Y/m/d', start_at) == $A.formatDate('Y/m/d', end_at)) {
|
||||
string = $A.formatDate('Y/m/d H:i', start_at) + " ~ " + $A.formatDate('H:i', end_at)
|
||||
@ -733,27 +725,29 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
initLanguage() {
|
||||
|
||||
},
|
||||
|
||||
innerHeightListener() {
|
||||
this.innerHeight = Math.min(1100, window.innerHeight);
|
||||
},
|
||||
|
||||
within24Hours(date) {
|
||||
return $A.Date(date, true) - this.nowTime < 86400
|
||||
return Math.round($A.Date(date).getTime() / 1000) - this.nowTime < 86400
|
||||
},
|
||||
|
||||
expiresFormat(date) {
|
||||
return $A.countDownFormat(date, this.nowTime)
|
||||
},
|
||||
|
||||
isOverdue(taskDetail) {
|
||||
if (taskDetail.overdue) {
|
||||
return true;
|
||||
}
|
||||
return $A.Date(taskDetail.end_at, true) < this.nowTime;
|
||||
},
|
||||
|
||||
onNameKeydown(e) {
|
||||
if (e.keyCode === 13) {
|
||||
if (e.keyCode === 83) {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
this.updateData('name');
|
||||
}
|
||||
} else if (e.keyCode === 13) {
|
||||
if (!e.shiftKey) {
|
||||
e.preventDefault();
|
||||
this.updateData('name');
|
||||
@ -761,40 +755,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
checkUpdate(update) {
|
||||
let isModify = false;
|
||||
if (this.openTask.name != this.taskDetail.name) {
|
||||
isModify = true;
|
||||
if (update) {
|
||||
this.updateData('name');
|
||||
} else if (isModify) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (this.$refs.desc && this.$refs.desc.getContent() != this.taskContent) {
|
||||
isModify = true;
|
||||
if (update) {
|
||||
this.updateData('content');
|
||||
} else if (isModify) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (this.addsubShow && this.addsubName) {
|
||||
isModify = true;
|
||||
if (update) {
|
||||
this.onAddsub();
|
||||
} else if (isModify) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
this.subList.some(({id}) => {
|
||||
if (this.$refs[`subTask_${id}`][0].checkUpdate(update)) {
|
||||
isModify = true;
|
||||
}
|
||||
})
|
||||
return isModify;
|
||||
},
|
||||
|
||||
updateData(action, params) {
|
||||
switch (action) {
|
||||
case 'priority':
|
||||
|
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
</div>
|
||||
</slot>
|
||||
<EDropdownMenu ref="dropdownMenu" slot="dropdown" class="task-menu-more-dropdown">
|
||||
<EDropdownMenu slot="dropdown" class="task-menu-more-dropdown">
|
||||
<li class="task-menu-more-warp" :class="size">
|
||||
<ul>
|
||||
<EDropdownItem v-if="!flow" class="load-flow" disabled>
|
||||
@ -218,9 +218,7 @@ export default {
|
||||
|
||||
visibleChange(visible) {
|
||||
if (visible) {
|
||||
this.$store.dispatch("getTaskFlow", this.task.id)
|
||||
.then(this.$refs.dropdownMenu.updatePopper)
|
||||
.catch(this.$refs.dropdownMenu.updatePopper)
|
||||
this.$store.dispatch("getTaskFlow", this.task.id).catch(() => {})
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -266,7 +266,7 @@ export default {
|
||||
},
|
||||
|
||||
completeAtFormat(date) {
|
||||
let time = $A.Date(date, true);
|
||||
let time = Math.round($A.Date(date).getTime() / 1000);
|
||||
if ($A.formatDate('Y') === $A.formatDate('Y', time)) {
|
||||
return $A.formatDate('m-d H:i', time)
|
||||
} else {
|
||||
|
@ -87,9 +87,9 @@
|
||||
<li
|
||||
v-for="item in fileList"
|
||||
:class="{
|
||||
shear: shearIds.includes(item.id),
|
||||
highlight: selectIds.includes(item.id),
|
||||
}"
|
||||
shear: shearIds.includes(item.id),
|
||||
highlight: selectIds.includes(item.id),
|
||||
}"
|
||||
@contextmenu.prevent.stop="handleRightClick($event, item)"
|
||||
@click="openFile(item)">
|
||||
<div class="file-check" :class="{'file-checked':selectIds.includes(item.id)}" @click.stop="dropFile(item, 'select')">
|
||||
@ -121,7 +121,7 @@
|
||||
size="small"
|
||||
:disabled="!!item._load"
|
||||
@on-blur="onBlur(item)"
|
||||
@on-keyup="onKeyup($event, item)"/>
|
||||
@on-enter="onEnter(item)"/>
|
||||
<div v-if="item._load" class="file-load"><Loading/></div>
|
||||
</div>
|
||||
<div v-else class="file-name" :title="item.name">{{formatName(item)}}</div>
|
||||
@ -959,6 +959,7 @@ export default {
|
||||
break;
|
||||
|
||||
case 'rename':
|
||||
this.$set(item, 'newname', item.name);
|
||||
this.setEdit(item.id, true)
|
||||
this.autoBlur(item.id)
|
||||
break;
|
||||
@ -1153,21 +1154,9 @@ export default {
|
||||
},
|
||||
|
||||
onBlur(item) {
|
||||
if (this.files.find(({id, _edit}) => id == item.id && !_edit)) {
|
||||
return;
|
||||
}
|
||||
this.onEnter(item);
|
||||
},
|
||||
|
||||
onKeyup(e, item) {
|
||||
if (e.keyCode === 13) {
|
||||
this.onEnter(item);
|
||||
} else if (e.keyCode === 27) {
|
||||
this.setLoad(item.id, false)
|
||||
this.setEdit(item.id, false)
|
||||
}
|
||||
},
|
||||
|
||||
onEnter(item) {
|
||||
let isCreate = !/^\d+$/.test(item.id);
|
||||
if (!item.newname) {
|
||||
@ -1215,9 +1204,6 @@ export default {
|
||||
let item = this.$store.state.files.find(({id}) => id == fileId)
|
||||
if (item) {
|
||||
this.$set(item, '_edit', is);
|
||||
if (is) {
|
||||
this.$set(item, 'newname', item.name);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
16
resources/assets/js/store/actions.js
vendored
16
resources/assets/js/store/actions.js
vendored
@ -74,12 +74,8 @@ export default {
|
||||
}
|
||||
}
|
||||
};
|
||||
params.error = (xhr, status) => {
|
||||
if (window.navigator.onLine === false || (status === 0 && xhr.readyState === 4)) {
|
||||
reject({data: {}, msg: $A.L('网络异常,请稍后再试!')})
|
||||
} else {
|
||||
reject({data: {}, msg: "System error"})
|
||||
}
|
||||
params.error = () => {
|
||||
reject({data: {}, msg: "System error"})
|
||||
};
|
||||
//
|
||||
if (params.websocket === true || params.ws === true) {
|
||||
@ -2050,7 +2046,7 @@ export default {
|
||||
}
|
||||
});
|
||||
state.wsReadWaitList = [];
|
||||
}, 50);
|
||||
}, 20);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2178,12 +2174,6 @@ export default {
|
||||
// 更新最后消息
|
||||
dispatch("updateDialogLastMsg", data);
|
||||
break;
|
||||
case 'readed':
|
||||
// 已读回执
|
||||
if (state.dialogMsgs.find(({id}) => id == data.id)) {
|
||||
dispatch("saveDialogMsg", data)
|
||||
}
|
||||
break;
|
||||
}
|
||||
})(msgDetail);
|
||||
break;
|
||||
|
@ -77,13 +77,6 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
pre {
|
||||
padding: 14px;
|
||||
margin: 7px 0;
|
||||
overflow: auto;
|
||||
background: #f5f2f0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
&[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
@ -163,13 +163,6 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
pre {
|
||||
padding: 14px;
|
||||
margin: 7px 0;
|
||||
overflow: auto;
|
||||
background: #f5f2f0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
&[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
@ -108,8 +108,8 @@
|
||||
padding: 8px;
|
||||
|
||||
.load-flow-warp {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,8 @@
|
||||
&:last-child {
|
||||
background-color: #98de6e;
|
||||
margin-right: 0;
|
||||
cursor: default;
|
||||
box-shadow: none;
|
||||
}
|
||||
.block-title {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
|
14
resources/assets/sass/pages/page-file.scss
vendored
14
resources/assets/sass/pages/page-file.scss
vendored
@ -485,7 +485,7 @@
|
||||
.file-upload-list {
|
||||
display: flex;
|
||||
width: 380px;
|
||||
padding: 14px 26px 14px 26px;
|
||||
padding: 14px 26px 14px 13px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ebeef5;
|
||||
position: fixed;
|
||||
@ -497,7 +497,8 @@
|
||||
overflow: hidden;
|
||||
.upload-wrap {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
margin-right: 8px;
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
@ -515,18 +516,16 @@
|
||||
.content {
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
margin: 12px 0 0;
|
||||
margin: 12px -16px 0 0;
|
||||
color: #606266;
|
||||
max-height: 500px;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
> li {
|
||||
list-style: none;
|
||||
padding: 4px 0;
|
||||
padding: 4px 16px 4px 0;
|
||||
position: relative;
|
||||
.file-name {
|
||||
line-height: 18px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
.file-error {
|
||||
font-size: 12px;
|
||||
@ -534,9 +533,8 @@
|
||||
}
|
||||
.file-close {
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
top: 7px;
|
||||
right: -1px;
|
||||
right: 0;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user