Compare commits

..

No commits in common. "master" and "v0.9.83" have entirely different histories.

55 changed files with 142 additions and 280 deletions

View File

@ -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(),
]
]);
}

View File

@ -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('&amp;', '&quot;', '&lt;', '&gt;'), array('&', '"', '<', '>'), $string);
$strcut = Base::utf8Substr($strcut, $length, $start);
$strcut = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
return $strcut . $dot;
} else {
$length = $length * 2;
if (strlen($string) <= $length) return $string;
$string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), 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('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
}
return $strcut . $dot;
}

View File

@ -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
View File

@ -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

View File

@ -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",

View File

@ -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

File diff suppressed because one or more lines are too long

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

File diff suppressed because one or more lines are too long

2
public/js/build/510.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* clipboard.js v2.0.8
* clipboard.js v2.0.10
* https://clipboardjs.com/
*
* Licensed MIT © Zeno Rocha

File diff suppressed because one or more lines are too long

View File

@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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 */

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* clipboard.js v2.0.8
* clipboard.js v2.0.10
* https://clipboardjs.com/
*
* Licensed MIT © Zeno Rocha

View File

@ -21,7 +21,6 @@ export default {
},
mounted() {
tocObj.reset()
this.init();
this.createEditor();
},

View File

@ -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();

View File

@ -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 + '">');
},

View File

@ -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) {

View File

@ -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)
},

View File

@ -37,7 +37,7 @@
<i class="taskfont">&#xe689;</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 = "";

View File

@ -103,9 +103,7 @@
<li @click="toggleRoute('dashboard')" :class="classNameRoute('dashboard')">
<i class="taskfont">&#xe6fb;</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">&#xe6f5;</i>
@ -114,7 +112,7 @@
<li @click="toggleRoute('messenger')" :class="classNameRoute('messenger')">
<i class="taskfont">&#xe6eb;</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">&#xe6f3;</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)
}
}
},

View File

@ -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 = [];
});

View File

@ -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;
}

View File

@ -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">&#xe71d;</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">&#xe6f0;</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':

View File

@ -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(() => {})
}
},

View File

@ -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 {

View File

@ -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);
}
}
},

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -108,8 +108,8 @@
padding: 8px;
.load-flow-warp {
width: 18px;
height: 18px;
width: 20px;
height: 20px;
}
}
}

View File

@ -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);

View File

@ -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;
}