Merge branch 'develop' of ssh://git.gezi.vip:6006/gx/dootask
# Conflicts: # electron/package.json # package.json # public/css/app.css # public/js/app.js # public/js/build/189.js.LICENSE.txt # public/js/build/206.js # public/js/build/400.js.LICENSE.txt # public/js/build/486.js # public/js/build/496.js.LICENSE.txt # public/js/build/528.js # public/js/build/535.js # public/js/build/535.js.LICENSE.txt # public/js/build/578.js # public/js/build/78.js.LICENSE.txt # public/js/build/817.js # public/js/build/856.js # public/js/build/862.js # public/js/build/889.js # public/js/build/91.js.LICENSE.txt # public/js/build/954.js # public/js/build/956.js # resources/assets/js/pages/manage/components/TaskDetail.vue # resources/assets/js/pages/manage/dashboard.vue # resources/assets/sass/pages/common.scss # resources/assets/sass/pages/page-dashboard.scss
@ -155,6 +155,12 @@ class DialogController extends AbstractController
|
|||||||
$user->task_dialog_id = $dialog->id;
|
$user->task_dialog_id = $dialog->id;
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
//去掉标记未读
|
||||||
|
$isMarkDialogUser = WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($user->userid)->whereIsMarkUnread(1)->first();
|
||||||
|
if ($isMarkDialogUser) {
|
||||||
|
$isMarkDialogUser->is_mark_unread = 0;
|
||||||
|
$isMarkDialogUser->save();
|
||||||
|
}
|
||||||
//
|
//
|
||||||
$data = $list->toArray();
|
$data = $list->toArray();
|
||||||
if ($list->currentPage() === 1) {
|
if ($list->currentPage() === 1) {
|
||||||
@ -490,4 +496,48 @@ class DialogController extends AbstractController
|
|||||||
'top_at' => $dialogUser->top_at?->toDateTimeString(),
|
'top_at' => $dialogUser->top_at?->toDateTimeString(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/dialog/msg/mark 13. 消息标记操作
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup dialog
|
||||||
|
* @apiName msg__mark
|
||||||
|
*
|
||||||
|
* @apiParam {Number} dialog_id 消息ID
|
||||||
|
* @apiParam {String} type 类型
|
||||||
|
* - read
|
||||||
|
* - unread
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function msg__mark()
|
||||||
|
{
|
||||||
|
$user = User::auth();
|
||||||
|
$dialogId = intval(Request::input('dialog_id'));
|
||||||
|
$type = Request::input('type');
|
||||||
|
$dialogUser = WebSocketDialogUser::whereUserid($user->userid)->whereDialogId($dialogId)->first();
|
||||||
|
if (!$dialogUser) {
|
||||||
|
return Base::retError("会话不存在");
|
||||||
|
}
|
||||||
|
if ($type == 'read') {
|
||||||
|
WebSocketDialogMsgRead::whereUserid($user->userid)
|
||||||
|
->whereReadAt(null)
|
||||||
|
->whereDialogId($dialogId)
|
||||||
|
->update(
|
||||||
|
[
|
||||||
|
'read_at' => Carbon::now()
|
||||||
|
]);
|
||||||
|
$dialogUser->is_mark_unread = 0;
|
||||||
|
$dialogUser->save();
|
||||||
|
} elseif ($type == 'unread') {
|
||||||
|
$dialogUser->is_mark_unread = 1;
|
||||||
|
$dialogUser->save();
|
||||||
|
}
|
||||||
|
return Base::retSuccess("success");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,7 @@ use App\Models\ProjectInvite;
|
|||||||
use App\Models\ProjectLog;
|
use App\Models\ProjectLog;
|
||||||
use App\Models\ProjectTask;
|
use App\Models\ProjectTask;
|
||||||
use App\Models\ProjectTaskFile;
|
use App\Models\ProjectTaskFile;
|
||||||
|
use App\Models\ProjectTaskFlowChange;
|
||||||
use App\Models\ProjectUser;
|
use App\Models\ProjectUser;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
@ -915,6 +916,7 @@ class ProjectController extends AbstractController
|
|||||||
$time_before = Request::input('time_before');
|
$time_before = Request::input('time_before');
|
||||||
$complete = Request::input('complete', 'all');
|
$complete = Request::input('complete', 'all');
|
||||||
$archived = Request::input('archived', 'no');
|
$archived = Request::input('archived', 'no');
|
||||||
|
$deleted = Request::input('deleted');
|
||||||
$keys = Request::input('keys');
|
$keys = Request::input('keys');
|
||||||
$sorts = Request::input('sorts');
|
$sorts = Request::input('sorts');
|
||||||
$keys = is_array($keys) ? $keys : [];
|
$keys = is_array($keys) ? $keys : [];
|
||||||
@ -953,7 +955,7 @@ class ProjectController extends AbstractController
|
|||||||
$builder->whereNotNull('project_tasks.end_at')->where('project_tasks.end_at', '<', Carbon::parse($time_before));
|
$builder->whereNotNull('project_tasks.end_at')->where('project_tasks.end_at', '<', Carbon::parse($time_before));
|
||||||
} elseif (is_array($time)) {
|
} elseif (is_array($time)) {
|
||||||
if (Base::isDateOrTime($time[0]) && Base::isDateOrTime($time[1])) {
|
if (Base::isDateOrTime($time[0]) && Base::isDateOrTime($time[1])) {
|
||||||
$builder->betweenTime(Carbon::parse($time[0])->startOfDay(), Carbon::parse($time[1])->endOfDay());
|
$builder->betweenTime(Carbon::parse($time[0])->startOfDay(), Carbon::parse($time[1])->endOfDay(),'taskTime');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -969,6 +971,10 @@ class ProjectController extends AbstractController
|
|||||||
$builder->whereNull('project_tasks.archived_at');
|
$builder->whereNull('project_tasks.archived_at');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
if ($deleted == 'yes') {
|
||||||
|
$builder->onlyTrashed();
|
||||||
|
}
|
||||||
|
//
|
||||||
foreach ($sorts as $column => $direction) {
|
foreach ($sorts as $column => $direction) {
|
||||||
if (!in_array($column, ['complete_at', 'archived_at', 'end_at'])) continue;
|
if (!in_array($column, ['complete_at', 'archived_at', 'end_at'])) continue;
|
||||||
if (!in_array($direction, ['asc', 'desc'])) continue;
|
if (!in_array($direction, ['asc', 'desc'])) continue;
|
||||||
@ -1013,56 +1019,111 @@ class ProjectController extends AbstractController
|
|||||||
if (Carbon::parse($time[1])->timestamp - Carbon::parse($time[0])->timestamp > 90 * 86400) {
|
if (Carbon::parse($time[1])->timestamp - Carbon::parse($time[0])->timestamp > 90 * 86400) {
|
||||||
return Base::retError('时间范围限制最大90天');
|
return Base::retError('时间范围限制最大90天');
|
||||||
}
|
}
|
||||||
//
|
$type = Request::input('type','taskTime');
|
||||||
$headings = [];
|
$headings = [];
|
||||||
$headings[] = '任务ID';
|
$headings[] = '任务ID';
|
||||||
|
$headings[] = '父级任务ID';
|
||||||
|
$headings[] = '所属项目';
|
||||||
$headings[] = '任务标题';
|
$headings[] = '任务标题';
|
||||||
$headings[] = '负责人';
|
|
||||||
$headings[] = '创建人';
|
|
||||||
$headings[] = '是否完成';
|
|
||||||
$headings[] = '完成时间';
|
|
||||||
$headings[] = '是否归档';
|
|
||||||
$headings[] = '归档时间';
|
|
||||||
$headings[] = '任务开始时间';
|
$headings[] = '任务开始时间';
|
||||||
$headings[] = '任务结束时间';
|
$headings[] = '任务结束时间';
|
||||||
$headings[] = '结束剩余';
|
$headings[] = '完成时间';
|
||||||
$headings[] = '所属项目';
|
$headings[] = '归档时间';
|
||||||
$headings[] = '父级任务ID';
|
$headings[] = '任务计划用时';
|
||||||
|
$headings[] = '实际完成用时';
|
||||||
|
$headings[] = '超时时间';
|
||||||
|
$headings[] = '开发用时';
|
||||||
|
$headings[] = '验收/测试用时';
|
||||||
|
$headings[] = '负责人';
|
||||||
|
$headings[] = '创建人';
|
||||||
$datas = [];
|
$datas = [];
|
||||||
//
|
//
|
||||||
$builder = ProjectTask::select(['project_tasks.*', 'project_task_users.userid as ownerid'])
|
$builder = ProjectTask::select(['project_tasks.*', 'project_task_users.userid as ownerid'])
|
||||||
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_id')
|
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_id')
|
||||||
->where('project_task_users.owner', 1)
|
->where('project_task_users.owner', 1)
|
||||||
->whereIn('project_task_users.userid', $userid)
|
->whereIn('project_task_users.userid', $userid)
|
||||||
->betweenTime(Carbon::parse($time[0])->startOfDay(), Carbon::parse($time[1])->endOfDay());
|
->betweenTime(Carbon::parse($time[0])->startOfDay(), Carbon::parse($time[1])->endOfDay(),$type);
|
||||||
$builder->orderByDesc('project_tasks.id')->chunk(100, function($tasks) use (&$datas) {
|
$builder->orderByDesc('project_tasks.id')->chunk(100, function($tasks) use (&$datas) {
|
||||||
/** @var ProjectTask $task */
|
/** @var ProjectTask $task */
|
||||||
foreach ($tasks as $task) {
|
foreach ($tasks as $task) {
|
||||||
|
$flowChanges = ProjectTaskFlowChange::whereTaskId($task->id)->get();
|
||||||
|
$developTime = 0;//开发时间
|
||||||
|
$testTime = 0;//验收/测试时间
|
||||||
|
foreach ($flowChanges as $change) {
|
||||||
|
if (strpos($change->before_flow_item_name, 'end') === false) {
|
||||||
|
$upOne = ProjectTaskFlowChange::where('id', '<', $change->id)->whereTaskId($task->id)->orderByDesc('id')->first();
|
||||||
|
if ($upOne) {
|
||||||
|
if (strpos($change->before_flow_item_name, 'progress') !== false && strpos($change->before_flow_item_name, '进行') !== false) {
|
||||||
|
$devCtime = Carbon::parse($change->created_at)->timestamp;
|
||||||
|
$oCtime = Carbon::parse($upOne->created_at)->timestamp;
|
||||||
|
$minusNum = $devCtime - $oCtime;
|
||||||
|
$developTime += $minusNum;
|
||||||
|
}
|
||||||
|
if (strpos($change->before_flow_item_name, 'test') !== false || strpos($change->before_flow_item_name, '测试') !== false || strpos($change->before_flow_item_name, '验收') !== false) {
|
||||||
|
$testCtime = Carbon::parse($change->created_at)->timestamp;
|
||||||
|
$tTime = Carbon::parse($upOne->created_at)->timestamp;
|
||||||
|
$tMinusNum = $testCtime - $tTime;
|
||||||
|
$testTime += $tMinusNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$task->complete_at) {
|
||||||
|
$lastChange = ProjectTaskFlowChange::whereTaskId($task->id)->orderByDesc('id')->first();
|
||||||
|
$nowTime = time();
|
||||||
|
$unFinishTime = $nowTime - Carbon::parse($lastChange->created_at)->timestamp;
|
||||||
|
if (strpos($lastChange->after_flow_item_name, 'progress') !== false || strpos($lastChange->after_flow_item_name, '进行') !== false) {
|
||||||
|
$developTime += $unFinishTime;
|
||||||
|
} elseif (strpos($lastChange->after_flow_item_name, 'test') !== false || strpos($lastChange->after_flow_item_name, '测试') !== false || strpos($lastChange->after_flow_item_name, '验收') !== false) {
|
||||||
|
$testTime += $unFinishTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$firstChange = ProjectTaskFlowChange::whereTaskId($task->id)->orderBy('id')->first();
|
||||||
|
if (strpos($firstChange->after_flow_item_name, 'end') !== false) {
|
||||||
|
$firstDevTime = Carbon::parse($firstChange->created_at)->timestamp - Carbon::parse($task->created_at)->timestamp;
|
||||||
|
$developTime += $firstDevTime;
|
||||||
|
}
|
||||||
|
if (count($flowChanges) === 0 && $task->start_at) {
|
||||||
|
$lastTime = $task->complete_at ? Carbon::parse($task->complete_at)->timestamp : time();
|
||||||
|
$developTime = $lastTime - Carbon::parse($task->start_at)->timestamp;
|
||||||
|
}
|
||||||
|
$totalTime = $developTime + $testTime; //任务总用时
|
||||||
if ($task->complete_at) {
|
if ($task->complete_at) {
|
||||||
$a = Carbon::parse($task->complete_at)->timestamp;
|
$a = Carbon::parse($task->complete_at)->timestamp;
|
||||||
$b = Carbon::parse($task->end_at)->timestamp;
|
if ($task->start_at) {
|
||||||
if ($b > $a) {
|
$b = Carbon::parse($task->start_at)->timestamp;
|
||||||
$endSurplus = Base::timeDiff($a, $b);
|
$totalTime = $a - $b;
|
||||||
} else {
|
|
||||||
$endSurplus = "-" . Base::timeDiff($b, $a);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$endSurplus = '-';
|
|
||||||
}
|
}
|
||||||
|
$planTime = '-';//任务计划用时
|
||||||
|
$overTime = '-';//超时时间
|
||||||
|
if ($task->end_at) {
|
||||||
|
$startTime = Carbon::parse($task->start_at)->timestamp;
|
||||||
|
$endTime = Carbon::parse($task->end_at)->timestamp;
|
||||||
|
$planTotalTime = $endTime - $startTime;
|
||||||
|
$residueTime = $planTotalTime - $totalTime;
|
||||||
|
if ($residueTime < 0) {
|
||||||
|
$overTime = Base::timeFormat(abs($residueTime));
|
||||||
|
}
|
||||||
|
$planTime = Base::timeDiff($startTime, $endTime);
|
||||||
|
}
|
||||||
|
$actualTime = $task->complete_at ? $totalTime : 0;//实际完成用时
|
||||||
$datas[] = [
|
$datas[] = [
|
||||||
$task->id,
|
$task->id,
|
||||||
|
$task->parent_id ?: '-',
|
||||||
|
Base::filterEmoji($task->project?->name) ?: '-',
|
||||||
Base::filterEmoji($task->name),
|
Base::filterEmoji($task->name),
|
||||||
Base::filterEmoji(User::userid2nickname($task->ownerid)) . " (ID: {$task->ownerid})",
|
|
||||||
Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})",
|
|
||||||
$task->complete_at ? '已完成' : '-',
|
|
||||||
$task->complete_at ?: '-',
|
|
||||||
$task->archived_at ? '已归档' : '-',
|
|
||||||
$task->archived_at ?: '-',
|
|
||||||
$task->start_at ?: '-',
|
$task->start_at ?: '-',
|
||||||
$task->end_at ?: '-',
|
$task->end_at ?: '-',
|
||||||
$endSurplus,
|
$task->complete_at ?: '-',
|
||||||
Base::filterEmoji($task->project?->name) ?: '-',
|
$task->archived_at ?: '-',
|
||||||
$task->parent_id ?: '-',
|
$planTime ?: '-',
|
||||||
|
$actualTime ? Base::timeFormat($actualTime) : '-',
|
||||||
|
$overTime,
|
||||||
|
$developTime > 0? Base::timeFormat($developTime) : '-',
|
||||||
|
$testTime > 0 ? Base::timeFormat($testTime) : '-',
|
||||||
|
Base::filterEmoji(User::userid2nickname($task->ownerid)) . " (ID: {$task->ownerid})",
|
||||||
|
Base::filterEmoji(User::userid2nickname($task->userid)) . " (ID: {$task->userid})",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1471,6 +1532,9 @@ class ProjectController extends AbstractController
|
|||||||
$task_id = intval($data['task_id']);
|
$task_id = intval($data['task_id']);
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id, true, 2);
|
$task = ProjectTask::userTask($task_id, true, 2);
|
||||||
|
if ($task->deleted_at) {
|
||||||
|
throw new ApiException('任务已删除');
|
||||||
|
}
|
||||||
// 更新任务
|
// 更新任务
|
||||||
$updateMarking = [];
|
$updateMarking = [];
|
||||||
$task->updateTask($data, $updateMarking);
|
$task->updateTask($data, $updateMarking);
|
||||||
@ -1590,8 +1654,21 @@ class ProjectController extends AbstractController
|
|||||||
User::auth();
|
User::auth();
|
||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
|
$type = Request::input('type');
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id, null, true);
|
$task = ProjectTask::userTask($task_id, null, true);
|
||||||
|
if($type == 'recovery'){
|
||||||
|
$task->deleted_at = null;
|
||||||
|
$task->deleted_userid = 0;
|
||||||
|
$task->save();
|
||||||
|
return Base::retSuccess('操作成功', ['id' => $task->id]);
|
||||||
|
}
|
||||||
|
if($type == 'completely_delete'){
|
||||||
|
$task->forceDelete();
|
||||||
|
return Base::retSuccess('彻底删除成功', ['id' => $task->id]);
|
||||||
|
}
|
||||||
|
$task->deleted_userid = User::userid();
|
||||||
|
$task->save();
|
||||||
//
|
//
|
||||||
$task->deleteTask();
|
$task->deleteTask();
|
||||||
return Base::retSuccess('删除成功', ['id' => $task->id]);
|
return Base::retSuccess('删除成功', ['id' => $task->id]);
|
||||||
|
|||||||
@ -41,7 +41,7 @@ class SystemController extends AbstractController
|
|||||||
User::auth('admin');
|
User::auth('admin');
|
||||||
$all = Request::input();
|
$all = Request::input();
|
||||||
foreach ($all AS $key => $value) {
|
foreach ($all AS $key => $value) {
|
||||||
if (!in_array($key, ['reg', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_nickname', 'auto_archived', 'archived_day'])) {
|
if (!in_array($key, ['reg', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_nickname', 'auto_archived', 'archived_day', 'start_home', 'home_footer'])) {
|
||||||
unset($all[$key]);
|
unset($all[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,6 +72,7 @@ class SystemController extends AbstractController
|
|||||||
$setting['chat_nickname'] = $setting['chat_nickname'] ?: 'optional';
|
$setting['chat_nickname'] = $setting['chat_nickname'] ?: 'optional';
|
||||||
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
|
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
|
||||||
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
|
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
|
||||||
|
$setting['start_home'] = $setting['start_home'] ?: 'close';
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
||||||
}
|
}
|
||||||
@ -478,4 +479,79 @@ class SystemController extends AbstractController
|
|||||||
//
|
//
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/system/get/starthome 13. 启动首页设置信息
|
||||||
|
*
|
||||||
|
* @apiDescription 用于判断注册是否需要启动首页
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup system
|
||||||
|
* @apiName get__starthome
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function get__starthome()
|
||||||
|
{
|
||||||
|
return Base::retSuccess('success', [
|
||||||
|
'need_start' => Base::settingFind('system', 'start_home') == 'open',
|
||||||
|
'home_footer' => Base::settingFind('system', 'home_footer')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/system/emailSetting 14. 获取邮箱设置、保存邮箱设置
|
||||||
|
*
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup system
|
||||||
|
* @apiName emailSetting
|
||||||
|
*
|
||||||
|
* @apiParam {String} type
|
||||||
|
* - get: 获取(默认)
|
||||||
|
* - all: 获取所有(需要管理员权限)
|
||||||
|
* - save: 保存设置(参数:smtp_server port account password reg_verify notice task_remind_hours task_remind_hours2)
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function emailSetting()
|
||||||
|
{
|
||||||
|
$type = trim(Request::input('type'));
|
||||||
|
if ($type == 'save') {
|
||||||
|
if (env("SYSTEM_SETTING") == 'disabled') {
|
||||||
|
return Base::retError('当前环境禁止修改');
|
||||||
|
}
|
||||||
|
User::auth('admin');
|
||||||
|
$all = Request::input();
|
||||||
|
foreach ($all as $key => $value) {
|
||||||
|
if (!in_array($key, ['smtp_server', 'port', 'account', 'password', 'reg_verify', 'notice', 'task_remind_hours', 'task_remind_hours2'])) {
|
||||||
|
unset($all[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$setting = Base::setting('emailSetting', Base::newTrim($all));
|
||||||
|
} else {
|
||||||
|
$setting = Base::setting('emailSetting');
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if ($type == 'all' || $type == 'save') {
|
||||||
|
User::auth('admin');
|
||||||
|
$setting['reg_invite'] = $setting['reg_invite'] ?: Base::generatePassword(8);
|
||||||
|
} else {
|
||||||
|
if (isset($setting['reg_invite'])) unset($setting['reg_invite']);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
$setting['smtp_server'] = $setting['smtp_server'] ?: '';
|
||||||
|
$setting['port'] = $setting['port'] ?: '';
|
||||||
|
$setting['account'] = $setting['account'] ?: '';
|
||||||
|
$setting['password'] = $setting['password'] ?: '';
|
||||||
|
$setting['reg_verify'] = $setting['reg_verify'] ?: 'close';
|
||||||
|
$setting['notice'] = $setting['notice'] ?: 'open';
|
||||||
|
$setting['task_remind_hours'] = floatval($setting['task_remind_hours']) ?: 0;
|
||||||
|
$setting['task_remind_hours2'] = floatval($setting['task_remind_hours2']) ?: 0;
|
||||||
|
//
|
||||||
|
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,14 @@
|
|||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\UserEmailVerification;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use Arr;
|
use Arr;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Captcha;
|
use Captcha;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Request;
|
use Request;
|
||||||
|
use Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine users
|
* @apiDefine users
|
||||||
@ -42,6 +44,7 @@ class UsersController extends AbstractController
|
|||||||
$type = trim(Request::input('type'));
|
$type = trim(Request::input('type'));
|
||||||
$email = trim(Request::input('email'));
|
$email = trim(Request::input('email'));
|
||||||
$password = trim(Request::input('password'));
|
$password = trim(Request::input('password'));
|
||||||
|
$isRegVerify = Base::settingFind('emailSetting', 'reg_verify') === 'open' ? true : false;
|
||||||
if ($type == 'reg') {
|
if ($type == 'reg') {
|
||||||
$setting = Base::setting('system');
|
$setting = Base::setting('system');
|
||||||
if ($setting['reg'] == 'close') {
|
if ($setting['reg'] == 'close') {
|
||||||
@ -53,6 +56,10 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$user = User::reg($email, $password);
|
$user = User::reg($email, $password);
|
||||||
|
if ($isRegVerify) {
|
||||||
|
UserEmailVerification::userEmailSend($user);
|
||||||
|
return Base::retError('注册成功,请验证邮箱后登录', ['code' => 1000]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$needCode = !Base::isError(User::needCode($email));
|
$needCode = !Base::isError(User::needCode($email));
|
||||||
if ($needCode) {
|
if ($needCode) {
|
||||||
@ -73,16 +80,20 @@ class UsersController extends AbstractController
|
|||||||
};
|
};
|
||||||
$user = User::whereEmail($email)->first();
|
$user = User::whereEmail($email)->first();
|
||||||
if (empty($user)) {
|
if (empty($user)) {
|
||||||
return $retError('账号或密码错误');
|
return $retError('账号不存在,请确认账号是否输入正确');
|
||||||
}
|
}
|
||||||
if ($user->password != Base::md52($password, $user->encrypt)) {
|
if ($user->password != Base::md52($password, $user->encrypt)) {
|
||||||
return $retError('账号或密码错误');
|
return $retError('密码错误,请输入正确密码');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (in_array('disable', $user->identity)) {
|
if (in_array('disable', $user->identity)) {
|
||||||
return $retError('帐号已停用...');
|
return $retError('帐号已停用...');
|
||||||
}
|
}
|
||||||
Cache::forget("code::" . $email);
|
Cache::forget("code::" . $email);
|
||||||
|
if ($isRegVerify && $user->is_email_verity === 0) {
|
||||||
|
UserEmailVerification::userEmailSend($user);
|
||||||
|
return $retError('请验证邮箱后再登录');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$array = [
|
$array = [
|
||||||
@ -559,4 +570,53 @@ class UsersController extends AbstractController
|
|||||||
//
|
//
|
||||||
return Base::retSuccess('修改成功', $userInfo);
|
return Base::retSuccess('修改成功', $userInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/users/email/verification 13. 邮箱验证
|
||||||
|
*
|
||||||
|
* @apiDescription 不需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup users
|
||||||
|
* @apiName email__verification
|
||||||
|
*
|
||||||
|
* @apiParam {String} code 验证参数
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据(同"获取我的信息"接口)
|
||||||
|
*/
|
||||||
|
public function email__verification()
|
||||||
|
{
|
||||||
|
$data = Request::input();
|
||||||
|
// 表单验证
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
"code" => ["required"],
|
||||||
|
], [
|
||||||
|
"code.required" => "required字段非法",
|
||||||
|
]);
|
||||||
|
if ($validator->fails())
|
||||||
|
return Base::retError($validator->errors()->first());
|
||||||
|
$res = UserEmailVerification::where('code', $data['code'])->first();
|
||||||
|
if (empty($res)) {
|
||||||
|
return Base::retError('无效连接,请重新注册');
|
||||||
|
}
|
||||||
|
// 如果已经校验过
|
||||||
|
if (intval($res->status) === 1)
|
||||||
|
return Base::retError('链接已经使用过',['code' => 2]);
|
||||||
|
|
||||||
|
$oldTime = strtotime($res->created_at);
|
||||||
|
$time = time();
|
||||||
|
//24个小时失效
|
||||||
|
if (abs($time - $oldTime) > 86400) {
|
||||||
|
return Base::retError("链接已失效,请重新登录/注册");
|
||||||
|
}
|
||||||
|
UserEmailVerification::where('code', $data['code'])
|
||||||
|
->update([
|
||||||
|
'status' => 1
|
||||||
|
]);
|
||||||
|
User::where('userid', $res->userid)->update([
|
||||||
|
'is_email_verity' => 1
|
||||||
|
]);
|
||||||
|
return Base::retSuccess('绑定邮箱成功');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
|||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Tasks\AutoArchivedTask;
|
use App\Tasks\AutoArchivedTask;
|
||||||
use App\Tasks\DeleteTmpTask;
|
use App\Tasks\DeleteTmpTask;
|
||||||
|
use App\Tasks\OverdueRemindEmailTask;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Redirect;
|
use Redirect;
|
||||||
|
|
||||||
@ -61,6 +62,8 @@ class IndexController extends InvokeController
|
|||||||
Task::deliver(new DeleteTmpTask('tmp', 24));
|
Task::deliver(new DeleteTmpTask('tmp', 24));
|
||||||
// 自动归档任务
|
// 自动归档任务
|
||||||
Task::deliver(new AutoArchivedTask());
|
Task::deliver(new AutoArchivedTask());
|
||||||
|
// 任务到期邮件提醒
|
||||||
|
Task::deliver(new OverdueRemindEmailTask());
|
||||||
|
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -376,6 +376,7 @@ class Project extends AbstractModel
|
|||||||
$idc = [];
|
$idc = [];
|
||||||
$hasStart = false;
|
$hasStart = false;
|
||||||
$hasEnd = false;
|
$hasEnd = false;
|
||||||
|
$testNum = 0;
|
||||||
$upTaskList = [];
|
$upTaskList = [];
|
||||||
foreach ($flows as $item) {
|
foreach ($flows as $item) {
|
||||||
$id = intval($item['id']);
|
$id = intval($item['id']);
|
||||||
@ -416,6 +417,9 @@ class Project extends AbstractModel
|
|||||||
if ($flow->status == 'end') {
|
if ($flow->status == 'end') {
|
||||||
$hasEnd = true;
|
$hasEnd = true;
|
||||||
}
|
}
|
||||||
|
if ($flow->status == 'test') {
|
||||||
|
$testNum++;
|
||||||
|
}
|
||||||
if (!$isInsert) {
|
if (!$isInsert) {
|
||||||
$upTaskList[$flow->id] = $flow->status . "|" . $flow->name;
|
$upTaskList[$flow->id] = $flow->status . "|" . $flow->name;
|
||||||
}
|
}
|
||||||
@ -424,6 +428,9 @@ class Project extends AbstractModel
|
|||||||
if (!$hasStart) {
|
if (!$hasStart) {
|
||||||
throw new ApiException('至少需要1个开始状态');
|
throw new ApiException('至少需要1个开始状态');
|
||||||
}
|
}
|
||||||
|
if($testNum > 1){
|
||||||
|
throw new ApiException('验收/测试状态只能有1个');
|
||||||
|
}
|
||||||
if (!$hasEnd) {
|
if (!$hasEnd) {
|
||||||
throw new ApiException('至少需要1个结束状态');
|
throw new ApiException('至少需要1个结束状态');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,12 @@ use App\Module\Base;
|
|||||||
use App\Tasks\PushTask;
|
use App\Tasks\PushTask;
|
||||||
use Arr;
|
use Arr;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Config;
|
||||||
use DB;
|
use DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Mail;
|
||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +42,7 @@ use Request;
|
|||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||||
|
* @property int|null $deleted_userid 删除会员
|
||||||
* @property-read \App\Models\ProjectTaskContent|null $content
|
* @property-read \App\Models\ProjectTaskContent|null $content
|
||||||
* @property-read int $file_num
|
* @property-read int $file_num
|
||||||
* @property-read int $msg_num
|
* @property-read int $msg_num
|
||||||
@ -58,7 +61,7 @@ use Request;
|
|||||||
* @property-read int|null $task_user_count
|
* @property-read int|null $task_user_count
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask allData($userid = null)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask allData($userid = null)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask authData($userid = null, $owner = null)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask authData($userid = null, $owner = null)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask betweenTime($start, $end)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask betweenTime($start, $end, $type)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
||||||
* @method static \Illuminate\Database\Query\Builder|ProjectTask onlyTrashed()
|
* @method static \Illuminate\Database\Query\Builder|ProjectTask onlyTrashed()
|
||||||
@ -71,6 +74,7 @@ use Request;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCompleteAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCompleteAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDeletedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDeletedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDeletedUserid($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDesc($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDesc($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDialogId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDialogId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereEndAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereEndAt($value)
|
||||||
@ -312,11 +316,13 @@ class ProjectTask extends AbstractModel
|
|||||||
* @param $query
|
* @param $query
|
||||||
* @param $start
|
* @param $start
|
||||||
* @param $end
|
* @param $end
|
||||||
|
* @param $type
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function scopeBetweenTime($query, $start, $end)
|
public function scopeBetweenTime($query, $start, $end, $type)
|
||||||
{
|
{
|
||||||
$query->where(function ($q1) use ($start, $end) {
|
$query->where(function ($q1) use ($start, $end, $type) {
|
||||||
|
if ($type === 'taskTime') {
|
||||||
$q1->where(function ($q2) use ($start) {
|
$q1->where(function ($q2) use ($start) {
|
||||||
$q2->where('project_tasks.start_at', '<=', $start)->where('project_tasks.end_at', '>=', $start);
|
$q2->where('project_tasks.start_at', '<=', $start)->where('project_tasks.end_at', '>=', $start);
|
||||||
})->orWhere(function ($q2) use ($end) {
|
})->orWhere(function ($q2) use ($end) {
|
||||||
@ -324,6 +330,15 @@ class ProjectTask extends AbstractModel
|
|||||||
})->orWhere(function ($q2) use ($start, $end) {
|
})->orWhere(function ($q2) use ($start, $end) {
|
||||||
$q2->where('project_tasks.start_at', '>', $start)->where('project_tasks.end_at', '<', $end);
|
$q2->where('project_tasks.start_at', '>', $start)->where('project_tasks.end_at', '<', $end);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
$q1->where(function ($q2) use ($start) {
|
||||||
|
$q2->where('project_tasks.created_at', '>=', $start);
|
||||||
|
})->orWhere(function ($q2) use ($end) {
|
||||||
|
$q2->where('project_tasks.created_at', '<=', $end);
|
||||||
|
})->orWhere(function ($q2) use ($start, $end) {
|
||||||
|
$q2->where('project_tasks.created_at', '>', $start)->where('project_tasks.created_at', '<', $end);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
@ -742,6 +757,9 @@ class ProjectTask extends AbstractModel
|
|||||||
$this->addLog("修改{任务}时间", [
|
$this->addLog("修改{任务}时间", [
|
||||||
'change' => [$oldStringAt, $newStringAt]
|
'change' => [$oldStringAt, $newStringAt]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
//修改计划时间需要重置任务邮件提醒日志
|
||||||
|
ProjectTaskMailLog::whereTaskId($this->id)->delete();
|
||||||
}
|
}
|
||||||
// 以下紧顶级任务可修改
|
// 以下紧顶级任务可修改
|
||||||
if ($this->parent_id === 0) {
|
if ($this->parent_id === 0) {
|
||||||
@ -1179,6 +1197,7 @@ class ProjectTask extends AbstractModel
|
|||||||
public static function userTask($task_id, $archived = true, $permission = 0, $with = [])
|
public static function userTask($task_id, $archived = true, $permission = 0, $with = [])
|
||||||
{
|
{
|
||||||
$task = self::with($with)->allData()->where("project_tasks.id", intval($task_id))->first();
|
$task = self::with($with)->allData()->where("project_tasks.id", intval($task_id))->first();
|
||||||
|
$task = $task ?: ProjectTask::where("project_tasks.id", intval($task_id))->onlyTrashed()->first();
|
||||||
//
|
//
|
||||||
if (empty($task)) {
|
if (empty($task)) {
|
||||||
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
||||||
@ -1211,4 +1230,58 @@ class ProjectTask extends AbstractModel
|
|||||||
//
|
//
|
||||||
return $task;
|
return $task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预超期任务提醒
|
||||||
|
* @param $task
|
||||||
|
*/
|
||||||
|
public static function overdueRemindEmail($task)
|
||||||
|
{
|
||||||
|
$ownerIds = ProjectTaskUser::whereTaskId($task['id'])->whereOwner(1)->pluck('userid')->toArray();
|
||||||
|
$users = User::whereIn('userid', $ownerIds)->get();
|
||||||
|
if (!$users) {
|
||||||
|
throw new ApiException("ProjectTask::overdueRemindEmail--没有负责人");
|
||||||
|
}
|
||||||
|
$type = $task['end_at'] < Carbon::now() ? 2 : 1;
|
||||||
|
$setting = Base::setting('emailSetting');
|
||||||
|
$hours = floatval($setting['task_remind_hours']);
|
||||||
|
$hours2 = floatval($setting['task_remind_hours2']);
|
||||||
|
$time = $type === 1 ? $hours : $hours2;
|
||||||
|
Config::set("mail.mailers.smtp.host", Base::settingFind('emailSetting', 'smtp_server') ?: Config::get("mail.mailers.smtp.host"));
|
||||||
|
Config::set("mail.mailers.smtp.port", Base::settingFind('emailSetting', 'port') ?: Config::get("mail.mailers.smtp.port"));
|
||||||
|
Config::set("mail.mailers.smtp.username", Base::settingFind('emailSetting', 'account') ?: Config::get("mail.mailers.smtp.username"));
|
||||||
|
Config::set("mail.mailers.smtp.password", Base::settingFind('emailSetting', 'password') ?: Config::get("mail.mailers.smtp.password"));
|
||||||
|
foreach ($users as $user) {
|
||||||
|
/** @var User $user */
|
||||||
|
if (ProjectTaskMailLog::whereTaskId($task['id'])->whereUserid($user->userid)->whereType($type)->whereIsSend(1)->exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$email = $user->email;
|
||||||
|
$isSend = 1;
|
||||||
|
try {
|
||||||
|
$emailContent = [
|
||||||
|
'name' => $task['name'],
|
||||||
|
'time' => $time,
|
||||||
|
'type' => $type
|
||||||
|
];
|
||||||
|
Mail::send('taskOverdueRemind', $emailContent, function ($m) use ($email) {
|
||||||
|
$m->from(Config::get("mail.mailers.smtp.username"), env('APP_NAME'));
|
||||||
|
$m->to($email);
|
||||||
|
$m->subject("任务提醒");
|
||||||
|
});
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$isSend = 0;
|
||||||
|
\Log::error($email . '--邮箱发送报错:', [$e->getMessage()]);
|
||||||
|
}
|
||||||
|
$logData = [
|
||||||
|
'userid' => $user->userid,
|
||||||
|
'task_id' => $task['id'],
|
||||||
|
'email' => $email,
|
||||||
|
'type' => $type,
|
||||||
|
'is_send' => $isSend,
|
||||||
|
];
|
||||||
|
$emailLog = ProjectTaskMailLog::whereTaskId($task['id'])->whereUserid($user->userid)->whereType($type)->first();
|
||||||
|
ProjectTaskMailLog::createInstance($logData, $emailLog->id ?? null)->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
app/Models/ProjectTaskMailLog.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App\Models\ProjectTaskMailLog
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int|null $userid 用户id
|
||||||
|
* @property int|null $task_id 任务id
|
||||||
|
* @property string|null $email 电子邮箱
|
||||||
|
* @property int|null $type 提醒类型:1第一次任务提醒,2第二次任务超期提醒
|
||||||
|
* @property int|null $is_send 邮件发送是否成功:0否,1是
|
||||||
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
|
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog newQuery()
|
||||||
|
* @method static \Illuminate\Database\Query\Builder|ProjectTaskMailLog onlyTrashed()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereCreatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereDeletedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereEmail($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereIsSend($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereTaskId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereType($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereUpdatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskMailLog whereUserid($value)
|
||||||
|
* @method static \Illuminate\Database\Query\Builder|ProjectTaskMailLog withTrashed()
|
||||||
|
* @method static \Illuminate\Database\Query\Builder|ProjectTaskMailLog withoutTrashed()
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
class ProjectTaskMailLog extends AbstractModel
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
}
|
||||||
@ -29,6 +29,7 @@ use Carbon\Carbon;
|
|||||||
* @property int|null $task_dialog_id 最后打开的任务会话ID
|
* @property int|null $task_dialog_id 最后打开的任务会话ID
|
||||||
* @property string|null $created_ip 注册IP
|
* @property string|null $created_ip 注册IP
|
||||||
* @property string|null $disable_at 禁用时间
|
* @property string|null $disable_at 禁用时间
|
||||||
|
* @property int $is_email_verity 邮箱是否已验证
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Database\Factories\UserFactory factory(...$parameters)
|
* @method static \Database\Factories\UserFactory factory(...$parameters)
|
||||||
@ -43,6 +44,7 @@ use Carbon\Carbon;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereEncrypt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereEncrypt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereIdentity($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereIdentity($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereIsEmailVerity($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastIp($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereLastIp($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineAt($value)
|
||||||
@ -185,6 +187,12 @@ class User extends AbstractModel
|
|||||||
throw new ApiException('请输入正确的邮箱地址');
|
throw new ApiException('请输入正确的邮箱地址');
|
||||||
}
|
}
|
||||||
if (User::email2userid($email) > 0) {
|
if (User::email2userid($email) > 0) {
|
||||||
|
$isRegVerify = Base::settingFind('emailSetting', 'reg_verify') === 'open' ? true : false;
|
||||||
|
$user = self::whereUserid(User::email2userid($email))->first();
|
||||||
|
if ($isRegVerify && $user->is_email_verity === 0) {
|
||||||
|
UserEmailVerification::userEmailSend($user);
|
||||||
|
throw new ApiException('您的账号已注册过,请验证邮箱');
|
||||||
|
}
|
||||||
throw new ApiException('邮箱地址已存在');
|
throw new ApiException('邮箱地址已存在');
|
||||||
}
|
}
|
||||||
//密码
|
//密码
|
||||||
|
|||||||
79
app/Models/UserEmailVerification.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Exceptions\ApiException;
|
||||||
|
use App\Module\Base;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Config;
|
||||||
|
use Exception;
|
||||||
|
use Mail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App\Models\UserEmailVerification
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int $userid 用户id
|
||||||
|
* @property string $code 验证参数
|
||||||
|
* @property string $email 电子邮箱
|
||||||
|
* @property string $status 0-未验证,1-已验证
|
||||||
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereCreatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereCode($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereEmail($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereStatus($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereUpdatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket whereUserid($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
class UserEmailVerification extends AbstractModel
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发验证邮箱
|
||||||
|
* @param User $user
|
||||||
|
*/
|
||||||
|
public static function userEmailSend(User $user)
|
||||||
|
{
|
||||||
|
$res = self::where('userid', $user->userid)->where('created_at', '>', Carbon::now()->subMinutes(1440))->first();
|
||||||
|
if ($res) return;
|
||||||
|
//删除
|
||||||
|
self::where('userid', $user->userid)->delete();
|
||||||
|
$info['created_at'] = date("Y-m-d H:i:s");
|
||||||
|
$info['userid'] = $user->userid;
|
||||||
|
$info['email'] = $user->email;
|
||||||
|
$info['code'] = md5(uniqid(md5(microtime(true)), true)) . md5($user->userid . md5('lddsgagsgkdiid' . microtime(true)));
|
||||||
|
$url = Base::fillUrl('single/valid/email') . '?code=' . $info['code'];
|
||||||
|
$info['status'] = 0;
|
||||||
|
$userEmailVerification = self::createInstance($info);
|
||||||
|
$userEmailVerification->save();
|
||||||
|
try {
|
||||||
|
// 15秒后超时
|
||||||
|
Config::set("mail.mailers.smtp.host", Base::settingFind('emailSetting', 'smtp_server') ?: Config::get("mail.mailers.smtp.host"));
|
||||||
|
Config::set("mail.mailers.smtp.port", Base::settingFind('emailSetting', 'port') ?: Config::get("mail.mailers.smtp.port"));
|
||||||
|
Config::set("mail.mailers.smtp.username", Base::settingFind('emailSetting', 'account') ?: Config::get("mail.mailers.smtp.username"));
|
||||||
|
Config::set("mail.mailers.smtp.password", Base::settingFind('emailSetting', 'password') ?: Config::get("mail.mailers.smtp.password"));
|
||||||
|
Mail::send('email', ['url' => $url], function ($m) use ($user) {
|
||||||
|
$m->from(Base::settingFind('emailSetting', 'account') ?: Config::get("mail.mailers.smtp.username"), env('APP_NAME'));
|
||||||
|
$m->to($user->email);
|
||||||
|
$m->subject("绑定邮箱验证");
|
||||||
|
});
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
// 一般是请求超时
|
||||||
|
if (strpos($exception->getMessage(), "Timed Out") !== false) {
|
||||||
|
throw new ApiException("language.TimedOut");
|
||||||
|
} elseif ($exception->getCode() == 550) {
|
||||||
|
throw new ApiException('邮件内容被拒绝,请检查邮箱是否开启接收功能');
|
||||||
|
} else {
|
||||||
|
throw new ApiException($exception->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -105,13 +105,16 @@ class WebSocketDialog extends AbstractModel
|
|||||||
$last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first();
|
$last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first();
|
||||||
$dialog->last_msg = $last_msg;
|
$dialog->last_msg = $last_msg;
|
||||||
// 未读信息
|
// 未读信息
|
||||||
$dialog->unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
$unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count();
|
||||||
|
$isMarkUnread = WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->whereIsMarkUnread(1)->exists();
|
||||||
|
$dialog->unread = $unread > 0 ? $unread : ($isMarkUnread ? 1 : 0);
|
||||||
// 对话人数
|
// 对话人数
|
||||||
$builder = WebSocketDialogUser::whereDialogId($dialog->id);
|
$builder = WebSocketDialogUser::whereDialogId($dialog->id);
|
||||||
$dialog->people = $builder->count();
|
$dialog->people = $builder->count();
|
||||||
// 对方信息
|
// 对方信息
|
||||||
$dialog->dialog_user = null;
|
$dialog->dialog_user = null;
|
||||||
$dialog->group_info = null;
|
$dialog->group_info = null;
|
||||||
|
$dialog->top_at = $dialog->top_at ?? WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->value('top_at');
|
||||||
switch ($dialog->type) {
|
switch ($dialog->type) {
|
||||||
case "user":
|
case "user":
|
||||||
$dialog_user = $builder->where('userid', '!=', $userid)->first();
|
$dialog_user = $builder->where('userid', '!=', $userid)->first();
|
||||||
|
|||||||
@ -9,6 +9,7 @@ namespace App\Models;
|
|||||||
* @property int|null $dialog_id 对话ID
|
* @property int|null $dialog_id 对话ID
|
||||||
* @property int|null $userid 会员ID
|
* @property int|null $userid 会员ID
|
||||||
* @property string|null $top_at 置顶时间
|
* @property string|null $top_at 置顶时间
|
||||||
|
* @property int $is_mark_unread 是否标记为未读:0否,1是
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery()
|
||||||
@ -17,6 +18,7 @@ namespace App\Models;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereDialogId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereDialogId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereIsMarkUnread($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereTopAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereTopAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUserid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUserid($value)
|
||||||
|
|||||||
@ -1712,24 +1712,46 @@ class Base
|
|||||||
*/
|
*/
|
||||||
public static function timeDiff($s, $e)
|
public static function timeDiff($s, $e)
|
||||||
{
|
{
|
||||||
$d = $e - $s;
|
$time = $e - $s;
|
||||||
if ($d > 86400) {
|
$days = 0;
|
||||||
$day = floor($d / 86400);
|
if ($time >= 86400) { // 如果大于1天
|
||||||
$hour = ceil(($d - ($day * 86400)) / 3600);
|
$days = (int)($time / 86400);
|
||||||
if ($hour > 0) {
|
$time = $time % 86400; // 计算天后剩余的毫秒数
|
||||||
return $day . '天' . $hour . '小时';
|
|
||||||
} else {
|
|
||||||
return $day . '天';
|
|
||||||
}
|
}
|
||||||
} elseif ($d > 3600) {
|
$hours = 0;
|
||||||
return ceil($d / 3600) . '小时';
|
if ($time >= 3600) { // 如果大于1小时
|
||||||
} elseif ($d > 60) {
|
$hours = (int)($time / 3600);
|
||||||
return ceil($d / 60) . '分钟';
|
$time = $time % 3600; // 计算小时后剩余的毫秒数
|
||||||
} elseif ($d > 1) {
|
|
||||||
return '1分钟内';
|
|
||||||
} else {
|
|
||||||
return '0秒';
|
|
||||||
}
|
}
|
||||||
|
$minutes = ceil($time / 60); // 剩下的毫秒数都算作分
|
||||||
|
$daysStr = $days > 0 ? $days . '天' : '';
|
||||||
|
$hoursStr = ($hours > 0 || ($days > 0 && $minutes > 0)) ? $hours . '时' : '';
|
||||||
|
$minuteStr = ($minutes > 0) ? $minutes . '分' : '';
|
||||||
|
return $daysStr . $hoursStr . $minuteStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间秒数格式化
|
||||||
|
* @param int $time 时间秒数
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function timeFormat($time)
|
||||||
|
{
|
||||||
|
$days = 0;
|
||||||
|
if ($time >= 86400) { // 如果大于1天
|
||||||
|
$days = (int)($time / 86400);
|
||||||
|
$time = $time % 86400; // 计算天后剩余的毫秒数
|
||||||
|
}
|
||||||
|
$hours = 0;
|
||||||
|
if ($time >= 3600) { // 如果大于1小时
|
||||||
|
$hours = (int)($time / 3600);
|
||||||
|
$time = $time % 3600; // 计算小时后剩余的毫秒数
|
||||||
|
}
|
||||||
|
$minutes = ceil($time / 60); // 剩下的毫秒数都算作分
|
||||||
|
$daysStr = $days > 0 ? $days . '天' : '';
|
||||||
|
$hoursStr = ($hours > 0 || ($days > 0 && $minutes > 0)) ? $hours . '时' : '';
|
||||||
|
$minuteStr = ($minutes > 0) ? $minutes . '分' : '';
|
||||||
|
return $daysStr . $hoursStr . $minuteStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2978,4 +3000,112 @@ class Base
|
|||||||
},
|
},
|
||||||
$str);
|
$str);
|
||||||
}
|
}
|
||||||
|
//去重复
|
||||||
|
public static function assoc_unique($array, $keyid,$desc=true) {
|
||||||
|
if(empty($array)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$array = array_values($array);
|
||||||
|
//倒叙排列数
|
||||||
|
if($desc)
|
||||||
|
{
|
||||||
|
$array =(new Self)->array_rsort($array,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//提取需要判断的项目变成一维数组
|
||||||
|
$a = (new Self)->array_tq($array,$keyid);
|
||||||
|
|
||||||
|
//去除一维数组重复值
|
||||||
|
$a = array_unique($a);
|
||||||
|
//提取二维数组项目值
|
||||||
|
foreach($array[0] AS $key=>$value)
|
||||||
|
{
|
||||||
|
$akey[] = $key;
|
||||||
|
}
|
||||||
|
//重新拼接二维数组
|
||||||
|
foreach($akey AS $key=>$value)
|
||||||
|
{
|
||||||
|
$b = (new Self)->array_tq($array,$value);
|
||||||
|
foreach($a AS $key2=>$value2)
|
||||||
|
{
|
||||||
|
$c[$key2][$value] = $b[$key2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($desc)
|
||||||
|
{
|
||||||
|
$c = (new Self)->array_rsort($c,true);
|
||||||
|
}
|
||||||
|
return $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//提取二维数组项目
|
||||||
|
public static function array_tq($array,$aval="")
|
||||||
|
{
|
||||||
|
foreach($array AS $key=>$value)
|
||||||
|
{
|
||||||
|
$result[] = $value[$aval];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function array_rsort($arr,$isvalues=false)
|
||||||
|
{
|
||||||
|
if(is_array($arr)){
|
||||||
|
$flag = false;
|
||||||
|
//一维数组
|
||||||
|
if(count($arr) == count($arr,1)){
|
||||||
|
$flag = true;
|
||||||
|
$i = 0;
|
||||||
|
//转换成二维数组
|
||||||
|
foreach($arr AS $key=>$value){
|
||||||
|
$a[$i]["okey"] = $key;
|
||||||
|
$a[$i]["value"] = $value;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$arr = $a;
|
||||||
|
}
|
||||||
|
//多维数组
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//添加临时key值
|
||||||
|
foreach($arr AS $key=>$value){
|
||||||
|
$value["okey"] = $key;
|
||||||
|
$array[] = $value;
|
||||||
|
}
|
||||||
|
$arr = $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
//倒叙并还原key值
|
||||||
|
$count = count($arr)-1;
|
||||||
|
for($i=0;$i<count($arr);$i++){
|
||||||
|
$b[$arr[$count]["okey"]] = $arr[$count];
|
||||||
|
$count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//重构一维数组
|
||||||
|
if($flag == true){
|
||||||
|
foreach($b AS $key=>$value){
|
||||||
|
if($isvalues){
|
||||||
|
$c[] = $value["value"];
|
||||||
|
}else{
|
||||||
|
$c[$value["okey"]] = $value["value"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//多维数组去除临时key值
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach($b AS $key=>$value) {
|
||||||
|
unset($value["okey"]);
|
||||||
|
if($isvalues){
|
||||||
|
$c[] = $value;
|
||||||
|
}else{
|
||||||
|
$c[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
app/Tasks/OverdueRemindEmailTask.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Models\ProjectTask;
|
||||||
|
use App\Module\Base;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class OverdueRemindEmailTask extends AbstractTask
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start()
|
||||||
|
{
|
||||||
|
$setting = Base::setting('emailSetting');
|
||||||
|
if ($setting['notice'] === 'open') {
|
||||||
|
$hours = floatval($setting['task_remind_hours']);
|
||||||
|
$hours2 = floatval($setting['task_remind_hours2']);
|
||||||
|
$taskLists1 = [];
|
||||||
|
$taskLists2 = [];
|
||||||
|
if ($hours > 0) {
|
||||||
|
$taskLists1 = ProjectTask::whereNull('complete_at')
|
||||||
|
->where('end_at', '>=', Carbon::now()->addMinutes($hours * 60 - 3)->rawFormat('Y-m-d H:i:s'))
|
||||||
|
->where('end_at', '<=', Carbon::now()->addMinutes($hours * 60 + 3)->rawFormat('Y-m-d H:i:s'))
|
||||||
|
->whereNull('archived_at')
|
||||||
|
->take(100)
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
if ($hours2 > 0) {
|
||||||
|
$taskLists2 = ProjectTask::whereNull('complete_at')
|
||||||
|
->where('end_at', '>=', Carbon::now()->subMinutes($hours2 * 60 + 3)->rawFormat('Y-m-d H:i:s'))
|
||||||
|
->where('end_at', '<=', Carbon::now()->subMinutes($hours2 * 60 - 3)->rawFormat('Y-m-d H:i:s'))
|
||||||
|
->whereNull('archived_at')
|
||||||
|
->take(100)
|
||||||
|
->get()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
$taskLists = array_merge($taskLists1, $taskLists2);
|
||||||
|
$taskLists = Base::assoc_unique($taskLists, 'id');
|
||||||
|
foreach ($taskLists as $task) {
|
||||||
|
ProjectTask::overdueRemindEmail($task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -36,13 +36,12 @@ return [
|
|||||||
'mailers' => [
|
'mailers' => [
|
||||||
'smtp' => [
|
'smtp' => [
|
||||||
'transport' => 'smtp',
|
'transport' => 'smtp',
|
||||||
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
'host' => 'smtp.qq.com',
|
||||||
'port' => env('MAIL_PORT', 587),
|
'port' => 465,
|
||||||
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
'encryption' => 'ssl',
|
||||||
'username' => env('MAIL_USERNAME'),
|
'username' => '302645122@qq.com',
|
||||||
'password' => env('MAIL_PASSWORD'),
|
'password' => 'ijncezxbmhrvbhab',
|
||||||
'timeout' => null,
|
'timeout' => 15,
|
||||||
'auth_mode' => null,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'ses' => [
|
'ses' => [
|
||||||
@ -70,6 +69,7 @@ return [
|
|||||||
'array' => [
|
'array' => [
|
||||||
'transport' => 'array',
|
'transport' => 'array',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddIsEmailVerityToUsers extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_email_verity')->default(0)->nullable(false)->after('disable_at')->comment('邮箱是否已验证');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("is_email_verity");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateUserEmailVerificationsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('user_email_verifications', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->integer('userid')->nullable()->default(0)->comment('用户id');
|
||||||
|
$table->string('code')->nullable()->default('')->comment('验证参数');
|
||||||
|
$table->string('email')->nullable()->default('')->comment('电子邮箱');
|
||||||
|
$table->integer('status')->nullable()->default(0)->comment('0-未验证,1-已验证');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('user_email_verifications');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateProjectTaskMailLogsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('project_task_mail_logs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->integer('userid')->nullable()->default(0)->comment('用户id');
|
||||||
|
$table->integer('task_id')->nullable()->default(0)->comment('任务id');
|
||||||
|
$table->string('email')->nullable()->default('')->comment('电子邮箱');
|
||||||
|
$table->tinyInteger('type')->nullable()->default(0)->comment('提醒类型:1第一次任务提醒,2第二次任务超期提醒');
|
||||||
|
$table->tinyInteger('is_send')->nullable()->default(0)->comment('邮件发送是否成功:0否,1是');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('project_task_mail_logs');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddWebSocketDialogUsersAddIsMarkUnread extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('web_socket_dialog_users', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_mark_unread')->default(0)->nullable(false)->after('top_at')->comment('是否标记为未读:0否,1是');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('web_socket_dialog_users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("is_mark_unread");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddProjectTaskMailLogsAddDeletes extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('project_task_mail_logs', function (Blueprint $table) {
|
||||||
|
if (!Schema::hasColumn('project_task_mail_logs', 'deleted_at')) {
|
||||||
|
$table->softDeletes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('project_task_mail_logs', function (Blueprint $table) {
|
||||||
|
$table->dropSoftDeletes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddProjectTasksDeletedUserid extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('project_tasks', function (Blueprint $table) {
|
||||||
|
if (!Schema::hasColumn('project_tasks', 'deleted_userid')) {
|
||||||
|
$table->bigInteger('deleted_userid')->nullable()->default(0)->after('deleted_at')->comment('删除会员');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('project_tasks', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("deleted_userid");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/images/index/box-pic1.png
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
public/images/index/box-pic2.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
public/images/index/box-pic3.png
Normal file
|
After Width: | Height: | Size: 348 KiB |
BIN
public/images/index/box-pic4.png
Normal file
|
After Width: | Height: | Size: 624 KiB |
BIN
public/images/index/decoration.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/images/index/footer-bg.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/images/index/indexlogo.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/images/index/language.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
public/images/index/pic.png
Normal file
|
After Width: | Height: | Size: 530 KiB |
BIN
public/images/index/square.png
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
public/images/indexlogo.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
public/images/language.png
Normal file
|
After Width: | Height: | Size: 592 B |
13
public/images/mark.svg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#8BCF70;}
|
||||||
|
</style>0
|
||||||
|
<path class="st0" d="M20.7,8.1c-1.5-1.5-4.4-4.4-4.4-4.4c-1.2-1.2-2.5-1.4-3.4-0.7c-0.5,0.4-0.7,0.9-0.8,1.4c-0.1,0.5-0.4,1-0.8,1.3
|
||||||
|
l-0.1,0.1c-2,1.5-4.3,2.8-6.8,3.2C3.9,9.2,3.3,9.5,3,10c-0.6,0.9-0.4,2.1,0.3,2.9l3.4,3.4c0,0,0,0,0,0l-3.1,3.1
|
||||||
|
c-0.3,0.3-0.3,0.8,0,1.1c0.1,0.1,0.3,0.2,0.5,0.2c0.2,0,0.4-0.1,0.5-0.2l3.1-3.1c0,0,0,0,0,0l2.9,2.9c1.3,1.3,2.5,1.5,3.4,0.9
|
||||||
|
c0.4-0.3,0.7-0.7,0.9-1.2c0.6-2.3,1.4-4.6,2.8-6.5l0.5-0.7c0.3-0.4,0.8-0.8,1.3-0.8c0.5-0.1,1.1-0.3,1.4-0.8
|
||||||
|
C21.7,10.2,21.5,8.9,20.7,8.1z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 909 B |
2
public/js/app.js
vendored
2
public/js/build/120.js
vendored
@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* html2canvas 1.4.1 <https://html2canvas.hertzen.com>
|
* html2canvas 1.4.0 <https://html2canvas.hertzen.com>
|
||||||
* Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
|
* Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
|
||||||
* Released under MIT License
|
* Released under MIT License
|
||||||
*/
|
*/
|
||||||
|
|||||||
1
public/js/build/135.js
vendored
2
public/js/build/206.js
vendored
1
public/js/build/39.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[39],{55983:(t,e,s)=>{s.d(e,{Z:()=>o});var i=s(1519),a=s.n(i)()((function(t){return t[1]}));a.push([t.id,".valid-wrap{align-items:center;display:flex;height:100vh;justify-content:center;width:100vw}.valid-box{background-color:#fff;border-radius:10px;padding:5px 15px 20px;width:500px}.valid-box .valid-title{border-bottom:1px solid #e8eaec;line-height:1;padding:14px 16px}.valid-box .validation-text{color:#333;font-size:14px;padding:10px}",""]);const o=a},5039:(t,e,s)=>{s.r(e),s.d(e,{default:()=>c});const i={name:"validEmail",components:{},data:function(){return{success:!1,error:!1,errorText:this.$L("链接已过期,已重新发送")}},mounted:function(){this.verificationEmail()},watch:{},methods:{verificationEmail:function(){var t=this;this.$store.dispatch("call",{url:"users/email/verification",data:{code:this.$route.query.code}}).then((function(e){e.data;t.success=!0,t.error=!1})).catch((function(e){var s=e.data,i=e.msg;2===s.code?t.goForward({path:"/"},!0):(t.success=!1,t.error=!0,t.errorText=t.$L(i))}))},userLogout:function(){this.$store.dispatch("logout",!1)}}};var a=s(93379),o=s.n(a),r=s(55983),n={insert:"head",singleton:!1};o()(r.Z,n);r.Z.locals;const c=(0,s(51900).Z)(i,(function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{staticClass:"valid-wrap"},[s("div",{staticClass:"valid-box"},[s("div",{staticClass:"valid-title"},[t._v(t._s(t.$L("验证邮箱")))]),t._v(" "),t.success||t.error?t._e():s("Spin",{attrs:{size:"large"}}),t._v(" "),t.success?s("div",{staticClass:"validation-text"},[s("p",[t._v(t._s(t.$L("您的邮箱已通过验证")))]),t._v(" "),s("p",[t._v(t._s(t.$L("今后您可以通过此邮箱重置您的账号密码")))])]):t._e(),t._v(" "),t.error?s("div",{staticClass:"validation-text"},[s("div",[t._v(t._s(t.errorText))])]):t._e(),t._v(" "),t.success?s("div",{attrs:{slot:"footer"},slot:"footer"},[s("Button",{attrs:{type:"primary",long:""},on:{click:t.userLogout}},[t._v(t._s(t.$L("返回首页")))])],1):t._e()],1)])}),[],!1,null,null,null).exports}}]);
|
||||||
1
public/js/build/396.js
vendored
Normal file
2
public/js/build/482.js
vendored
Normal file
2
public/js/build/486.js
vendored
2
public/js/build/496.js
vendored
Normal file
13
public/js/build/496.js.LICENSE.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*!
|
||||||
|
* clipboard.js v2.0.8
|
||||||
|
* https://clipboardjs.com/
|
||||||
|
*
|
||||||
|
* Licensed MIT © Zeno Rocha
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**!
|
||||||
|
* Sortable 1.10.2
|
||||||
|
* @author RubaXa <trash@rubaxa.org>
|
||||||
|
* @author owenm <owen23355@gmail.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
2
public/js/build/528.js
vendored
2
public/js/build/544.js
vendored
1
public/js/build/569.js
vendored
Normal file
1
public/js/build/605.js
vendored
Normal file
1
public/js/build/662.js
vendored
Normal file
2
public/js/build/78.js
vendored
Normal file
799
public/js/build/78.js.LICENSE.txt
Normal file
@ -0,0 +1,799 @@
|
|||||||
|
/*!
|
||||||
|
* TOAST UI Calendar
|
||||||
|
* @version 1.15.1-5 | Sun Jan 09 2022
|
||||||
|
* @author NHN FE Development Lab <dl_javascript@nhn.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* TOAST UI Date Picker
|
||||||
|
* @version 4.3.1
|
||||||
|
* @author NHN. FE Development Lab <dl_javascript@nhn.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* TOAST UI Time Picker
|
||||||
|
* @version 2.1.4
|
||||||
|
* @author NHN FE Development Lab <dl_javascript@nhn.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* tui-code-snippet.js
|
||||||
|
* @version 1.5.2
|
||||||
|
* @author NHN. FE Development Lab <dl_javascript@nhn.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! ../..//common/vlayout */
|
||||||
|
|
||||||
|
/*! ../../common/array */
|
||||||
|
|
||||||
|
/*! ../../common/autoScroll */
|
||||||
|
|
||||||
|
/*! ../../common/collection */
|
||||||
|
|
||||||
|
/*! ../../common/common */
|
||||||
|
|
||||||
|
/*! ../../common/common.js */
|
||||||
|
|
||||||
|
/*! ../../common/datetime */
|
||||||
|
|
||||||
|
/*! ../../common/domevent */
|
||||||
|
|
||||||
|
/*! ../../common/domutil */
|
||||||
|
|
||||||
|
/*! ../../common/floatingLayer */
|
||||||
|
|
||||||
|
/*! ../../common/point */
|
||||||
|
|
||||||
|
/*! ../../common/reqAnimFrame */
|
||||||
|
|
||||||
|
/*! ../../common/timezone */
|
||||||
|
|
||||||
|
/*! ../../config */
|
||||||
|
|
||||||
|
/*! ../../model/schedule */
|
||||||
|
|
||||||
|
/*! ../../model/viewModel/scheduleViewModel */
|
||||||
|
|
||||||
|
/*! ../../view/template/week/timeMoveGuide.hbs */
|
||||||
|
|
||||||
|
/*! ../../view/view */
|
||||||
|
|
||||||
|
/*! ../common/array */
|
||||||
|
|
||||||
|
/*! ../common/collection */
|
||||||
|
|
||||||
|
/*! ../common/common */
|
||||||
|
|
||||||
|
/*! ../common/datetime */
|
||||||
|
|
||||||
|
/*! ../common/dirty */
|
||||||
|
|
||||||
|
/*! ../common/domevent */
|
||||||
|
|
||||||
|
/*! ../common/domutil */
|
||||||
|
|
||||||
|
/*! ../common/dw */
|
||||||
|
|
||||||
|
/*! ../common/model */
|
||||||
|
|
||||||
|
/*! ../common/point */
|
||||||
|
|
||||||
|
/*! ../common/reqAnimFrame */
|
||||||
|
|
||||||
|
/*! ../common/sanitizer */
|
||||||
|
|
||||||
|
/*! ../common/timezone */
|
||||||
|
|
||||||
|
/*! ../common/vlayout */
|
||||||
|
|
||||||
|
/*! ../config */
|
||||||
|
|
||||||
|
/*! ../controller/base */
|
||||||
|
|
||||||
|
/*! ../controller/viewMixin/core */
|
||||||
|
|
||||||
|
/*! ../controller/viewMixin/month */
|
||||||
|
|
||||||
|
/*! ../controller/viewMixin/week */
|
||||||
|
|
||||||
|
/*! ../exception */
|
||||||
|
|
||||||
|
/*! ../handler/daygrid/click */
|
||||||
|
|
||||||
|
/*! ../handler/daygrid/creation */
|
||||||
|
|
||||||
|
/*! ../handler/daygrid/move */
|
||||||
|
|
||||||
|
/*! ../handler/daygrid/resize */
|
||||||
|
|
||||||
|
/*! ../handler/drag */
|
||||||
|
|
||||||
|
/*! ../handler/month/click */
|
||||||
|
|
||||||
|
/*! ../handler/month/creation */
|
||||||
|
|
||||||
|
/*! ../handler/month/move */
|
||||||
|
|
||||||
|
/*! ../handler/month/resize */
|
||||||
|
|
||||||
|
/*! ../handler/time/click */
|
||||||
|
|
||||||
|
/*! ../handler/time/clickDayname */
|
||||||
|
|
||||||
|
/*! ../handler/time/creation */
|
||||||
|
|
||||||
|
/*! ../handler/time/move */
|
||||||
|
|
||||||
|
/*! ../handler/time/resize */
|
||||||
|
|
||||||
|
/*! ../logger */
|
||||||
|
|
||||||
|
/*! ../model/schedule */
|
||||||
|
|
||||||
|
/*! ../model/viewModel/scheduleViewModel */
|
||||||
|
|
||||||
|
/*! ../template/month/month.hbs */
|
||||||
|
|
||||||
|
/*! ../template/month/more.hbs */
|
||||||
|
|
||||||
|
/*! ../template/month/weekdayInMonth.hbs */
|
||||||
|
|
||||||
|
/*! ../template/month/weekdayInMonthSchedule.hbs */
|
||||||
|
|
||||||
|
/*! ../template/popup/scheduleCreationPopup.hbs */
|
||||||
|
|
||||||
|
/*! ../template/popup/scheduleDetailPopup.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/dayGrid.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/dayGridSchedule.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/daynames.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/time.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/timeGrid.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/timeGridCurrentTime.hbs */
|
||||||
|
|
||||||
|
/*! ../template/week/timezoneSticky.hbs */
|
||||||
|
|
||||||
|
/*! ../theme/theme */
|
||||||
|
|
||||||
|
/*! ../utils */
|
||||||
|
|
||||||
|
/*! ../view */
|
||||||
|
|
||||||
|
/*! ../view/layout */
|
||||||
|
|
||||||
|
/*! ../view/month/month */
|
||||||
|
|
||||||
|
/*! ../view/month/more */
|
||||||
|
|
||||||
|
/*! ../view/popup/scheduleCreationPopup */
|
||||||
|
|
||||||
|
/*! ../view/popup/scheduleDetailPopup */
|
||||||
|
|
||||||
|
/*! ../view/view */
|
||||||
|
|
||||||
|
/*! ../view/week/dayGrid */
|
||||||
|
|
||||||
|
/*! ../view/week/dayname */
|
||||||
|
|
||||||
|
/*! ../view/week/timeGrid */
|
||||||
|
|
||||||
|
/*! ../view/week/week */
|
||||||
|
|
||||||
|
/*! ../weekday */
|
||||||
|
|
||||||
|
/*! ./../../../../../webpack/buildin/global.js */
|
||||||
|
|
||||||
|
/*! ./../../../../node_modules/webpack/buildin/global.js */
|
||||||
|
|
||||||
|
/*! ./../../../../webpack/buildin/global.js */
|
||||||
|
|
||||||
|
/*! ./../../../node_modules/webpack/buildin/global.js */
|
||||||
|
|
||||||
|
/*! ./../node_modules/webpack/buildin/global.js */
|
||||||
|
|
||||||
|
/*! ./base */
|
||||||
|
|
||||||
|
/*! ./collection */
|
||||||
|
|
||||||
|
/*! ./common */
|
||||||
|
|
||||||
|
/*! ./controller */
|
||||||
|
|
||||||
|
/*! ./core */
|
||||||
|
|
||||||
|
/*! ./create-new-lookup-object */
|
||||||
|
|
||||||
|
/*! ./creationGuide */
|
||||||
|
|
||||||
|
/*! ./css/main.styl */
|
||||||
|
|
||||||
|
/*! ./dayGridSchedule */
|
||||||
|
|
||||||
|
/*! ./decorators */
|
||||||
|
|
||||||
|
/*! ./decorators/inline */
|
||||||
|
|
||||||
|
/*! ./dist/cjs/handlebars.runtime */
|
||||||
|
|
||||||
|
/*! ./domevent */
|
||||||
|
|
||||||
|
/*! ./domutil */
|
||||||
|
|
||||||
|
/*! ./exception */
|
||||||
|
|
||||||
|
/*! ./guide */
|
||||||
|
|
||||||
|
/*! ./guide.hbs */
|
||||||
|
|
||||||
|
/*! ./handlebars/base */
|
||||||
|
|
||||||
|
/*! ./handlebars/exception */
|
||||||
|
|
||||||
|
/*! ./handlebars/no-conflict */
|
||||||
|
|
||||||
|
/*! ./handlebars/runtime */
|
||||||
|
|
||||||
|
/*! ./handlebars/safe-string */
|
||||||
|
|
||||||
|
/*! ./handlebars/utils */
|
||||||
|
|
||||||
|
/*! ./helpers */
|
||||||
|
|
||||||
|
/*! ./helpers/block-helper-missing */
|
||||||
|
|
||||||
|
/*! ./helpers/each */
|
||||||
|
|
||||||
|
/*! ./helpers/helper-missing */
|
||||||
|
|
||||||
|
/*! ./helpers/if */
|
||||||
|
|
||||||
|
/*! ./helpers/log */
|
||||||
|
|
||||||
|
/*! ./helpers/lookup */
|
||||||
|
|
||||||
|
/*! ./helpers/with */
|
||||||
|
|
||||||
|
/*! ./internal/proto-access */
|
||||||
|
|
||||||
|
/*! ./internal/wrapHelper */
|
||||||
|
|
||||||
|
/*! ./intlUtil */
|
||||||
|
|
||||||
|
/*! ./js/factory/calendar */
|
||||||
|
|
||||||
|
/*! ./js/view/template/helper */
|
||||||
|
|
||||||
|
/*! ./logger */
|
||||||
|
|
||||||
|
/*! ./monthView */
|
||||||
|
|
||||||
|
/*! ./move */
|
||||||
|
|
||||||
|
/*! ./moveGuide */
|
||||||
|
|
||||||
|
/*! ./moveGuide.hbs */
|
||||||
|
|
||||||
|
/*! ./node_modules/handlebars/runtime.js */
|
||||||
|
|
||||||
|
/*! ./resizeGuide */
|
||||||
|
|
||||||
|
/*! ./standard */
|
||||||
|
|
||||||
|
/*! ./themeConfig */
|
||||||
|
|
||||||
|
/*! ./time */
|
||||||
|
|
||||||
|
/*! ./timezone */
|
||||||
|
|
||||||
|
/*! ./utils */
|
||||||
|
|
||||||
|
/*! ./view */
|
||||||
|
|
||||||
|
/*! ./vpanel */
|
||||||
|
|
||||||
|
/*! ./weekView */
|
||||||
|
|
||||||
|
/*! ./weekdayInMonth */
|
||||||
|
|
||||||
|
/*! @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 */
|
||||||
|
|
||||||
|
/*! dompurify */
|
||||||
|
|
||||||
|
/*! handlebars-template-loader/runtime */
|
||||||
|
|
||||||
|
/*! handlebars/runtime */
|
||||||
|
|
||||||
|
/*! no static exports found */
|
||||||
|
|
||||||
|
/*! tui-code-snippet */
|
||||||
|
|
||||||
|
/*! tui-date-picker */
|
||||||
|
|
||||||
|
/*!**********************!*\
|
||||||
|
!*** ./src/index.js ***!
|
||||||
|
\**********************/
|
||||||
|
|
||||||
|
/*!**************************!*\
|
||||||
|
!*** ./src/js/config.js ***!
|
||||||
|
\**************************/
|
||||||
|
|
||||||
|
/*!***************************!*\
|
||||||
|
!*** ./src/css/main.styl ***!
|
||||||
|
\***************************/
|
||||||
|
|
||||||
|
/*!*****************************!*\
|
||||||
|
!*** ./src/js/common/dw.js ***!
|
||||||
|
\*****************************/
|
||||||
|
|
||||||
|
/*!*****************************!*\
|
||||||
|
!*** ./src/js/view/view.js ***!
|
||||||
|
\*****************************/
|
||||||
|
|
||||||
|
/*!*******************************!*\
|
||||||
|
!*** ./src/js/theme/theme.js ***!
|
||||||
|
\*******************************/
|
||||||
|
|
||||||
|
/*!*******************************!*\
|
||||||
|
!*** ./src/js/view/layout.js ***!
|
||||||
|
\*******************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/common/array.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/common/dirty.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/common/model.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/common/point.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/handler/drag.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!********************************!*\
|
||||||
|
!*** ./src/js/view/weekday.js ***!
|
||||||
|
\********************************/
|
||||||
|
|
||||||
|
/*!*********************************!*\
|
||||||
|
!*** ./src/js/common/common.js ***!
|
||||||
|
\*********************************/
|
||||||
|
|
||||||
|
/*!*********************************!*\
|
||||||
|
!*** ./src/js/common/vpanel.js ***!
|
||||||
|
\*********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/common/domutil.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/common/vlayout.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/model/schedule.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/theme/standard.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/view/week/time.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!**********************************!*\
|
||||||
|
!*** ./src/js/view/week/week.js ***!
|
||||||
|
\**********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** (webpack)/buildin/global.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/common/datetime.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/common/domevent.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/common/intlUtil.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/common/timezone.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/controller/base.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!***********************************!*\
|
||||||
|
!*** ./src/js/view/month/more.js ***!
|
||||||
|
\***********************************/
|
||||||
|
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** ./src/js/common/sanitizer.js ***!
|
||||||
|
\************************************/
|
||||||
|
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** ./src/js/factory/calendar.js ***!
|
||||||
|
\************************************/
|
||||||
|
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** ./src/js/factory/weekView.js ***!
|
||||||
|
\************************************/
|
||||||
|
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** ./src/js/view/month/month.js ***!
|
||||||
|
\************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/common/autoScroll.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/common/collection.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/factory/monthView.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/handler/time/core.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/handler/time/move.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/theme/themeConfig.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/view/week/dayGrid.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/js/view/week/dayname.js ***!
|
||||||
|
\*************************************/
|
||||||
|
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/js/factory/controller.js ***!
|
||||||
|
\**************************************/
|
||||||
|
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/js/handler/month/core.js ***!
|
||||||
|
\**************************************/
|
||||||
|
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/js/handler/month/move.js ***!
|
||||||
|
\**************************************/
|
||||||
|
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/js/handler/time/click.js ***!
|
||||||
|
\**************************************/
|
||||||
|
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/js/view/week/timeGrid.js ***!
|
||||||
|
\**************************************/
|
||||||
|
|
||||||
|
/*!***************************************!*\
|
||||||
|
!*** ./src/js/common/reqAnimFrame.js ***!
|
||||||
|
\***************************************/
|
||||||
|
|
||||||
|
/*!***************************************!*\
|
||||||
|
!*** ./src/js/handler/month/click.js ***!
|
||||||
|
\***************************************/
|
||||||
|
|
||||||
|
/*!***************************************!*\
|
||||||
|
!*** ./src/js/handler/month/guide.js ***!
|
||||||
|
\***************************************/
|
||||||
|
|
||||||
|
/*!***************************************!*\
|
||||||
|
!*** ./src/js/handler/time/resize.js ***!
|
||||||
|
\***************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/common/floatingLayer.js ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/core.js ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/move.js ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/handler/month/guide.hbs ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/handler/month/resize.js ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!****************************************!*\
|
||||||
|
!*** ./src/js/view/template/helper.js ***!
|
||||||
|
\****************************************/
|
||||||
|
|
||||||
|
/*!*****************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/click.js ***!
|
||||||
|
\*****************************************/
|
||||||
|
|
||||||
|
/*!*****************************************!*\
|
||||||
|
!*** ./src/js/handler/time/creation.js ***!
|
||||||
|
\*****************************************/
|
||||||
|
|
||||||
|
/*!******************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/resize.js ***!
|
||||||
|
\******************************************/
|
||||||
|
|
||||||
|
/*!******************************************!*\
|
||||||
|
!*** ./src/js/handler/month/creation.js ***!
|
||||||
|
\******************************************/
|
||||||
|
|
||||||
|
/*!******************************************!*\
|
||||||
|
!*** ./src/js/handler/time/moveGuide.js ***!
|
||||||
|
\******************************************/
|
||||||
|
|
||||||
|
/*!*******************************************!*\
|
||||||
|
!*** ./src/js/handler/month/moveGuide.js ***!
|
||||||
|
\*******************************************/
|
||||||
|
|
||||||
|
/*!********************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/runtime.js ***!
|
||||||
|
\********************************************/
|
||||||
|
|
||||||
|
/*!********************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/creation.js ***!
|
||||||
|
\********************************************/
|
||||||
|
|
||||||
|
/*!********************************************!*\
|
||||||
|
!*** ./src/js/handler/month/moveGuide.hbs ***!
|
||||||
|
\********************************************/
|
||||||
|
|
||||||
|
/*!********************************************!*\
|
||||||
|
!*** ./src/js/handler/time/resizeGuide.js ***!
|
||||||
|
\********************************************/
|
||||||
|
|
||||||
|
/*!********************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/time.hbs ***!
|
||||||
|
\********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/controller/viewMixin/core.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/controller/viewMixin/week.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/moveGuide.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/handler/month/resizeGuide.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/handler/time/clickDayname.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/view/month/weekdayInMonth.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/view/template/month/more.hbs ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!*********************************************!*\
|
||||||
|
!*** ./src/js/view/week/dayGridSchedule.js ***!
|
||||||
|
\*********************************************/
|
||||||
|
|
||||||
|
/*!**********************************************!*\
|
||||||
|
!*** ./src/js/controller/viewMixin/month.js ***!
|
||||||
|
\**********************************************/
|
||||||
|
|
||||||
|
/*!**********************************************!*\
|
||||||
|
!*** ./src/js/handler/time/creationGuide.js ***!
|
||||||
|
\**********************************************/
|
||||||
|
|
||||||
|
/*!**********************************************!*\
|
||||||
|
!*** ./src/js/view/template/month/month.hbs ***!
|
||||||
|
\**********************************************/
|
||||||
|
|
||||||
|
/*!***********************************************!*\
|
||||||
|
!*** ./node_modules/dompurify/dist/purify.js ***!
|
||||||
|
\***********************************************/
|
||||||
|
|
||||||
|
/*!***********************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/resizeGuide.js ***!
|
||||||
|
\***********************************************/
|
||||||
|
|
||||||
|
/*!***********************************************!*\
|
||||||
|
!*** ./src/js/handler/month/creationGuide.js ***!
|
||||||
|
\***********************************************/
|
||||||
|
|
||||||
|
/*!***********************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/dayGrid.hbs ***!
|
||||||
|
\***********************************************/
|
||||||
|
|
||||||
|
/*!************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/daynames.hbs ***!
|
||||||
|
\************************************************/
|
||||||
|
|
||||||
|
/*!************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/timeGrid.hbs ***!
|
||||||
|
\************************************************/
|
||||||
|
|
||||||
|
/*!*************************************************!*\
|
||||||
|
!*** ./src/js/handler/daygrid/creationGuide.js ***!
|
||||||
|
\*************************************************/
|
||||||
|
|
||||||
|
/*!**************************************************!*\
|
||||||
|
!*** ./src/js/view/popup/scheduleDetailPopup.js ***!
|
||||||
|
\**************************************************/
|
||||||
|
|
||||||
|
/*!****************************************************!*\
|
||||||
|
!*** ./src/js/view/popup/scheduleCreationPopup.js ***!
|
||||||
|
\****************************************************/
|
||||||
|
|
||||||
|
/*!*****************************************************!*\
|
||||||
|
!*** ./src/js/model/viewModel/scheduleViewModel.js ***!
|
||||||
|
\*****************************************************/
|
||||||
|
|
||||||
|
/*!*****************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/timeMoveGuide.hbs ***!
|
||||||
|
\*****************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/timezoneSticky.hbs ***!
|
||||||
|
\******************************************************/
|
||||||
|
|
||||||
|
/*!*******************************************************!*\
|
||||||
|
!*** ./src/js/view/template/month/weekdayInMonth.hbs ***!
|
||||||
|
\*******************************************************/
|
||||||
|
|
||||||
|
/*!*******************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/dayGridSchedule.hbs ***!
|
||||||
|
\*******************************************************/
|
||||||
|
|
||||||
|
/*!***********************************************************!*\
|
||||||
|
!*** ./src/js/view/template/week/timeGridCurrentTime.hbs ***!
|
||||||
|
\***********************************************************/
|
||||||
|
|
||||||
|
/*!************************************************************!*\
|
||||||
|
!*** ./src/js/view/template/popup/scheduleDetailPopup.hbs ***!
|
||||||
|
\************************************************************/
|
||||||
|
|
||||||
|
/*!*************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/base.js ***!
|
||||||
|
\*************************************************************/
|
||||||
|
|
||||||
|
/*!**************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/utils.js ***!
|
||||||
|
\**************************************************************/
|
||||||
|
|
||||||
|
/*!**************************************************************!*\
|
||||||
|
!*** ./src/js/view/template/popup/scheduleCreationPopup.hbs ***!
|
||||||
|
\**************************************************************/
|
||||||
|
|
||||||
|
/*!***************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/logger.js ***!
|
||||||
|
\***************************************************************/
|
||||||
|
|
||||||
|
/*!***************************************************************!*\
|
||||||
|
!*** ./src/js/view/template/month/weekdayInMonthSchedule.hbs ***!
|
||||||
|
\***************************************************************/
|
||||||
|
|
||||||
|
/*!****************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars.runtime.js ***!
|
||||||
|
\****************************************************************/
|
||||||
|
|
||||||
|
/*!****************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers.js ***!
|
||||||
|
\****************************************************************/
|
||||||
|
|
||||||
|
/*!****************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/runtime.js ***!
|
||||||
|
\****************************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars-template-loader/runtime/index.js ***!
|
||||||
|
\******************************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/exception.js ***!
|
||||||
|
\******************************************************************/
|
||||||
|
|
||||||
|
/*!*******************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/decorators.js ***!
|
||||||
|
\*******************************************************************/
|
||||||
|
|
||||||
|
/*!*******************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/if.js ***!
|
||||||
|
\*******************************************************************/
|
||||||
|
|
||||||
|
/*!********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/log.js ***!
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
/*!********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/no-conflict.js ***!
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
/*!********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/safe-string.js ***!
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
/*!*********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/each.js ***!
|
||||||
|
\*********************************************************************/
|
||||||
|
|
||||||
|
/*!*********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/with.js ***!
|
||||||
|
\*********************************************************************/
|
||||||
|
|
||||||
|
/*!***********************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/lookup.js ***!
|
||||||
|
\***********************************************************************/
|
||||||
|
|
||||||
|
/*!**************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/decorators/inline.js ***!
|
||||||
|
\**************************************************************************/
|
||||||
|
|
||||||
|
/*!****************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/internal/wrapHelper.js ***!
|
||||||
|
\****************************************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/internal/proto-access.js ***!
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
/*!*******************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/helper-missing.js ***!
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
/*!*************************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/helpers/block-helper-missing.js ***!
|
||||||
|
\*************************************************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************************************************!*\
|
||||||
|
!*** ./node_modules/handlebars/dist/cjs/handlebars/internal/create-new-lookup-object.js ***!
|
||||||
|
\******************************************************************************************/
|
||||||
|
|
||||||
|
/*!******************************************************************************************************************************!*\
|
||||||
|
!*** external {"commonjs":"tui-code-snippet","commonjs2":"tui-code-snippet","amd":"tui-code-snippet","root":["tui","util"]} ***!
|
||||||
|
\******************************************************************************************************************************/
|
||||||
|
|
||||||
|
/*!*********************************************************************************************************************************!*\
|
||||||
|
!*** external {"commonjs":"tui-date-picker","commonjs2":"tui-date-picker","amd":"tui-date-picker","root":["tui","DatePicker"]} ***!
|
||||||
|
\*********************************************************************************************************************************/
|
||||||
|
|
||||||
|
//! moment.js
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
2
public/js/build/817.js
vendored
1
public/js/build/855.js
vendored
@ -1 +0,0 @@
|
|||||||
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[855],{45855:(t,e,s)=>{s.r(e),s.d(e,{default:()=>a});const n={data:function(){return{}},mounted:function(){this.$store.state.userId>0?this.goForward({path:"/manage/dashboard"},!0):this.goForward({path:"/login"},!0)},deactivated:function(){this.$destroy()}};const a=(0,s(51900).Z)(n,(function(){var t=this.$createElement;return(this._self._c||t)("div")}),[],!1,null,null,null).exports}}]);
|
|
||||||
3
public/js/build/856.js
vendored
2
public/js/build/862.js
vendored
2
public/js/build/889.js
vendored
1
public/js/build/907.js
vendored
Normal file
2
public/js/build/954.js
vendored
53
public/js/language.all.js
vendored
@ -448,5 +448,58 @@
|
|||||||
{"CN": "置顶该聊天","EN": "Top the chat","TC": "置頂該聊天","KM": "បញ្ចូលការជជែក","TH": "ด้านบนการแชท","KO": "채팅 상단","JA": "トップチャット"},
|
{"CN": "置顶该聊天","EN": "Top the chat","TC": "置頂該聊天","KM": "បញ្ចូលការជជែក","TH": "ด้านบนการแชท","KO": "채팅 상단","JA": "トップチャット"},
|
||||||
{"CN": "请输入正确的邀请码","EN": "Please enter the correct invitation code","TC": "請輸入正確的邀請碼","KM": "សូមបញ្ចូលលេខកូដអញ្ជើញត្រឹមត្រូវ","TH": "โปรดป้อนรหัสเชิญที่ถูกต้อง","KO": "올바른 초대 코드를 입력하십시오","JA": "正しい招待状コードを入力してください"},
|
{"CN": "请输入正确的邀请码","EN": "Please enter the correct invitation code","TC": "請輸入正確的邀請碼","KM": "សូមបញ្ចូលលេខកូដអញ្ជើញត្រឹមត្រូវ","TH": "โปรดป้อนรหัสเชิญที่ถูกต้อง","KO": "올바른 초대 코드를 입력하십시오","JA": "正しい招待状コードを入力してください"},
|
||||||
{"CN": "置顶","EN": "Topping","TC": "置頂","KM": "ការបញ្ចូល","TH": "โรยหน้า","KO": "토핑","JA": "トッピング"},
|
{"CN": "置顶","EN": "Topping","TC": "置頂","KM": "ការបញ្ចូល","TH": "โรยหน้า","KO": "토핑","JA": "トッピング"},
|
||||||
|
{"CN": "立即登录","EN": "Log in immediately","TC": "立即登錄","KM": "ចូលភ្លាមៗ","TH": "เข้าสู่ระบบทันที","KO": "즉시 로그인하십시오","JA": "すぐにログインします"},
|
||||||
|
{"CN": "轻量级任务管理工具","EN": "Lightweight task management tool","TC": "輕量級任務管理工具","KM": "ឧបករណ៍គ្រប់គ្រងភារកិច្ចស្រាល","TH": "เครื่องมือการจัดการงานที่มีน้ำหนักเบา","KO": "경량 작업 관리 도구","JA": "軽量タスク管理ツール"},
|
||||||
|
{"CN": "DooTask是一款轻量级的开源在线项目任务管理工具,提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,文件管理等工具。","EN": "DOOTASK is a lightweight open source online project task management tool, providing various document collaboration tools, online-related map, online flow chart, project management, task distribution, instant IM, file management and other tools.","TC": "DooTask是一款輕量級的開源在線項目任務管理工具,提供各類文檔協作工具、在線思維導圖、在線流程圖、項目管理、任務分發、即時IM,文件管理等工具。","KM": "Takestask គឺជាឧបករណ៍នៃការគ្រប់គ្រងភារកិច្ចរបស់គំរោងតាមអ៊ិនធរណេតស្រាល ៗ ដែលផ្តល់នូវឧបករណ៍សហប្រតិបត្តិការឯកសារផ្សេងៗតារាងផែនទីតាមអ៊ីនធឺណិត, គំនូសតាងនៃការគ្រប់គ្រងលើអ៊ីនធឺណិត, ការគ្រប់គ្រងគម្រោង, ការ, ការងារ, ការគ្រប់គ្រងឯកសារ, ការគ្រប់គ្រងឯកសារនិងឧបករណ៍ផ្សេងទៀត។","TH": "DOOTASK เป็นเครื่องมือการจัดการงานโครงการออนไลน์โอเพ่นซอร์สที่มีน้ำหนักเบาให้เครื่องมือการทำงานร่วมกันเอกสารต่างๆแผนที่ที่เกี่ยวข้องกับออนไลน์แผนภูมิการไหลออนไลน์การจัดการโครงการการกระจายงาน IM ทันทีการจัดการไฟล์และเครื่องมืออื่น ๆ","KO": "DootAck는 다양한 문서 공동 작업 도구, 온라인 관련지도, 온라인 흐름도, 프로젝트 관리, 작업 배포, 인스턴트 IM, 파일 관리 및 기타 도구를 제공하는 가벼운 오픈 오픈 온라인 프로젝트 작업 관리 도구입니다.","JA": "DoTaskは、軽量なオープンソースのオンラインプロジェクトタスク管理ツールで、さまざまなドキュメントコラボレーションツール、オンライン関連マップ、オンラインフローチャート、プロジェクト管理、タスク配信、インスタントIM、ファイル管理などのツールを提供します。"},
|
||||||
|
{"CN": "高效便捷的团队沟通工具","EN": "Efficient and convenient team communication tool","TC": "高效便捷的團隊溝通工具","KM": "ឧបករណ៍ទំនាក់ទំនងក្រុមប្រកបដោយប្រសិទ្ធភាពនិងងាយស្រួល","TH": "เครื่องมือสื่อสารทีมที่มีประสิทธิภาพและสะดวกสบาย","KO": "효율적이고 편리한 팀 커뮤니케이션 도구","JA": "効率的で便利なチームコミュニケーションツール"},
|
||||||
|
{"CN": "针对项目和任务建立群组,工作问题可及时沟通,促进团队快速协作,提高团队工作效率。","EN": "To establish groups in projects and tasks, work issues can communicate in time, promoting team rapid collaboration, and improve teamwork efficiency.","TC": "針對項目和任務建立群組,工作問題可及時溝通,促進團隊快速協作,提高團隊工作效率。","KM": "ដើម្បីបង្កើតក្រុមក្នុងគម្រោងនិងភារកិច្ចបញ្ហាការងារអាចប្រាស្រ័យទាក់ទងបានទាន់ពេលវេលាលើកកម្ពស់ការសហការគ្នារបស់ក្រុមនិងធ្វើឱ្យប្រសើរឡើងនូវប្រសិទ្ធភាពក្នុងក្រុមជម្រើសជាតិ។","TH": "ในการสร้างกลุ่มในโครงการและภารกิจปัญหาการทำงานสามารถสื่อสารได้ในเวลาการส่งเสริมการทำงานร่วมกันอย่างรวดเร็วของทีมและปรับปรุงประสิทธิภาพการทำงานเป็นทีม","KO": "프로젝트 및 작업의 그룹을 수립하기 위해 작업 문제는 시간에 통신하고 팀의 신속한 협력을 촉진하고 팀워크 효율성을 향상시킬 수 있습니다.","JA": "プロジェクトやタスクでグループを確立するために、仕事の問題は時間内に通信し、チームの急速なコラボレーションを促進し、チームワークの効率を向上させることができます。"},
|
||||||
|
{"CN": "强大易用的协同创作云文档","EN": "Powerful easy-to-use collaborative creation cloud documentation","TC": "強大易用的協同創作雲文檔","KM": "ឯកសារ Cloud ការបង្កើតរួមគ្នាដែលមានអនុភាពដែលមានអនុភាព","TH": "เอกสารคลาวด์สร้างความร่วมมือที่ใช้งานง่ายที่ใช้งานง่าย","KO": "강력한 사용하기 쉬운 공동 작성 클라우드 문서","JA": "強力な使いやすい共同作成クラウド文書"},
|
||||||
|
{"CN": "汇集文档、电子表格、思维笔记等多种在线工具,汇聚企业知识资源于一处,支持多人实时协同编辑,让团队协作更便捷。","EN": "Collect a variety of online tools such as documentation, spreadsheets, thinking notes, gather in corporate knowledge resources, support multi-person real-time collaborative editing, making teamwork more convenient.","TC": "匯集文檔、電子表格、思維筆記等多種在線工具,匯聚企業知識資源於一處,支持多人實時協同編輯,讓團隊協作更便捷。","KM": "ប្រមូលប្រភេទឧបករណ៍តាមអ៊ិនធរណេតជាច្រើនប្រភេទបទប្បទានលក្ខណៈការគិតកំណត់ត្រាការគិតដែលប្រមូលផ្តុំនៅក្នុងធនធានចំណេះដឹងរបស់ក្រុមហ៊ុនគាំទ្រការកែប្រែសហការច្រើនរបស់អ្នកធ្វើការធ្វើឱ្យការងារជាក្រុមកាន់តែងាយស្រួល។","TH": "รวบรวมเครื่องมือออนไลน์ที่หลากหลายเช่นเอกสารสเปรดชีตบันทึกการคิดรวบรวมในทรัพยากรความรู้ขององค์กรสนับสนุนการแก้ไขการทำงานร่วมกันแบบเรียลไทม์หลายคนทำให้การทำงานเป็นทีมสะดวกยิ่งขึ้น","KO": "문서, 스프레드 시트, 사고 메모와 같은 다양한 온라인 도구를 수집하고 기업 지식 리소스를 모으고 다중 사람 실시간 협업 편집을 지원하여 팀워크를보다 편리하게 만듭니다.","JA": "ドキュメンテーション、スプレッドシート、思考ノートなどのさまざまなオンラインツールを収集し、企業のナレッジリソースに集まり、マルチパーソンリアルタイムの共同編集をサポートして、チームワークをより便利です。"},
|
||||||
|
{"CN": "便捷易用的项目管理模板","EN": "Conveniently used project management template","TC": "便捷易用的項目管理模板","KM": "គំរូនៃការគ្រប់គ្រងគម្រោងដែលប្រើយ៉ាងងាយស្រួល","TH": "ใช้แม่แบบการจัดการโครงการที่ใช้งานได้สะดวก","KO": "편리하게 사용되는 프로젝트 관리 템플릿","JA": "便利なプロジェクト管理テンプレートを使用しました"},
|
||||||
|
{"CN": "模版满足多种团队协作场景,同时支持自定义模版,满足团队个性化场景管理需求,可直观的查看项目的进展情况,团队协作更方便。","EN": "The template meets a variety of teamwork scenes, and supports custom template, meets the management needs of team personalized scenes, and visually view the progress of the project, and teamwork is more convenient.","TC": "模版滿足多種團隊協作場景,同時支持自定義模版,滿足團隊個性化場景管理需求,可直觀的查看項目的進展情況,團隊協作更方便。","KM": "ទំព័រគំរូនេះត្រូវនឹងឈុតឆាកការងារជាក្រុមជាច្រើននិងគាំទ្រគំរូផ្ទាល់ខ្លួនត្រូវឆ្លើយតបទៅនឹងតម្រូវការរបស់ការគ្រប់គ្រងនៃឈុតឆាកផ្ទាល់ខ្លួនរបស់ក្រុមនិងមើលវឌ្ឍនភាពនៃគម្រោងនេះនិងការងារជាក្រុមកាន់តែងាយស្រួល។","TH": "เทมเพลตตรงกับฉากการทำงานเป็นทีมที่หลากหลายและรองรับเทมเพลตที่กำหนดเองตรงตามความต้องการด้านการจัดการของฉากส่วนบุคคลของทีมและมองเห็นความคืบหน้าของโครงการและการทำงานเป็นทีมสะดวกกว่า","KO": "템플릿은 다양한 팀웍 장면을 충족하며 사용자 정의 템플릿을 지원하고 팀 개인화 된 장면의 관리 요구 사항을 충족시키고 시각적으로 프로젝트의 진행 상황을 볼 수 있으며 팀웍이 더 편리합니다.","JA": "テンプレートはさまざまなチームワークシーンを満たし、カスタムテンプレートをサポートし、チームパーソナライズされたシーンの管理ニーズを満たし、プロジェクトの進行状況を視覚的に表示し、チームワークはより便利です。"},
|
||||||
|
{"CN": "清晰直观的任务日历","EN": "Clear and intuitive task calendar","TC": "清晰直觀的任務日曆","KM": "ប្រតិទិនភារកិច្ចច្បាស់លាស់និងវិចារណញាណ","TH": "ปฏิทินงานที่ชัดเจนและใช้งานง่าย","KO": "명확하고 직관적 인 작업 일정","JA": "クリアで直感的なタスクカレンダー"},
|
||||||
|
{"CN": "通过灵活的任务日历,轻松安排每一天的日程,把任务拆解到每天,让工作目标更清晰,时间分配更合理。","EN": "Through the flexible task calendar, easily arrange the daily schedule, disassemble the task to every day, let the work goals clearer, time allocation is more reasonable.","TC": "通過靈活的任務日曆,輕鬆安排每一天的日程,把任務拆解到每天,讓工作目標更清晰,時間分配更合理。","KM": "តាមរយៈប្រតិទិនភារកិច្ចដែលអាចបត់បែនបានរៀបចំឱ្យមានកាលវិភាគប្រចាំថ្ងៃដោយងាយផ្តាច់ភារកិច្ចឡើងវិញជារៀងរាល់ថ្ងៃឱ្យគោលដៅការងារកាន់តែច្បាស់ការបែងចែកពេលវេលាគឺសមហេតុផលជាង។","TH": "ผ่านปฏิทินงานที่ยืดหยุ่นจัดเรียงตารางประจำวันได้อย่างง่ายดายถอดชิ้นส่วนงานทุกวันปล่อยให้เป้าหมายการทำงานชัดเจนขึ้นการจัดสรรเวลานั้นสมเหตุสมผลมากขึ้น","KO": "유연한 작업 일정을 통해 일일 일정을 쉽게 준비하고, 매일 작업을 분해하고, 작업 목표를 더 명확하게, 시간 할당이 더 많습니다.","JA": "柔軟なタスクカレンダーを通して、毎日のスケジュールを簡単に調整し、タスクを毎日分解し、作業目標をより明確にして、時間割り当てがより合理的なものです。"},
|
||||||
|
{"CN": "开启您的 Dootask 团队协作","EN": "Open your DOOTASK team collaboration","TC": "開啟您的 Dootask 團隊協作","KM": "បើកកិច្ចសហប្រតិបត្តិការក្រុមរបស់អ្នក","TH": "เปิดการทำงานร่วมกันของทีม DOOTASK ของคุณ","KO": "Dootask 팀 공동 작업을 엽니 다","JA": "あなたのdootaskチームコラボレーションを開く"},
|
||||||
|
{"CN": "联系我们","EN": "Contact us","TC": "聯繫我們","KM": "ទាក់ទងមកពួកយើង","TH": "ติดต่อเรา","KO": "문의하기","JA": "お問い合わせ"},
|
||||||
|
{"CN": "桂公网安备 31011002000058号 桂ICP备12020087号-3","EN": "Gui Gong Net Anni 31011002000058 Gui ICP No. 12020087 -3","TC": "桂公網安備 31011002000058號 桂ICP備12020087號-3","KM": "Gui Gong Net Net Ann 31011002000058 GUI ICP លេខ 12020087 -3","TH": "Gui Gong Net Anni 31011002000058 GUI ICP No. 12020087 -3","KO": "Gui Gong Net Anni 31011002000058 GUI ICP No. 12020087 -3","JA": "GUI GONG NET ANNI 31011002000058 GUI ICP No. 12020087 -3"},
|
||||||
|
{"CN": "主题皮肤","EN": "Topic skin","TC": "主題皮膚","KM": "ស្បែកប្រធានបទ","TH": "ผิวหนัง","KO": "주제 피부","JA": "トピックスキン"},
|
||||||
|
{"CN": "注册账号","EN": "Register an account","TC": "註冊賬號","KM": "ចុះឈ្មោះគណនី","TH": "ลงทะเบียนบัญชี","KO": "계정을 등록하십시오","JA": "アカウントを登録"},
|
||||||
|
{"CN": "账号不存在,请确认账号是否输入正确","EN": "If the account does not exist, please confirm if the account is entered correct.","TC": "賬號不存在,請確認賬號是否輸入正確","KM": "ប្រសិនបើគណនីមិនមានសូមបញ្ជាក់ប្រសិនបើគណនីត្រូវបានបញ្ចូលត្រឹមត្រូវ។","TH": "หากบัญชีไม่มีอยู่โปรดยืนยันว่าบัญชีถูกป้อนที่ถูกต้องหรือไม่","KO": "계정이 존재하지 않으면 확인하면서 확인하십시오.","JA": "アカウントが存在しない場合は、アカウントが正しいかどうかを確認してください。"},
|
||||||
|
{"CN": "密码错误,请输入正确密码","EN": "Password error, please enter the correct password","TC": "密碼錯誤,請輸入正確密碼","KM": "កំហុសពាក្យសម្ងាត់សូមបញ្ចូលពាក្យសម្ងាត់ត្រឹមត្រូវ","TH": "ข้อผิดพลาดรหัสผ่านโปรดป้อนรหัสผ่านที่ถูกต้อง","KO": "암호 오류가 올바른 암호를 입력하십시오","JA": "パスワードエラー、正しいパスワードを入力してください"},
|
||||||
|
{"CN": "任务优先级","EN": "Task priority","TC": "任務優先級","KM": "អាទិភាពកិច្ចការ","TH": "ลำดับความสำคัญของงาน","KO": "작업 우선 순위","JA": "タスクの優先順位"},
|
||||||
|
{"CN": "邮件设置","EN": "E-Mail settings","TC": "郵件設置","KM": "ការកំណត់អ៊ីម៉ែល","TH": "การตั้งค่าอีเมล","KO": "전자 메일 설정","JA": "電子メール設定"},
|
||||||
|
{"CN": "邮箱服务器设置","EN": "Mailbox server settings","TC": "郵箱服務器設置","KM": "ការកំណត់ម៉ាស៊ីនមេប្រអប់សំបុត្រ","TH": "การตั้งค่าเซิร์ฟเวอร์กล่องจดหมาย","KO": "사서함 서버 설정","JA": "メールボックスサーバーの設定"},
|
||||||
|
{"CN": "SMTP服务器","EN": "SMTP server","TC": "SMTP服務器","KM": "ម៉ាស៊ីនមេ SMTP","TH": "เซิร์ฟเวอร์ SMTP","KO": "SMTP 서버","JA": "SMTPサーバー"},
|
||||||
|
{"CN": "端口","EN": "Port","TC": "端口","KM": "កមបង់ផេ","TH": "ท่า","KO": "포트","JA": "港"},
|
||||||
|
{"CN": "账号","EN": "Account","TC": "賬號","KM": "កននេយ្យ","TH": "บัญชีผู้ใช้","KO": "계정","JA": "アカウント"},
|
||||||
|
{"CN": "密码","EN": "Password","TC": "密碼","KM": "ហក្យសមងាត់","TH": "รหัสผ่าน","KO": "비밀번호","JA": "パスワード"},
|
||||||
|
{"CN": "邮件通知设置","EN": "Mail notification setting","TC": "郵件通知設置","KM": "ការកំណត់ការជូនដំណឹងតាមសំបុត្រ","TH": "การตั้งค่าการแจ้งเตือนทางไปรษณีย์","KO": "메일 알림 설정","JA": "メール通知の設定"},
|
||||||
|
{"CN": "开启注册验证","EN": "Open registration verification","TC": "開啟註冊驗證","KM": "ការផ្ទៀងផ្ទាត់ការចុះឈ្មោះបើកចំហ","TH": "เปิดการตรวจสอบการลงทะเบียน","KO": "오픈 등록 확인","JA": "オープン登録検証"},
|
||||||
|
{"CN": "开启后账号需验证通过才可登录","EN": "After the account is required to verify it, you can log in.","TC": "開啟後賬號需驗證通過才可登錄","KM": "បន្ទាប់ពីគណនីតម្រូវឱ្យផ្ទៀងផ្ទាត់វាអ្នកអាចចូលបាន។","TH": "หลังจากบัญชีที่จำเป็นต้องตรวจสอบแล้วคุณสามารถเข้าสู่ระบบได้","KO": "계정을 확인하려면 계정이 필요하면 로그인 할 수 있습니다.","JA": "確認が必要な場合は、ログインできます。"},
|
||||||
|
{"CN": "开启通知","EN": "Open notification","TC": "開啟通知","KM": "ការជូនដំណឹងបើក","TH": "เปิดการแจ้งเตือน","KO": "오픈 알림","JA": "オープン通知"},
|
||||||
|
{"CN": "任务提醒:","EN": "Task reminder:","TC": "任務提醒:","KM": "ការរំលឹកភារកិច្ច:","TH": "เตือนงาน:","KO": "작업 알림 :","JA": "タスクリマインダー:"},
|
||||||
|
{"CN": "到期前","EN": "Before the expiration","TC": "到期前","KM": "មុនពេលផុតកំណត់","TH": "ก่อนที่จะหมดอายุ","KO": "원정대 전에","JA": "満了前に"},
|
||||||
|
{"CN": "第二次任务提醒:","EN": "Second task reminder:","TC": "第二次任務提醒:","KM": "ការរំលឹកភារកិច្ចលើកទីពីរ:","TH": "เตือนงานที่สอง:","KO": "두 번째 작업 알림 :","JA": "2番目のタスクの通知:"},
|
||||||
|
{"CN": "到期后","EN": "After the expiration","TC": "到期後","KM": "បន្ទាប់ពីការផុតកំណត់","TH": "หลังจากหมดอายุ","KO": "원정대 후에","JA": "満了後"},
|
||||||
|
{"CN": "小时","EN": "Hour","TC": "小時","KM": "ម៉ោង","TH": "ชั่วโมง","KO": "시","JA": "時間"},
|
||||||
|
{"CN": "自动:密码输入错误后必须添加验证码。","EN": "Auto: The verification code must be added after password input error.","TC": "自動:密碼輸入錯誤後必須添加驗證碼。","KM": "ស្វ័យប្រវត្តិ: លេខកូដផ្ទៀងផ្ទាត់ត្រូវតែបន្ថែមកំហុសក្នុងកំហុសពាក្យសម្ងាត់។","TH": "อัตโนมัติ: ต้องเพิ่มรหัสยืนยันหลังจากข้อผิดพลาดในการป้อนรหัสผ่าน","KO": "AUTO : 암호 입력 오류가 발생한 후 확인 코드를 추가해야합니다.","JA": "AUTO:パスワード入力エラー後に検証コードを追加する必要があります。"},
|
||||||
|
{"CN": "密码策略","EN": "Password policy","TC": "密碼策略","KM": "គោលការណ៍ពាក្យសម្ងាត់","TH": "นโยบายรหัสผ่าน","KO": "암호 정책","JA": "パスワードポリシー"},
|
||||||
|
{"CN": "简单","EN": "Simple","TC": "簡單","KM": "តេឯកឯង","TH": "เรียบง่าย","KO": "단순한","JA": "単純"},
|
||||||
|
{"CN": "复杂","EN": "Complex","TC": "複雜","KM": "អបផាក","TH": "ซับซ้อน","KO": "복잡한","JA": "繁雑"},
|
||||||
|
{"CN": "简单:大于或等于6个字符。","EN": "Simple: greater than or equal to 6 characters.","TC": "簡單:大於或等於6個字符。","KM": "សាមញ្ញ: ធំជាងឬស្មើ 6 តួអក្សរ។","TH": "ง่าย: มากกว่าหรือเท่ากับ 6 ตัวอักษร","KO": "단순 : 6 자 이상 이상.","JA": "単純:6文字以上。"},
|
||||||
|
{"CN": "复杂:大于或等于6个字符,包含数字、字母大小写或者特殊字符。","EN": "Complex: greater than or equal to 6 characters, including numbers, letters, or special characters.","TC": "複雜:大於或等於6個字符,包含數字、字母大小寫或者特殊字符。","KM": "ស្មុគស្មាញ: ធំជាងឬស្មើ 6 តួអក្សររួមទាំងលេខអក្សរឬតួអក្សរពិសេស។","TH": "คอมเพล็กซ์: มากกว่าหรือเท่ากับ 6 ตัวอักษรรวมถึงตัวเลขตัวอักษรหรืออักขระพิเศษ","KO": "복잡한 : 숫자, 문자 또는 특수 문자를 포함하여 6 자 이상의 6 자 이상.","JA": "複合:数字、文字、または特殊文字を含む6文字以上。"},
|
||||||
|
{"CN": "邀请项目","EN": "Invitation project","TC": "邀請項目","KM": "គម្រោងលិខិតអញ្ជើញ","TH": "โครงการเชิญ","KO": "초대 프로젝트","JA": "招待状プロジェクト"},
|
||||||
|
{"CN": "开启:项目管理员可生成链接邀请成员加入项目。","EN": "Open: Project administrator can generate a link invitation member to join the project.","TC": "開啟:項目管理員可生成鏈接邀請成員加入項目。","KM": "Open: អ្នកគ្រប់គ្រងគម្រោងអាចបង្កើតនាយកដ្ឋានលិខិតអញ្ជើញភ្ជាប់ដើម្បីចូលរួមគម្រោងនេះ។","TH": "เปิด: ผู้ดูแลโครงการสามารถสร้างสมาชิกคำเชิญลิงก์เพื่อเข้าร่วมโครงการ","KO": "열기 : 프로젝트 관리자는 프로젝트에 가입하기 위해 링크 초대 구성원을 생성 할 수 있습니다.","JA": "Open:Project Administratorは、プロジェクトに参加するためのリンク招待メンバーを生成できます。"},
|
||||||
|
{"CN": "聊天昵称","EN": "Chat nickname","TC": "聊天暱稱","KM": "ឈ្មោះហៅក្រៅជជែក","TH": "ชื่อเล่นแชท","KO": "채팅 닉네임","JA": "チャットニックネーム"},
|
||||||
|
{"CN": "可选","EN": "Optional","TC": "可選","KM": "តាមចមរើស","TH": "ไม่จำเป็น","KO": "선택 과목","JA": "任意の"},
|
||||||
|
{"CN": "自动归档任务","EN": "Automatic archiving task","TC": "自動歸檔任務","KM": "ភារកិច្ចបណ្ណសារដោយស្វ័យប្រវត្តិ","TH": "งานเก็บถาวรอัตโนมัติ","KO": "자동 아카이빙 작업","JA": "自動アーカイブタスク"},
|
||||||
|
{"CN": "是否启动首页","EN": "Whether to start the home page","TC": "是否啟動首頁","KM": "ថាតើត្រូវចាប់ផ្តើមគេហទំព័រ","TH": "ไม่ว่าจะเริ่มต้นโฮมเพจ","KO": "홈 페이지를 시작할지 여부","JA": "ホームページを起動するかどうか"},
|
||||||
|
{"CN": "首页底部:首页底部网站备案号等信息","EN": "Home Bottom: Home Bottom Website Record No.","TC": "首頁底部:首頁底部網站備案號等信息","KM": "បាតផ្ទះ: គេហទំព័រកំណត់ត្រាគេហទំព័រលេខទំព័រដើម","TH": "หน้าแรกด้านล่าง: บันทึกเว็บไซต์ด้านล่างของหน้าแรก","KO": "홈 바닥 : 홈 하단 웹 사이트 레코드 번호","JA": "ホームボトム:ホームボトムウェブサイト記録番号"},
|
||||||
|
{"CN": "首页底部","EN": "Home bottom","TC": "首頁底部","KM": "បាតផ្ទះ","TH": "ก้นบ้าน","KO": "홈 바닥","JA": "ホームボトム"},
|
||||||
|
{"CN": "必填:发送聊天内容前必须设置昵称。","EN": "Required: You must set a nickname before sending chat content.","TC": "必填:發送聊天內容前必須設置暱稱。","KM": "ទាមទារ: អ្នកត្រូវតែដាក់ឈ្មោះហៅក្រៅមុនពេលផ្ញើមាតិកាជជែក។","TH": "ต้องการ: คุณต้องตั้งชื่อเล่นก่อนส่งเนื้อหาแชท","KO": "필수 : 채팅 콘텐츠를 보내기 전에 닉네임을 설정해야합니다.","JA": "必須:チャットコンテンツを送信する前にニックネームを設定する必要があります。"},
|
||||||
|
{"CN": "允许:开放注册功能。","EN": "Allow: Open registration function.","TC": "允許:開放註冊功能。","KM": "អនុញ្ញាត: បើកមុខងារចុះឈ្មោះ។","TH": "อนุญาตให้: เปิดฟังก์ชั่นการลงทะเบียน","KO": "허용 : 등록 기능을 엽니 다.","JA": "許可:オープン登録機能"},
|
||||||
|
{"CN": "邀请码:注册时需填写下方邀请码。","EN": "Invitation code: You need to fill in the following invitation code when registering.","TC": "邀請碼:註冊時需填寫下方邀請碼。","KM": "លេខកូដលិខិតអញ្ជើញ: អ្នកត្រូវបំពេញលេខកូដលិខិតអញ្ជើញខាងក្រោមនៅពេលចុះឈ្មោះ។","TH": "รหัสเชิญ: คุณต้องกรอกรหัสคำเชิญต่อไปนี้เมื่อลงทะเบียน","KO": "초대 코드 : 등록 할 때 다음 초대 코드를 입력해야합니다.","JA": "招待コード:登録時に次の招待コードを入力する必要があります。"},
|
||||||
|
{"CN": "添加模板","EN": "Add template","TC": "添加模板","KM": "បន្ថែមគំរូ","TH": "เพิ่มเทมเพลต","KO": "템플릿을 추가하십시오","JA": "テンプレートを追加します"},
|
||||||
|
{"CN": "版本","EN": "Version","TC": "版本","KM": "កមបុរក្នា","TH": "รุ่น","KO": "버전","JA": "バージョン"},
|
||||||
]
|
]
|
||||||
})(window)
|
})(window)
|
||||||
|
|||||||
1
resources/assets/js/language/index.js
vendored
@ -79,6 +79,7 @@ export default {
|
|||||||
this.addLanguageData(require("./language.js").default);
|
this.addLanguageData(require("./language.js").default);
|
||||||
this.addLanguageData(window.languageData);
|
this.addLanguageData(window.languageData);
|
||||||
//
|
//
|
||||||
|
|
||||||
languageListenerObjects.push((lang) => {
|
languageListenerObjects.push((lang) => {
|
||||||
this.languageType = lang;
|
this.languageType = lang;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,21 +1,267 @@
|
|||||||
<template>
|
<template>
|
||||||
<div></div>
|
<div v-if="needStartHome">
|
||||||
|
<div class="page-warp">
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="header-nav">
|
||||||
|
<div class="header-nav-box">
|
||||||
|
<div class="logo"></div>
|
||||||
|
</div>
|
||||||
|
<div class="header-nav-box">
|
||||||
|
<div class="header-right-one">
|
||||||
|
<Dropdown trigger="click" @on-click="setLanguage">
|
||||||
|
<Icon
|
||||||
|
class="header-right-one-language"
|
||||||
|
type="md-globe"
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href="javascript:void(0)"
|
||||||
|
class="header-right-one-dropdown"
|
||||||
|
v-if="screenWidth>441"
|
||||||
|
>
|
||||||
|
{{ currentLanguage }}
|
||||||
|
<Icon type="ios-arrow-down"></Icon>
|
||||||
|
</a>
|
||||||
|
<DropdownMenu slot="list">
|
||||||
|
<Dropdown-item
|
||||||
|
v-for="(item, key) in languageList"
|
||||||
|
:key="key"
|
||||||
|
:name="key"
|
||||||
|
:selected="getLanguage() === key"
|
||||||
|
>{{ item }}
|
||||||
|
</Dropdown-item>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
|
<div class="header-right-two" @click="register">
|
||||||
|
{{ $L("注册账号") }}
|
||||||
|
</div>
|
||||||
|
<div class="header-right-three" @click="login">
|
||||||
|
{{ $L("登录") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-content">
|
||||||
|
<div class="header-title header-title-one">Dootask</div>
|
||||||
|
<div class="header-title">
|
||||||
|
{{ $L("轻量级任务管理工具") }}
|
||||||
|
</div>
|
||||||
|
<div class="header-tips">
|
||||||
|
{{
|
||||||
|
$L("DooTask是一款轻量级的开源在线项目任务管理工具,提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时IM,文件管理等工具。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div class="login-buttom" @click="login">
|
||||||
|
{{ $L("登录") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header-bg"></div>
|
||||||
|
<div class="header-pic"></div>
|
||||||
|
</div>
|
||||||
|
<div class="page-main">
|
||||||
|
<div class="main-box-one">
|
||||||
|
<div class="box-one-square"></div>
|
||||||
|
<div class="box-pic" v-if="screenWidth<1920">
|
||||||
|
<img class="box-img" src="images/index/box-pic1.png" />
|
||||||
|
</div>
|
||||||
|
<div class="box-one-pic1" v-else>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="box-one-tips">
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("高效便捷的团队沟通工具") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("针对项目和任务建立群组,工作问题可及时沟通,促进团队快速协作,提高团队工作效率。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main-box-two" v-if="screenWidth>=1920">
|
||||||
|
<div class="box-two-tips">
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("强大易用的协同创作云文档") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("汇集文档、电子表格、思维笔记等多种在线工具,汇聚企业知识资源于一处,支持多人实时协同编辑,让团队协作更便捷。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-two-square"></div>
|
||||||
|
<div class="box-two-pic2"></div>
|
||||||
|
</div>
|
||||||
|
<div class="main-box-two" v-else>
|
||||||
|
<div class="box-two-tips">
|
||||||
|
<div class="box-pic">
|
||||||
|
<img class="box-img" src="images/index/box-pic2.png" />
|
||||||
|
</div>
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("强大易用的协同创作云文档") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("汇集文档、电子表格、思维笔记等多种在线工具,汇聚企业知识资源于一处,支持多人实时协同编辑,让团队协作更便捷。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="main-box-one">
|
||||||
|
<div class="box-one-square"></div>
|
||||||
|
<div class="box-pic" v-if="screenWidth<1920" >
|
||||||
|
<img class="box-img" src="images/index/box-pic3.png" />
|
||||||
|
</div>
|
||||||
|
<div class="box-one-pic3" v-else >
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="box-one-tips">
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("便捷易用的项目管理模板") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("模版满足多种团队协作场景,同时支持自定义模版,满足团队个性化场景管理需求,可直观的查看项目的进展情况,团队协作更方便。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main-box-two" v-if="screenWidth>=1920">
|
||||||
|
<div class="box-two-tips">
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("清晰直观的任务日历") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("通过灵活的任务日历,轻松安排每一天的日程,把任务拆解到每天,让工作目标更清晰,时间分配更合理。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box-two-square"></div>
|
||||||
|
<div class="box-two-pic4"></div>
|
||||||
|
</div>
|
||||||
|
<div class="main-box-two" v-else>
|
||||||
|
<div class="box-two-tips">
|
||||||
|
<div class="box-pic">
|
||||||
|
<img class="box-img" src="images/index/box-pic4.png" />
|
||||||
|
</div>
|
||||||
|
<div class="box-square"></div>
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("清晰直观的任务日历") }}
|
||||||
|
</div>
|
||||||
|
<div class="box-tips">
|
||||||
|
{{
|
||||||
|
$L("通过灵活的任务日历,轻松安排每一天的日程,把任务拆解到每天,让工作目标更清晰,时间分配更合理。")
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="page-footer">
|
||||||
|
<div class="footer-service">
|
||||||
|
<div class="footer-bg-box">
|
||||||
|
<div class="box-title">
|
||||||
|
{{ $L("开启您的 Dootask 团队协作") }}
|
||||||
|
</div>
|
||||||
|
<div class="buttom-box">
|
||||||
|
<div class="login-btn" @click="login">
|
||||||
|
{{ $L("立即登录") }}
|
||||||
|
</div>
|
||||||
|
<div class="contact-btn">{{ $L("联系我们") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-opyright" v-html="this.homeFooter"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
screenWidth: document.body.clientWidth,
|
||||||
|
needStartHome: false,
|
||||||
|
homeFooter: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
screenWidth(nVal) {
|
||||||
|
// console.log(nVal)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentLanguage() {
|
||||||
|
return this.languageList[this.languageType] || "Language";
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.getNeedStartHome();
|
||||||
|
const that = this;
|
||||||
|
window.onresize=()=>{
|
||||||
|
window.screenWidth=document.body.clientWidth
|
||||||
|
that.screenWidth=window.screenWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
login() {
|
||||||
|
this.goForward(
|
||||||
|
{
|
||||||
|
path: `/login`,
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
register() {
|
||||||
|
this.goForward(
|
||||||
|
{
|
||||||
|
path: `/login`,
|
||||||
|
query: {
|
||||||
|
type: "reg",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
},
|
||||||
|
getNeedStartHome() {
|
||||||
|
this.$store
|
||||||
|
.dispatch("call", {
|
||||||
|
url: "system/get/starthome",
|
||||||
|
})
|
||||||
|
.then(({data}) => {
|
||||||
|
this.homeFooter = data.home_footer;
|
||||||
if (this.$store.state.userId > 0) {
|
if (this.$store.state.userId > 0) {
|
||||||
this.goForward({path: '/manage/dashboard'}, true);
|
this.goForward({path: '/manage/dashboard'}, true);
|
||||||
} else {
|
} else {
|
||||||
|
this.needStartHome = !!data.need_start;
|
||||||
|
if (this.needStartHome === false) {
|
||||||
this.goForward({path: '/login'}, true);
|
this.goForward({path: '/login'}, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.needStartHome = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
deactivated() {
|
deactivated() {
|
||||||
this.$destroy()
|
// this.$destroy()
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -322,7 +322,11 @@ export default {
|
|||||||
});
|
});
|
||||||
}).catch(({data, msg}) => {
|
}).catch(({data, msg}) => {
|
||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
|
if (data.code === 1000) {
|
||||||
|
$A.modalSuccess(msg);
|
||||||
|
} else {
|
||||||
$A.modalError(msg);
|
$A.modalError(msg);
|
||||||
|
}
|
||||||
if (data.code === 'need') {
|
if (data.code === 'need') {
|
||||||
this.reCode();
|
this.reCode();
|
||||||
this.codeNeed = true;
|
this.codeNeed = true;
|
||||||
|
|||||||
@ -42,6 +42,30 @@
|
|||||||
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
<DropdownItem name="exportTask">{{$L('导出任务统计')}}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
<!--最近打开的任务-->
|
||||||
|
<Dropdown
|
||||||
|
v-else-if="item.path === 'taskBrowse'"
|
||||||
|
placement="right-start">
|
||||||
|
<DropdownItem divided>
|
||||||
|
<div class="manage-menu-flex">
|
||||||
|
{{$L(item.name)}}
|
||||||
|
<Icon type="ios-arrow-forward"></Icon>
|
||||||
|
</div>
|
||||||
|
</DropdownItem>
|
||||||
|
<DropdownMenu slot="list" v-if="taskBrowseLists.length > 0">
|
||||||
|
<DropdownItem
|
||||||
|
v-for="(item, key) in taskBrowseLists"
|
||||||
|
class="task-title"
|
||||||
|
:key="key"
|
||||||
|
@click.native="openTask(item)"
|
||||||
|
:name="item.name">{{ item.name }}</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
<DropdownMenu v-else slot="list">
|
||||||
|
<DropdownItem style="color: darkgrey;">
|
||||||
|
{{ $L('暂无打开记录') }}
|
||||||
|
</DropdownItem>
|
||||||
|
</DropdownMenu>
|
||||||
|
</Dropdown>
|
||||||
<!-- 主题皮肤 -->
|
<!-- 主题皮肤 -->
|
||||||
<Dropdown
|
<Dropdown
|
||||||
v-else-if="item.path === 'theme'"
|
v-else-if="item.path === 'theme'"
|
||||||
@ -131,6 +155,7 @@
|
|||||||
<div class="project-h1">
|
<div class="project-h1">
|
||||||
<em @click.stop="toggleOpenMenu(item.id)"></em>
|
<em @click.stop="toggleOpenMenu(item.id)"></em>
|
||||||
<div class="title">{{item.name}}</div>
|
<div class="title">{{item.name}}</div>
|
||||||
|
<img v-if="item.top_at" src="/images/mark.svg" class="icon-top">
|
||||||
<div v-if="item.task_my_num - item.task_my_complete > 0" class="num">{{item.task_my_num - item.task_my_complete}}</div>
|
<div v-if="item.task_my_num - item.task_my_complete > 0" class="num">{{item.task_my_num - item.task_my_complete}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="project-h2">
|
<div class="project-h2">
|
||||||
@ -248,6 +273,12 @@
|
|||||||
style="width:100%"
|
style="width:100%"
|
||||||
:placeholder="$L('请选择时间')"/>
|
:placeholder="$L('请选择时间')"/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
<FormItem prop="type" :label="$L('导出时间类型')">
|
||||||
|
<RadioGroup v-model="exportData.type">
|
||||||
|
<Radio label="taskTime">{{$L('任务时间')}}</Radio>
|
||||||
|
<Radio label="CreatedTime">{{$L('创建时间')}}</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
<div slot="footer" class="adaption">
|
<div slot="footer" class="adaption">
|
||||||
<Button type="default" @click="exportTaskShow=false">{{$L('取消')}}</Button>
|
<Button type="default" @click="exportTaskShow=false">{{$L('取消')}}</Button>
|
||||||
@ -363,6 +394,7 @@ export default {
|
|||||||
exportData: {
|
exportData: {
|
||||||
userid: [],
|
userid: [],
|
||||||
time: [],
|
time: [],
|
||||||
|
type:'taskTime',
|
||||||
},
|
},
|
||||||
|
|
||||||
dialogMsgSubscribe: null,
|
dialogMsgSubscribe: null,
|
||||||
@ -450,7 +482,8 @@ export default {
|
|||||||
|
|
||||||
'wsMsg',
|
'wsMsg',
|
||||||
|
|
||||||
'clientNewVersion'
|
'clientNewVersion',
|
||||||
|
'cacheTaskBrowse'
|
||||||
]),
|
]),
|
||||||
|
|
||||||
...mapGetters(['taskData', 'dashboardTask']),
|
...mapGetters(['taskData', 'dashboardTask']),
|
||||||
@ -489,6 +522,8 @@ export default {
|
|||||||
|
|
||||||
{path: 'team', name: '团队管理', divided: true},
|
{path: 'team', name: '团队管理', divided: true},
|
||||||
|
|
||||||
|
{path: 'taskBrowse', name: '最近打开的任务', divided: true},
|
||||||
|
|
||||||
{path: 'theme', name: '主题皮肤', divided: true},
|
{path: 'theme', name: '主题皮肤', divided: true},
|
||||||
|
|
||||||
{path: 'language', name: this.currentLanguage, divided: true},
|
{path: 'language', name: this.currentLanguage, divided: true},
|
||||||
@ -506,6 +541,8 @@ export default {
|
|||||||
{path: 'workReport', name: '工作报告', divided: true},
|
{path: 'workReport', name: '工作报告', divided: true},
|
||||||
{path: 'archivedProject', name: '已归档的项目'},
|
{path: 'archivedProject', name: '已归档的项目'},
|
||||||
|
|
||||||
|
{path: 'taskBrowse', name: '最近打开的任务', divided: true},
|
||||||
|
|
||||||
{path: 'theme', name: '主题皮肤', divided: true},
|
{path: 'theme', name: '主题皮肤', divided: true},
|
||||||
|
|
||||||
{path: 'language', name: this.currentLanguage, divided: true},
|
{path: 'language', name: this.currentLanguage, divided: true},
|
||||||
@ -550,7 +587,16 @@ export default {
|
|||||||
'overlay-y': true,
|
'overlay-y': true,
|
||||||
'overlay-none': this.topOperateVisible === true,
|
'overlay-none': this.topOperateVisible === true,
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
taskBrowseLists() {
|
||||||
|
const {cacheTaskBrowse} = this;
|
||||||
|
return $A.cloneJSON(cacheTaskBrowse).sort((a, b) => {
|
||||||
|
if (a.view_time || b.view_time) {
|
||||||
|
return b.view_time - a.view_time;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@ -569,6 +615,55 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
msgAllUnread() {
|
||||||
|
if (this.$Electron) {
|
||||||
|
this.$Electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dashboardTotal() {
|
||||||
|
if (this.$Electron) {
|
||||||
|
this.$Electron.ipcRenderer.send('setDockBadge', this.msgAllUnread + this.dashboardTotal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dialogMsgPush(data) {
|
||||||
|
if (this.natificationHidden && this.natificationReady) {
|
||||||
|
const {id, dialog_id, type, msg} = data;
|
||||||
|
let body = '';
|
||||||
|
switch (type) {
|
||||||
|
case 'text':
|
||||||
|
body = msg.text;
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
body = '[' + this.$L(msg.type == 'img' ? '图片信息' : '文件信息') + ']'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._notificationId = id;
|
||||||
|
this.notificationClass.replaceOptions({
|
||||||
|
icon: $A.originUrl('images/logo.png'),
|
||||||
|
body: body,
|
||||||
|
data: data,
|
||||||
|
tag: "dialog",
|
||||||
|
requireInteraction: true
|
||||||
|
});
|
||||||
|
let dialog = this.dialogs.find((item) => item.id == dialog_id);
|
||||||
|
if (dialog) {
|
||||||
|
this.notificationClass.replaceTitle(dialog.name);
|
||||||
|
this.notificationClass.userAgreed();
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch("getDialogOne", dialog_id).then(({data}) => {
|
||||||
|
if (this._notificationId === id) {
|
||||||
|
this.notificationClass.replaceTitle(data.name);
|
||||||
|
this.notificationClass.userAgreed();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
projectKeyValue(val) {
|
projectKeyValue(val) {
|
||||||
if (val == '') {
|
if (val == '') {
|
||||||
return;
|
return;
|
||||||
@ -723,7 +818,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
"active": this.curPath == '/manage/' + path,
|
"active": this.curPath == '/manage/' + path,
|
||||||
"open-menu": openMenu === true,
|
"open-menu": openMenu === true,
|
||||||
"top": item.top_at,
|
|
||||||
"operate": item.id == this.topOperateItem.id && this.topOperateVisible
|
"operate": item.id == this.topOperateItem.id && this.topOperateVisible
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -982,6 +1076,10 @@ export default {
|
|||||||
}
|
}
|
||||||
document.addEventListener(visibilityChangeEvent, visibilityChangeListener);
|
document.addEventListener(visibilityChangeEvent, visibilityChangeListener);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openTask(task) {
|
||||||
|
this.$store.dispatch("openTask", task)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -361,7 +361,7 @@ export default {
|
|||||||
content: '你确定要删除任务【' + data.name + '】吗?',
|
content: '你确定要删除任务【' + data.name + '】吗?',
|
||||||
loading: true,
|
loading: true,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
this.$store.dispatch("removeTask", data.id).then(({msg}) => {
|
this.$store.dispatch("removeTask", {task_id: data.id}).then(({msg}) => {
|
||||||
$A.messageSuccess(msg);
|
$A.messageSuccess(msg);
|
||||||
this.$Modal.remove();
|
this.$Modal.remove();
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="tuiCalendar" class="calendar-wrapper"></div>
|
<div ref="tuiCalendar" className="calendar-wrapper"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Calendar from 'tui-calendar-hi';
|
import Calendar from 'tui-calendar-hi';
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<h2>{{dialogData.name}}</h2>
|
<h2>{{dialogData.name}}</h2>
|
||||||
<em v-if="peopleNum > 0">({{peopleNum}})</em>
|
<em v-if="peopleNum > 0">({{peopleNum}})</em>
|
||||||
|
<label v-if="dialogData.top_at" class="top-text">{{$L('置顶')}}</label>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="dialogData.type === 'group'">
|
<template v-if="dialogData.type === 'group'">
|
||||||
<div v-if="dialogData.group_type === 'project'" class="sub-title pointer" @click="openProject">
|
<div v-if="dialogData.group_type === 'project'" class="sub-title pointer" @click="openProject">
|
||||||
|
|||||||
@ -55,6 +55,7 @@
|
|||||||
<EDropdownItem command="invite">{{$L('邀请链接')}}</EDropdownItem>
|
<EDropdownItem command="invite">{{$L('邀请链接')}}</EDropdownItem>
|
||||||
<EDropdownItem command="log" divided>{{$L('项目动态')}}</EDropdownItem>
|
<EDropdownItem command="log" divided>{{$L('项目动态')}}</EDropdownItem>
|
||||||
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
||||||
|
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="transfer" divided>{{$L('移交项目')}}</EDropdownItem>
|
<EDropdownItem command="transfer" divided>{{$L('移交项目')}}</EDropdownItem>
|
||||||
<EDropdownItem command="archived">{{$L('归档项目')}}</EDropdownItem>
|
<EDropdownItem command="archived">{{$L('归档项目')}}</EDropdownItem>
|
||||||
<EDropdownItem command="delete" style="color:#f40">{{$L('删除项目')}}</EDropdownItem>
|
<EDropdownItem command="delete" style="color:#f40">{{$L('删除项目')}}</EDropdownItem>
|
||||||
@ -62,6 +63,7 @@
|
|||||||
<EDropdownMenu v-else slot="dropdown">
|
<EDropdownMenu v-else slot="dropdown">
|
||||||
<EDropdownItem command="log">{{$L('项目动态')}}</EDropdownItem>
|
<EDropdownItem command="log">{{$L('项目动态')}}</EDropdownItem>
|
||||||
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
||||||
|
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="exit" divided style="color:#f40">{{$L('退出项目')}}</EDropdownItem>
|
<EDropdownItem command="exit" divided style="color:#f40">{{$L('退出项目')}}</EDropdownItem>
|
||||||
</EDropdownMenu>
|
</EDropdownMenu>
|
||||||
</EDropdown>
|
</EDropdown>
|
||||||
@ -431,6 +433,14 @@
|
|||||||
:size="900">
|
:size="900">
|
||||||
<TaskArchived v-if="archivedTaskShow" :project-id="projectId"/>
|
<TaskArchived v-if="archivedTaskShow" :project-id="projectId"/>
|
||||||
</DrawerOverlay>
|
</DrawerOverlay>
|
||||||
|
|
||||||
|
<!--查看已删除任务-->
|
||||||
|
<DrawerOverlay
|
||||||
|
v-model="deletedTaskShow"
|
||||||
|
placement="right"
|
||||||
|
:size="900">
|
||||||
|
<TaskDeleted v-if="deletedTaskShow" :project-id="projectId"/>
|
||||||
|
</DrawerOverlay>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -452,6 +462,7 @@ import ProjectLog from "./ProjectLog";
|
|||||||
import DrawerOverlay from "../../../components/DrawerOverlay";
|
import DrawerOverlay from "../../../components/DrawerOverlay";
|
||||||
import ProjectWorkflow from "./ProjectWorkflow";
|
import ProjectWorkflow from "./ProjectWorkflow";
|
||||||
import TaskMenu from "./TaskMenu";
|
import TaskMenu from "./TaskMenu";
|
||||||
|
import TaskDeleted from "./TaskDeleted";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ProjectList",
|
name: "ProjectList",
|
||||||
@ -459,7 +470,7 @@ export default {
|
|||||||
TaskMenu,
|
TaskMenu,
|
||||||
ProjectWorkflow,
|
ProjectWorkflow,
|
||||||
DrawerOverlay,
|
DrawerOverlay,
|
||||||
ProjectLog, TaskArchived, TaskRow, Draggable, TaskAddSimple, UserInput, TaskAdd, TaskPriority},
|
ProjectLog, TaskArchived, TaskRow, Draggable, TaskAddSimple, UserInput, TaskAdd, TaskPriority, TaskDeleted },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -500,6 +511,7 @@ export default {
|
|||||||
workflowShow: false,
|
workflowShow: false,
|
||||||
logShow: false,
|
logShow: false,
|
||||||
archivedTaskShow: false,
|
archivedTaskShow: false,
|
||||||
|
deletedTaskShow: false,
|
||||||
|
|
||||||
projectDialogSubscribe: null,
|
projectDialogSubscribe: null,
|
||||||
|
|
||||||
@ -1180,6 +1192,10 @@ export default {
|
|||||||
this.archivedTaskShow = true;
|
this.archivedTaskShow = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "deleted_task":
|
||||||
|
this.deletedTaskShow = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case "transfer":
|
case "transfer":
|
||||||
this.$set(this.transferData, 'owner_userid', [this.projectData.owner_userid]);
|
this.$set(this.transferData, 'owner_userid', [this.projectData.owner_userid]);
|
||||||
this.transferShow = true;
|
this.transferShow = true;
|
||||||
|
|||||||
@ -42,6 +42,12 @@
|
|||||||
<div class="subtitle">{{$L('可设置多个状态为进行中')}}</div>
|
<div class="subtitle">{{$L('可设置多个状态为进行中')}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="taskflow-config-table-block-item">
|
||||||
|
<div>
|
||||||
|
<div class="title">{{$L('验收/测试')}}</div>
|
||||||
|
<div class="subtitle">{{$L('只能设置单个状态为验收/测试')}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="taskflow-config-table-block-item">
|
<div class="taskflow-config-table-block-item">
|
||||||
<div>
|
<div>
|
||||||
<div class="title">{{$L('结束状态')}}</div>
|
<div class="title">{{$L('结束状态')}}</div>
|
||||||
@ -113,6 +119,7 @@
|
|||||||
<RadioGroup v-model="item.status">
|
<RadioGroup v-model="item.status">
|
||||||
<Radio label="start"><span></span></Radio>
|
<Radio label="start"><span></span></Radio>
|
||||||
<Radio label="progress"><span></span></Radio>
|
<Radio label="progress"><span></span></Radio>
|
||||||
|
<Radio label="test"><span></span></Radio>
|
||||||
<Radio label="end"><span></span></Radio>
|
<Radio label="end"><span></span></Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
@ -295,6 +302,15 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": -12,
|
"id": -12,
|
||||||
|
"name": "待测试",
|
||||||
|
"status": "test",
|
||||||
|
"turns": [-10, -11, -12, -13],
|
||||||
|
"userids": [],
|
||||||
|
"usertype": 'add',
|
||||||
|
"userlimit": 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": -13,
|
||||||
"name": "已完成",
|
"name": "已完成",
|
||||||
"status": "end",
|
"status": "end",
|
||||||
"turns": [-10, -11, -12, -13],
|
"turns": [-10, -11, -12, -13],
|
||||||
@ -303,7 +319,7 @@ export default {
|
|||||||
"userlimit": 0,
|
"userlimit": 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": -13,
|
"id": -14,
|
||||||
"name": "已取消",
|
"name": "已取消",
|
||||||
"status": "end",
|
"status": "end",
|
||||||
"turns": [-10, -11, -12, -13],
|
"turns": [-10, -11, -12, -13],
|
||||||
|
|||||||
@ -300,7 +300,7 @@ export default {
|
|||||||
delete(row) {
|
delete(row) {
|
||||||
this.list = this.list.filter(({id}) => id != row.id);
|
this.list = this.list.filter(({id}) => id != row.id);
|
||||||
this.loadIng++;
|
this.loadIng++;
|
||||||
this.$store.dispatch("removeTask", row.id).then(({msg}) => {
|
this.$store.dispatch("removeTask", {task_id: row.id}).then(({msg}) => {
|
||||||
$A.messageSuccess(msg);
|
$A.messageSuccess(msg);
|
||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
this.getLists();
|
this.getLists();
|
||||||
|
|||||||
104
resources/assets/js/pages/manage/components/TaskDashboard.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<ul class="dashboard-list overlay-y">
|
||||||
|
<li
|
||||||
|
v-for="(item, index) in list"
|
||||||
|
:key="index"
|
||||||
|
:class="{complete: item.complete_at}"
|
||||||
|
:style="item.color ? {backgroundColor: item.color} : {}"
|
||||||
|
@click="openTask(item)">
|
||||||
|
<em
|
||||||
|
v-if="item.p_name"
|
||||||
|
class="priority-color"
|
||||||
|
:style="{backgroundColor:item.p_color}"></em>
|
||||||
|
<TaskMenu :ref="`taskMenu_${item.id}`" :task="item">
|
||||||
|
<div slot="icon" class="drop-icon" @click.stop="">
|
||||||
|
<i class="taskfont" v-html="item.complete_at ? '' : ''"></i>
|
||||||
|
</div>
|
||||||
|
</TaskMenu>
|
||||||
|
<div class="item-title">
|
||||||
|
<!--工作流状态-->
|
||||||
|
<span v-if="item.flow_item_name" :class="item.flow_item_status"
|
||||||
|
@click.stop="openMenu(item)">{{ item.flow_item_name }}</span>
|
||||||
|
<!--是否子任务-->
|
||||||
|
<span v-if="item.sub_top === true">{{ $L('子任务') }}</span>
|
||||||
|
<!--有多少个子任务-->
|
||||||
|
<span v-if="item.sub_my && item.sub_my.length > 0">+{{ item.sub_my.length }}</span>
|
||||||
|
<!--任务描述-->
|
||||||
|
{{ item.name }}
|
||||||
|
</div>
|
||||||
|
<div v-if="item.desc" class="item-icon">
|
||||||
|
<i class="taskfont"></i>
|
||||||
|
</div>
|
||||||
|
<div v-if="item.sub_num > 0" class="item-icon">
|
||||||
|
<i class="taskfont"></i>
|
||||||
|
<em>{{ item.sub_complete }}/{{ item.sub_num }}</em>
|
||||||
|
</div>
|
||||||
|
<ETooltip v-if="item.end_at" :content="item.end_at" placement="right">
|
||||||
|
<div :class="['item-icon', item.today ? 'today' : '', item.overdue ? 'overdue' : '']">
|
||||||
|
<i class="taskfont"></i>
|
||||||
|
<em>{{ expiresFormat(item.end_at) }}</em>
|
||||||
|
</div>
|
||||||
|
</ETooltip>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TaskMenu from "../components/TaskMenu";
|
||||||
|
import {mapGetters, mapState} from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {TaskMenu},
|
||||||
|
name: "TaskDashboard",
|
||||||
|
props: {
|
||||||
|
list: {
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
nowTime: $A.Time(),
|
||||||
|
nowInterval: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.nowInterval = setInterval(() => {
|
||||||
|
this.nowTime = $A.Time();
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
clearInterval(this.nowInterval)
|
||||||
|
},
|
||||||
|
|
||||||
|
activated() {
|
||||||
|
this.$store.dispatch("getTaskForDashboard");
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivated() {
|
||||||
|
this.$store.dispatch("forgetTaskCompleteTemp", true);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openTask(task) {
|
||||||
|
this.$store.dispatch("openTask", task)
|
||||||
|
},
|
||||||
|
|
||||||
|
openMenu(task) {
|
||||||
|
const el = this.$refs[`taskMenu_${task.id}`];
|
||||||
|
if (el) {
|
||||||
|
el[0].handleClick()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
expiresFormat(date) {
|
||||||
|
return $A.countDownFormat(date, this.nowTime)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
286
resources/assets/js/pages/manage/components/TaskDeleted.vue
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
<template>
|
||||||
|
<div class="task-archived">
|
||||||
|
<div class="archived-title">
|
||||||
|
{{$L('删除的任务')}}
|
||||||
|
<div class="title-icon">
|
||||||
|
<Loading v-if="loadIng > 0"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="search-container lr">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="search-label">
|
||||||
|
{{$L("任务名")}}
|
||||||
|
</div>
|
||||||
|
<div class="search-content">
|
||||||
|
<Input v-model="keys.name" clearable/>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="search-button">
|
||||||
|
<Tooltip
|
||||||
|
theme="light"
|
||||||
|
placement="right"
|
||||||
|
transfer-class-name="search-button-clear"
|
||||||
|
transfer>
|
||||||
|
<Button :loading="loadIng > 0" type="primary" icon="ios-search" @click="getLists">{{$L('搜索')}}</Button>
|
||||||
|
<div slot="content">
|
||||||
|
<Button :loading="loadIng > 0" type="text" @click="getLists">{{$L('刷新')}}</Button>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<Table :columns="columns" :data="list" :loading="loadIng > 0" :no-data-text="$L(noText)"></Table>
|
||||||
|
<Page
|
||||||
|
class="page-container"
|
||||||
|
:total="total"
|
||||||
|
:current="page"
|
||||||
|
:pageSize="pageSize"
|
||||||
|
:disabled="loadIng > 0"
|
||||||
|
:simple="windowMax768"
|
||||||
|
showTotal
|
||||||
|
@on-change="setPage"
|
||||||
|
@on-page-size-change="setPageSize"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapState} from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TaskDeleted",
|
||||||
|
props: {
|
||||||
|
projectId: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loadIng: 0,
|
||||||
|
|
||||||
|
keys: {},
|
||||||
|
|
||||||
|
columns: [],
|
||||||
|
list: [],
|
||||||
|
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
noText: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['cacheTasks', 'windowMax768'])
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
projectId: {
|
||||||
|
handler() {
|
||||||
|
this.getLists();
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initLanguage() {
|
||||||
|
this.columns = [
|
||||||
|
{
|
||||||
|
title: this.$L('ID'),
|
||||||
|
minWidth: 50,
|
||||||
|
maxWidth: 70,
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$L('任务名称'),
|
||||||
|
key: 'name',
|
||||||
|
minWidth: 200,
|
||||||
|
render: (h, {row}) => {
|
||||||
|
return h('AutoTip', {
|
||||||
|
on: {
|
||||||
|
'on-click': () => {
|
||||||
|
this.$store.dispatch("openTask", row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, row.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$L('创建时间'),
|
||||||
|
key: 'created_at',
|
||||||
|
width: 168,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$L('删除时间'),
|
||||||
|
key: 'deleted_at',
|
||||||
|
width: 168,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$L('删除人员'),
|
||||||
|
key: 'deleted_userid',
|
||||||
|
minWidth: 100,
|
||||||
|
render: (h, {row}) => {
|
||||||
|
if (!row.deleted_userid) {
|
||||||
|
return h('span', '-');
|
||||||
|
}
|
||||||
|
return h('UserAvatar', {
|
||||||
|
props: {
|
||||||
|
userid: row.deleted_userid,
|
||||||
|
size: 24,
|
||||||
|
showName: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.$L('操作'),
|
||||||
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
|
render: (h, params) => {
|
||||||
|
const vNodes = [
|
||||||
|
h('span', {
|
||||||
|
style: {
|
||||||
|
fontSize: '13px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#8bcf70',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
'click': () => {
|
||||||
|
this.$store.dispatch("openTask", params.row);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, this.$L('查看')),
|
||||||
|
h('Poptip', {
|
||||||
|
props: {
|
||||||
|
title: this.$L('你确定要还原删除吗?'),
|
||||||
|
confirm: true,
|
||||||
|
transfer: true,
|
||||||
|
placement: 'left',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginLeft: '6px',
|
||||||
|
fontSize: '13px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#8bcf70',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
'on-ok': () => {
|
||||||
|
this.recovery(params.row);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, this.$L('还原')),
|
||||||
|
h('Poptip', {
|
||||||
|
props: {
|
||||||
|
title: this.$L('你确定要彻底删除任务吗?'),
|
||||||
|
confirm: true,
|
||||||
|
transfer: true,
|
||||||
|
placement: 'left',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
marginLeft: '6px',
|
||||||
|
fontSize: '13px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: '#f00',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
'on-ok': () => {
|
||||||
|
this.delete(params.row);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, this.$L('彻底删除'))
|
||||||
|
];
|
||||||
|
return h('TableAction', {
|
||||||
|
props: {
|
||||||
|
column: params.column
|
||||||
|
}
|
||||||
|
}, vNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
this.keys = {};
|
||||||
|
this.getLists()
|
||||||
|
},
|
||||||
|
|
||||||
|
getLists() {
|
||||||
|
if (!this.projectId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadIng++;
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'project/task/lists',
|
||||||
|
data: {
|
||||||
|
keys: this.keys,
|
||||||
|
project_id: this.projectId,
|
||||||
|
parent_id: -1,
|
||||||
|
deleted: 'yes',
|
||||||
|
sorts: {
|
||||||
|
deleted_at: 'desc'
|
||||||
|
},
|
||||||
|
page: Math.max(this.page, 1),
|
||||||
|
pagesize: Math.max($A.runNum(this.pageSize), 20),
|
||||||
|
},
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.loadIng--;
|
||||||
|
this.page = data.current_page;
|
||||||
|
this.total = data.total;
|
||||||
|
this.list = data.data;
|
||||||
|
this.noText = '没有相关的数据';
|
||||||
|
}).catch(() => {
|
||||||
|
this.loadIng--;
|
||||||
|
this.noText = '数据加载失败';
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
setPage(page) {
|
||||||
|
this.page = page;
|
||||||
|
this.getLists();
|
||||||
|
},
|
||||||
|
|
||||||
|
setPageSize(pageSize) {
|
||||||
|
this.page = 1;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.getLists();
|
||||||
|
},
|
||||||
|
|
||||||
|
recovery(row) {
|
||||||
|
this.list = this.list.filter(({id}) => id != row.id);
|
||||||
|
this.loadIng++;
|
||||||
|
this.$store.dispatch("removeTask", {
|
||||||
|
task_id: row.id,
|
||||||
|
type: 'recovery'
|
||||||
|
}).then(({msg}) => {
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
this.loadIng--;
|
||||||
|
this.getLists();
|
||||||
|
this.$store.dispatch("openTask", row);
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg);
|
||||||
|
this.loadIng--;
|
||||||
|
this.getLists();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
delete(row) {
|
||||||
|
this.list = this.list.filter(({id}) => id != row.id);
|
||||||
|
this.loadIng++;
|
||||||
|
this.$store.dispatch("removeTask", {
|
||||||
|
task_id: row.id,
|
||||||
|
type: 'completely_delete'
|
||||||
|
}).then(({msg}) => {
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
this.loadIng--;
|
||||||
|
this.getLists();
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg);
|
||||||
|
this.loadIng--;
|
||||||
|
this.getLists();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -74,6 +74,7 @@
|
|||||||
<div v-show="taskDetail.id > 0" class="task-info">
|
<div v-show="taskDetail.id > 0" class="task-info">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<TaskMenu
|
<TaskMenu
|
||||||
|
v-if="taskId > 0 && !taskDetail.deleted_at"
|
||||||
:ref="`taskMenu_${taskDetail.id}`"
|
:ref="`taskMenu_${taskDetail.id}`"
|
||||||
:disabled="taskId === 0"
|
:disabled="taskId === 0"
|
||||||
:task="taskDetail"
|
:task="taskDetail"
|
||||||
@ -87,6 +88,9 @@
|
|||||||
<div v-if="taskDetail.archived_at" class="flow">
|
<div v-if="taskDetail.archived_at" class="flow">
|
||||||
<span class="archived" @click.stop="openMenu(taskDetail)">{{$L('已归档')}}</span>
|
<span class="archived" @click.stop="openMenu(taskDetail)">{{$L('已归档')}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="taskDetail.deleted_at" class="flow">
|
||||||
|
<span class="archived">{{$L('已删除')}}</span>
|
||||||
|
</div>
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<p v-if="projectName"><span>{{projectName}}</span></p>
|
<p v-if="projectName"><span>{{projectName}}</span></p>
|
||||||
<p v-if="columnName"><span>{{columnName}}</span></p>
|
<p v-if="columnName"><span>{{columnName}}</span></p>
|
||||||
@ -117,14 +121,18 @@
|
|||||||
<Button :loading="ownerLoad > 0" size="small" type="primary" @click="onOwner(true)">确定</Button>
|
<Button :loading="ownerLoad > 0" size="small" type="primary" @click="onOwner(true)">确定</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button slot="reference" :loading="ownerLoad > 0" class="pick" type="primary">{{$L('我要领取任务')}}</Button>
|
<Button v-if="!taskDetail.deleted_at" slot="reference" :loading="ownerLoad > 0" class="pick" type="primary">{{$L('我要领取任务')}}</Button>
|
||||||
</EPopover>
|
</EPopover>
|
||||||
<ETooltip v-if="$Electron" :content="$L('新窗口打开')">
|
<ETooltip v-if="$Electron" :content="$L('新窗口打开')">
|
||||||
<i class="taskfont open" @click="openNewWin"></i>
|
<i class="taskfont open" @click="openNewWin"></i>
|
||||||
</ETooltip>
|
</ETooltip>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<TaskMenu
|
<TaskMenu
|
||||||
|
<<<<<<< HEAD
|
||||||
:disabled="taskId === 0"
|
:disabled="taskId === 0"
|
||||||
|
=======
|
||||||
|
v-if="taskId > 0 && !taskDetail.deleted_at"
|
||||||
|
>>>>>>> 00e666e423e8eddc31391cea724548b066a62f41
|
||||||
:task="taskDetail"
|
:task="taskDetail"
|
||||||
icon="ios-more"
|
icon="ios-more"
|
||||||
completed-icon="ios-more"
|
completed-icon="ios-more"
|
||||||
@ -340,7 +348,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
<div v-if="menuList.length > 0" class="add">
|
<div v-if="menuList.length > 0 && !taskDetail.deleted_at" class="add">
|
||||||
<EDropdown
|
<EDropdown
|
||||||
trigger="click"
|
trigger="click"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
@ -383,21 +391,21 @@
|
|||||||
<div class="head">
|
<div class="head">
|
||||||
<Icon class="icon" type="ios-chatbubbles-outline" />
|
<Icon class="icon" type="ios-chatbubbles-outline" />
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<p :class="{active:navActive=='dialog'}" @click="navActive='dialog'">{{$L('聊天')}}</p>
|
<p :class="{active:navActive=='dialog'}" @click="navActive='dialog'" v-if="!taskDetail.deleted_at">{{$L('聊天')}}</p>
|
||||||
<p :class="{active:navActive=='log'}" @click="navActive='log'">{{$L('动态')}}</p>
|
<p :class="{active:navActive=='log' || taskDetail.deleted_at}" @click="navActive='log'">{{$L('动态')}}</p>
|
||||||
<div v-if="navActive=='log'" class="refresh">
|
<div v-if="navActive=='log'" class="refresh">
|
||||||
<Loading v-if="logLoadIng"/>
|
<Loading v-if="logLoadIng"/>
|
||||||
<Icon v-else type="ios-refresh" @click="getLogLists"></Icon>
|
<Icon v-else type="ios-refresh" @click="getLogLists"></Icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ProjectLog v-if="navActive=='log' && taskId > 0" ref="log" :task-id="taskDetail.id" :show-load="false" @on-load-change="logLoadChange"/>
|
<ProjectLog v-if="(navActive=='log' || taskDetail.deleted_at) && taskId > 0" ref="log" :task-id="taskDetail.id" :show-load="false" @on-load-change="logLoadChange"/>
|
||||||
<div v-else class="no-dialog"
|
<div v-else class="no-dialog"
|
||||||
@drop.prevent="taskPasteDrag($event, 'drag')"
|
@drop.prevent="taskPasteDrag($event, 'drag')"
|
||||||
@dragover.prevent="taskDragOver(true, $event)"
|
@dragover.prevent="taskDragOver(true, $event)"
|
||||||
@dragleave.prevent="taskDragOver(false, $event)">
|
@dragleave.prevent="taskDragOver(false, $event)">
|
||||||
<div class="no-tip">{{$L('暂无消息')}}</div>
|
<div class="no-tip">{{$L('暂无消息')}}</div>
|
||||||
<div class="no-input">
|
<div class="no-input" v-if="!taskDetail.deleted_at">
|
||||||
<DragInput
|
<DragInput
|
||||||
class="dialog-input"
|
class="dialog-input"
|
||||||
v-model="msgText"
|
v-model="msgText"
|
||||||
|
|||||||
@ -287,7 +287,7 @@ export default {
|
|||||||
archivedOrRemoveTask(type) {
|
archivedOrRemoveTask(type) {
|
||||||
let typeDispatch = 'removeTask';
|
let typeDispatch = 'removeTask';
|
||||||
let typeName = '删除';
|
let typeName = '删除';
|
||||||
let typeData = this.task.id;
|
let typeData = {task_id: this.task.id};
|
||||||
let typeTask = this.task.parent_id > 0 ? '子任务' : '任务';
|
let typeTask = this.task.parent_id > 0 ? '子任务' : '任务';
|
||||||
if (type == 'archived') {
|
if (type == 'archived') {
|
||||||
typeDispatch = 'archivedTask'
|
typeDispatch = 'archivedTask'
|
||||||
|
|||||||
@ -85,6 +85,12 @@
|
|||||||
<DropdownItem @click.native="handleTopClick">
|
<DropdownItem @click.native="handleTopClick">
|
||||||
{{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }}
|
{{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
|
<DropdownItem @click.native="updateRead('read')" v-if="topOperateItem.unread > 0">
|
||||||
|
{{ $L('标记已读') }}
|
||||||
|
</DropdownItem>
|
||||||
|
<DropdownItem @click.native="updateRead('unread')" v-else>
|
||||||
|
{{ $L('标记未读') }}
|
||||||
|
</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
@ -482,6 +488,22 @@ export default {
|
|||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
$A.modalError(msg);
|
$A.modalError(msg);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateRead(type) {
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'dialog/msg/mark',
|
||||||
|
data: {
|
||||||
|
dialog_id: this.topOperateItem.id,
|
||||||
|
type: type
|
||||||
|
},
|
||||||
|
}).then(() => {
|
||||||
|
this.$store.dispatch("getDialogs");
|
||||||
|
this.$Modal.remove();
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg, 301);
|
||||||
|
this.$Modal.remove();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
136
resources/assets/js/pages/manage/setting/system/EmailSetting.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="setting-item submit">
|
||||||
|
<Form ref="formData" :model="formData" :rules="ruleData" label-width="auto" @submit.native.prevent>
|
||||||
|
<h3 style="margin-bottom: 15px;">{{ $L('邮箱服务器设置') }}</h3>
|
||||||
|
<FormItem :label="$L('SMTP服务器')" prop="smtp_server">
|
||||||
|
<Input v-model="formData.smtp_server"/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem :label="$L('端口')" prop="port">
|
||||||
|
<Input :maxlength="20" v-model="formData.port"/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem :label="$L('账号')" prop="account">
|
||||||
|
<Input :maxlength="20" v-model="formData.account"/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem :label="$L('密码')" prop="password">
|
||||||
|
<Input :maxlength="20" v-model="formData.password"/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<h3 style="margin-bottom: 15px;">{{ $L('邮件通知设置') }}</h3>
|
||||||
|
<FormItem :label="$L('开启注册验证')" prop="reg_verify">
|
||||||
|
<RadioGroup v-model="formData.reg_verify">
|
||||||
|
<Radio label="open">{{ $L('开启') }}</Radio>
|
||||||
|
<Radio label="close">{{ $L('关闭') }}</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
<div v-if="formData.reg_verify == 'open'" class="form-tip">{{$L('开启后账号需验证通过才可登录')}}</div>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem :label="$L('开启通知')" prop="notice">
|
||||||
|
<RadioGroup v-model="formData.notice">
|
||||||
|
<Radio label="open">{{ $L('开启') }}</Radio>
|
||||||
|
<Radio label="close">{{ $L('关闭') }}</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</FormItem>
|
||||||
|
<template v-if="formData.notice == 'open'">
|
||||||
|
<FormItem :label="$L('任务提醒:')" prop="task_remind_hours">
|
||||||
|
<label>{{ $L('到期前') }}</label>
|
||||||
|
<InputNumber v-model="formData.task_remind_hours" :min="0.5" :step="0.5" @on-change="hoursChange"/>
|
||||||
|
<label>{{ $L('小时') }}</label>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem :label="$L('第二次任务提醒:')" prop="task_remind_hours2">
|
||||||
|
<label>{{ $L('到期后') }}</label>
|
||||||
|
<InputNumber v-model="formData.task_remind_hours2" :min="0.5" :step="0.5" @on-change="hours2Change"/>
|
||||||
|
<label>{{ $L('小时') }}</label>
|
||||||
|
</FormItem>
|
||||||
|
</template>
|
||||||
|
</Form>
|
||||||
|
<div class="setting-footer">
|
||||||
|
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{ $L('提交') }}</Button>
|
||||||
|
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{ $L('重置') }}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SystemEmailSetting",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loadIng: 0,
|
||||||
|
formData: {
|
||||||
|
smtp_server: '',
|
||||||
|
port: '',
|
||||||
|
account: '',
|
||||||
|
password: '',
|
||||||
|
reg_verify: 'colse',
|
||||||
|
notice: 'open',
|
||||||
|
task_remind_hours: 0,
|
||||||
|
task_remind_hours2: 0,
|
||||||
|
},
|
||||||
|
ruleData: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.systemSetting();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
submitForm() {
|
||||||
|
this.$refs.formData.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.systemSetting(true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
resetForm() {
|
||||||
|
this.formData = $A.cloneJSON(this.formDatum_bak);
|
||||||
|
},
|
||||||
|
|
||||||
|
formArchived(value) {
|
||||||
|
this.formData = {...this.formData, auto_archived: value};
|
||||||
|
},
|
||||||
|
|
||||||
|
systemSetting(save) {
|
||||||
|
this.loadIng++;
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'system/emailSetting?type=' + (save ? 'save' : 'all'),
|
||||||
|
data: this.formData,
|
||||||
|
}).then(({data}) => {
|
||||||
|
if (save) {
|
||||||
|
$A.messageSuccess('修改成功');
|
||||||
|
}
|
||||||
|
this.loadIng--;
|
||||||
|
this.formData = data;
|
||||||
|
this.formDatum_bak = $A.cloneJSON(this.formData);
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
if (save) {
|
||||||
|
$A.modalError(msg);
|
||||||
|
}
|
||||||
|
this.loadIng--;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hoursChange(e) {
|
||||||
|
let newNum = e * 10;
|
||||||
|
if (newNum % 5 !== 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.formData.task_remind_hours = 1;
|
||||||
|
})
|
||||||
|
$A.messageError('任务提醒只能是0.5的倍数');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hours2Change(e) {
|
||||||
|
let newNum = e * 10;
|
||||||
|
if (newNum % 5 !== 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.formData.task_remind_hours2 = 1;
|
||||||
|
})
|
||||||
|
$A.messageError('第二次任务提醒只能是0.5的倍数');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -10,6 +10,9 @@
|
|||||||
<TabPane :label="$L('项目模板')" name="columnTemplate">
|
<TabPane :label="$L('项目模板')" name="columnTemplate">
|
||||||
<SystemColumnTemplate/>
|
<SystemColumnTemplate/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
<TabPane :label="$L('邮件设置')" name="emailSetting">
|
||||||
|
<SystemEmailSetting/>
|
||||||
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -18,8 +21,10 @@
|
|||||||
import SystemSetting from "./setting";
|
import SystemSetting from "./setting";
|
||||||
import SystemTaskPriority from "./taskPriority";
|
import SystemTaskPriority from "./taskPriority";
|
||||||
import SystemColumnTemplate from "./columnTemplate";
|
import SystemColumnTemplate from "./columnTemplate";
|
||||||
|
import SystemEmailSetting from "./EmailSetting";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting},
|
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting, SystemEmailSetting},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tabAction: 'setting',
|
tabAction: 'setting',
|
||||||
|
|||||||
@ -59,6 +59,18 @@
|
|||||||
<div slot="content">{{$L('任务完成 % 天后自动归档。', formDatum.archived_day)}}</div>
|
<div slot="content">{{$L('任务完成 % 天后自动归档。', formDatum.archived_day)}}</div>
|
||||||
</ETooltip>
|
</ETooltip>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
<FormItem :label="$L('是否启动首页')" prop="startHome">
|
||||||
|
<RadioGroup v-model="formDatum.start_home">
|
||||||
|
<Radio label="open">{{$L('开启')}}</Radio>
|
||||||
|
<Radio label="close">{{$L('关闭')}}</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
<template v-if="formDatum.start_home == 'open'">
|
||||||
|
<div class="form-tip">{{ $L('首页底部:首页底部网站备案号等信息') }}</div>
|
||||||
|
<Input v-model="formDatum.home_footer" style="width:100%;margin-top:6px">
|
||||||
|
<span slot="prepend">{{ $L('首页底部') }}</span>
|
||||||
|
</Input>
|
||||||
|
</template>
|
||||||
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
<div class="setting-footer">
|
<div class="setting-footer">
|
||||||
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
||||||
|
|||||||
90
resources/assets/js/pages/single/validEmail.vue
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<div class="valid-wrap">
|
||||||
|
<div class="valid-box">
|
||||||
|
<div class="valid-title">{{$L('验证邮箱')}}</div>
|
||||||
|
<Spin size="large" v-if="!success && !error"></Spin>
|
||||||
|
<div class="validation-text" v-if="success">
|
||||||
|
<p>{{$L('您的邮箱已通过验证')}}</p>
|
||||||
|
<p>{{$L('今后您可以通过此邮箱重置您的账号密码')}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="validation-text" v-if="error">
|
||||||
|
<div>{{errorText}}</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" v-if="success">
|
||||||
|
<Button type="primary" @click="userLogout" long>{{$L('返回首页')}}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "validEmail",
|
||||||
|
components: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: false,
|
||||||
|
errorText: this.$L('链接已过期,已重新发送'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.verificationEmail();
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
verificationEmail() {
|
||||||
|
this.$store
|
||||||
|
.dispatch("call", {
|
||||||
|
url: "users/email/verification",
|
||||||
|
data: {
|
||||||
|
code: this.$route.query.code
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(({data}) => {
|
||||||
|
this.success = true;
|
||||||
|
this.error = false;
|
||||||
|
}).catch(({data, msg}) => {
|
||||||
|
if (data.code === 2) {
|
||||||
|
this.goForward({path: '/'}, true);
|
||||||
|
} else {
|
||||||
|
this.success = false;
|
||||||
|
this.error = true;
|
||||||
|
this.errorText = this.$L(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
userLogout() {
|
||||||
|
this.$store.dispatch("logout", false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.valid-wrap {
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.valid-box {
|
||||||
|
width: 500px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 5px 15px 20px 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
.valid-title {
|
||||||
|
border-bottom: 1px solid #e8eaec;
|
||||||
|
padding: 14px 16px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-text{
|
||||||
|
padding: 10px;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
6
resources/assets/js/routes.js
vendored
@ -90,6 +90,12 @@ export default [
|
|||||||
path: '/single/task/:id',
|
path: '/single/task/:id',
|
||||||
component: () => import('./pages/single/task.vue'),
|
component: () => import('./pages/single/task.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'valid-email',
|
||||||
|
path: '/single/valid/email',
|
||||||
|
meta: {title: '验证绑定邮箱'},
|
||||||
|
component: () => import('./pages/single/validEmail.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'login',
|
name: 'login',
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
|||||||
53
resources/assets/js/store/actions.js
vendored
@ -207,6 +207,7 @@ export default {
|
|||||||
dispatch("getProjects").catch(() => {});
|
dispatch("getProjects").catch(() => {});
|
||||||
dispatch("getDialogs").catch(() => {});
|
dispatch("getDialogs").catch(() => {});
|
||||||
dispatch("getTaskForDashboard");
|
dispatch("getTaskForDashboard");
|
||||||
|
dispatch("getTaskBrowse");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -424,19 +425,29 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const cacheLoginEmail = $A.getStorageString("cacheLoginEmail");
|
const cacheLoginEmail = $A.getStorageString("cacheLoginEmail");
|
||||||
const cacheThemeMode = $A.getStorageString("cacheThemeMode");
|
const cacheThemeMode = $A.getStorageString("cacheThemeMode");
|
||||||
|
let userId = state.userId > 0 ? state.userId : userInfo.userid;
|
||||||
|
const cacheTaskBrowse = $A.getStorageArray("cacheTaskBrowse" + userId)
|
||||||
|
|
||||||
//
|
//
|
||||||
window.localStorage.clear();
|
// window.localStorage.clear();
|
||||||
//
|
//
|
||||||
state.cacheUserBasic = [];
|
state.cacheUserBasic = [];
|
||||||
state.cacheDialogs = [];
|
state.cacheDialogs = [];
|
||||||
state.cacheProjects = [];
|
state.cacheProjects = [];
|
||||||
state.cacheColumns = [];
|
state.cacheColumns = [];
|
||||||
state.cacheTasks = [];
|
state.cacheTasks = [];
|
||||||
|
state.cacheLoading = {};
|
||||||
|
state.cacheDrawerIndex = 0;
|
||||||
|
state.cacheDrawerOverlay = [];
|
||||||
|
state.cacheUserActive = {};
|
||||||
|
state.cacheUserWait = [];
|
||||||
|
|
||||||
//
|
//
|
||||||
$A.setStorage("cacheProjectParameter", state.cacheProjectParameter);
|
$A.setStorage("cacheProjectParameter", state.cacheProjectParameter);
|
||||||
$A.setStorage("cacheServerUrl", state.cacheServerUrl);
|
$A.setStorage("cacheServerUrl", state.cacheServerUrl);
|
||||||
$A.setStorage("cacheLoginEmail", cacheLoginEmail);
|
$A.setStorage("cacheLoginEmail", cacheLoginEmail);
|
||||||
$A.setStorage("cacheThemeMode", cacheThemeMode);
|
$A.setStorage("cacheThemeMode", cacheThemeMode);
|
||||||
|
$A.setStorage("cacheTaskBrowse" + userId, cacheTaskBrowse);
|
||||||
dispatch("saveUserInfo", $A.isJson(userInfo) ? userInfo : state.userInfo);
|
dispatch("saveUserInfo", $A.isJson(userInfo) ? userInfo : state.userInfo);
|
||||||
//
|
//
|
||||||
resolve()
|
resolve()
|
||||||
@ -1224,29 +1235,27 @@ export default {
|
|||||||
* 删除任务
|
* 删除任务
|
||||||
* @param state
|
* @param state
|
||||||
* @param dispatch
|
* @param dispatch
|
||||||
* @param task_id
|
* @param data
|
||||||
* @returns {Promise<unknown>}
|
* @returns {Promise<unknown>}
|
||||||
*/
|
*/
|
||||||
removeTask({state, dispatch}, task_id) {
|
removeTask({state, dispatch}, data) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
if ($A.runNum(task_id) === 0) {
|
if ($A.runNum(data.task_id) === 0) {
|
||||||
reject({msg: 'Parameter error'});
|
reject({msg: 'Parameter error'});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch("taskLoadStart", task_id)
|
dispatch("taskLoadStart", data.task_id)
|
||||||
dispatch("call", {
|
dispatch("call", {
|
||||||
url: 'project/task/remove',
|
url: 'project/task/remove',
|
||||||
data: {
|
data,
|
||||||
task_id: task_id,
|
|
||||||
},
|
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
dispatch("forgetTask", task_id)
|
dispatch("forgetTask", data.task_id)
|
||||||
dispatch("taskLoadEnd", task_id)
|
dispatch("taskLoadEnd", data.task_id)
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
dispatch("getTaskOne", task_id).catch(() => {})
|
dispatch("getTaskOne", data.task_id).catch(() => {})
|
||||||
dispatch("taskLoadEnd", task_id)
|
dispatch("taskLoadEnd", data.task_id)
|
||||||
reject(e)
|
reject(e)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1402,7 +1411,21 @@ export default {
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
dispatch("getTaskContent", task_id);
|
dispatch("getTaskContent", task_id);
|
||||||
dispatch("getTaskFiles", task_id);
|
dispatch("getTaskFiles", task_id);
|
||||||
dispatch("getTaskForParent", task_id).catch(() => {})
|
dispatch("getTaskForParent", task_id).catch(() => {});
|
||||||
|
task.view_time = new Date().getTime();
|
||||||
|
let index = state.cacheTaskBrowse.findIndex(({id}) => id == task.id)
|
||||||
|
if (index > -1) {
|
||||||
|
state.cacheTaskBrowse.splice(index, 1,task)
|
||||||
|
} else {
|
||||||
|
state.cacheTaskBrowse.push(task)
|
||||||
|
}
|
||||||
|
if (state.cacheTaskBrowse.length > 10) {
|
||||||
|
let deleteNum = state.cacheTaskBrowse.length - 10
|
||||||
|
state.cacheTaskBrowse.splice(0, parseInt(deleteNum))
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
$A.setStorage("cacheTaskBrowse" + state.userId, state.cacheTaskBrowse);
|
||||||
|
})
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
$A.modalWarning({
|
$A.modalWarning({
|
||||||
content: msg,
|
content: msg,
|
||||||
@ -2383,4 +2406,8 @@ export default {
|
|||||||
websocketClose({state}) {
|
websocketClose({state}) {
|
||||||
state.ws && state.ws.close();
|
state.ws && state.ws.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getTaskBrowse({state}) {
|
||||||
|
state.cacheTaskBrowse = $A.getStorageArray("cacheTaskBrowse" + state.userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
resources/assets/js/store/mutations.js
vendored
@ -1,3 +1,4 @@
|
|||||||
export default {
|
export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
resources/assets/js/store/state.js
vendored
@ -29,6 +29,7 @@ const stateData = {
|
|||||||
cacheColumns: $A.getStorageArray("cacheColumns"),
|
cacheColumns: $A.getStorageArray("cacheColumns"),
|
||||||
cacheTasks: $A.getStorageArray("cacheTasks"),
|
cacheTasks: $A.getStorageArray("cacheTasks"),
|
||||||
cacheProjectParameter: $A.getStorageArray("cacheProjectParameter"),
|
cacheProjectParameter: $A.getStorageArray("cacheProjectParameter"),
|
||||||
|
cacheTaskBrowse: $A.getStorageArray("cacheTaskBrowse" + $A.getStorageJson("userInfo").userid),
|
||||||
|
|
||||||
// ServerUrl
|
// ServerUrl
|
||||||
cacheServerUrl: $A.getStorageString("cacheServerUrl"),
|
cacheServerUrl: $A.getStorageString("cacheServerUrl"),
|
||||||
|
|||||||
1
resources/assets/sass/app.scss
vendored
@ -5,7 +5,6 @@
|
|||||||
@import "taskfont";
|
@import "taskfont";
|
||||||
@import "loading";
|
@import "loading";
|
||||||
@import "scrollbar";
|
@import "scrollbar";
|
||||||
|
|
||||||
@import "components/_";
|
@import "components/_";
|
||||||
@import "pages/_";
|
@import "pages/_";
|
||||||
|
|
||||||
|
|||||||
2
resources/assets/sass/pages/_.scss
vendored
@ -7,5 +7,5 @@
|
|||||||
@import "page-messenger";
|
@import "page-messenger";
|
||||||
@import "page-project";
|
@import "page-project";
|
||||||
@import "page-setting";
|
@import "page-setting";
|
||||||
|
@import "page-index";
|
||||||
@import "components/_";
|
@import "components/_";
|
||||||
|
|||||||
@ -82,6 +82,17 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
.top-text{
|
||||||
|
width: 40px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius:4px;
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: #8BCF70;
|
||||||
|
color:#FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 4px;
|
||||||
|
padding-top: 1px
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub-title {
|
.sub-title {
|
||||||
|
|||||||
@ -174,6 +174,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
@ -423,6 +428,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
@ -786,6 +796,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
@ -978,7 +993,9 @@
|
|||||||
&.progress {
|
&.progress {
|
||||||
color: #0171c2 !important;
|
color: #0171c2 !important;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
color: #0171c2 !important;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
color: #038a24 !important;
|
color: #038a24 !important;
|
||||||
}
|
}
|
||||||
@ -994,7 +1011,9 @@
|
|||||||
&.progress {
|
&.progress {
|
||||||
background-color: rgba(27, 154, 238, 0.1);
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,6 +70,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
@ -329,6 +334,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.test {
|
||||||
|
border-color: #ccecff;
|
||||||
|
&:hover {
|
||||||
|
border-color: #87d2ff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.end {
|
&.end {
|
||||||
border-color: #cafac8;
|
border-color: #cafac8;
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -377,6 +389,11 @@
|
|||||||
color: #0171c2
|
color: #0171c2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.test {
|
||||||
|
background: rgba(27,154,238,0.1);
|
||||||
|
color: #0171c2
|
||||||
|
}
|
||||||
|
|
||||||
&.end {
|
&.end {
|
||||||
background: rgba(21,173,49,0.1);
|
background: rgba(21,173,49,0.1);
|
||||||
color: #038a24
|
color: #038a24
|
||||||
|
|||||||
@ -71,6 +71,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
@ -354,6 +359,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
|||||||
@ -93,6 +93,12 @@
|
|||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
|
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
|||||||
@ -182,6 +182,11 @@
|
|||||||
border-color: rgba(27, 154, 238, 0.1);
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
color: #0171c2;
|
color: #0171c2;
|
||||||
}
|
}
|
||||||
|
&.test {
|
||||||
|
background-color: rgba(27, 154, 238, 0.1);
|
||||||
|
border-color: rgba(27, 154, 238, 0.1);
|
||||||
|
color: #0171c2;
|
||||||
|
}
|
||||||
&.end {
|
&.end {
|
||||||
background-color: rgba(21, 173, 49, 0.1);
|
background-color: rgba(21, 173, 49, 0.1);
|
||||||
border-color: rgba(21, 173, 49, 0.1);
|
border-color: rgba(21, 173, 49, 0.1);
|
||||||
|
|||||||
667
resources/assets/sass/pages/page-index.scss
vendored
Normal file
@ -0,0 +1,667 @@
|
|||||||
|
@media (max-width: 1919px) {
|
||||||
|
.page-warp {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
.page-header {
|
||||||
|
width: 100%;
|
||||||
|
height: 720px;
|
||||||
|
background: #8bcf70;
|
||||||
|
border-radius: 0px 0px 300px 300px;
|
||||||
|
position: relative;
|
||||||
|
.header-nav {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.header-nav-box {
|
||||||
|
display: flex;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
position: relative;
|
||||||
|
.logo {
|
||||||
|
width: 65px;
|
||||||
|
height: 36px;
|
||||||
|
background: url("../images/index/indexlogo.png")
|
||||||
|
no-repeat center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
}
|
||||||
|
.header-right-one {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: end;
|
||||||
|
font-size: 12px;
|
||||||
|
min-width: 75px;
|
||||||
|
.header-right-one-language {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
.header-right-one-dropdown {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-right-two {
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
@media(max-width:414px){
|
||||||
|
|
||||||
|
.header-right-three {
|
||||||
|
max-width: 50px;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 36px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:414px){
|
||||||
|
|
||||||
|
.header-right-three {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 36px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media(min-width:660px){
|
||||||
|
.logo {
|
||||||
|
width: 143px;
|
||||||
|
height: 36px;
|
||||||
|
background: url("../images/index/indexlogo.png")
|
||||||
|
no-repeat center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
}
|
||||||
|
.header-right-one {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
min-width: 75px;
|
||||||
|
.header-right-one-language {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
.header-right-one-dropdown {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-right-two {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 0 40px 0 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.header-right-three {
|
||||||
|
font-size: 16px;
|
||||||
|
height: 36px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding: 0 10px 0 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 396px;
|
||||||
|
margin: 0 auto;
|
||||||
|
.header-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 67px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.header-title-one {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.header-tips {
|
||||||
|
width: 80%;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 22px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.login-buttom {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 34px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .header-bg {
|
||||||
|
// width: 100%;
|
||||||
|
// height: 400px;
|
||||||
|
// background: url("../images/index/decoration.png") no-repeat center
|
||||||
|
// center;
|
||||||
|
// background-size: contain;
|
||||||
|
// position: absolute;
|
||||||
|
// bottom: 0;
|
||||||
|
// }
|
||||||
|
.header-pic {
|
||||||
|
width: 100%;
|
||||||
|
height: 340px;
|
||||||
|
background: url("../images/index/pic.png") no-repeat center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-main {
|
||||||
|
width: 62.5%;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 200px;
|
||||||
|
.box-img{
|
||||||
|
height: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
vertical-align: bottom;
|
||||||
|
bottom: 0;
|
||||||
|
-o-object-fit: fill;
|
||||||
|
object-fit: fill;
|
||||||
|
}
|
||||||
|
.box-pic {
|
||||||
|
-webkit-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
-moz-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.box-square {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: url("../images/index/square.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.box-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 45px;
|
||||||
|
margin: 6px 0 18px 0;
|
||||||
|
}
|
||||||
|
.box-tips {
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #828282;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.main-box-one {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 70px;
|
||||||
|
|
||||||
|
.box-one-tips {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.main-box-two {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 70px;
|
||||||
|
.box-two-square {
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-two-tips {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-footer {
|
||||||
|
.footer-service {
|
||||||
|
width: 100%;
|
||||||
|
height: 188px;
|
||||||
|
background-color: #ffa25a;
|
||||||
|
position: relative;
|
||||||
|
.footer-bg-box {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 188px;
|
||||||
|
|
||||||
|
// background: url("../images/index/footer-bg.png") no-repeat
|
||||||
|
// center center;
|
||||||
|
// background-size: 100% 100%;
|
||||||
|
// background-size: contain;
|
||||||
|
.box-title {
|
||||||
|
height: 45px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 45px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 33px 0 22px 0;
|
||||||
|
}
|
||||||
|
.buttom-box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.login-btn {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffa25a;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.contact-btn {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer-opyright {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
background: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #828282;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1920px) {
|
||||||
|
.page-warp {
|
||||||
|
width: 1920px;
|
||||||
|
margin: 0 auto;
|
||||||
|
.page-header {
|
||||||
|
width: 100%;
|
||||||
|
height: 852px;
|
||||||
|
background: #8bcf70;
|
||||||
|
border-radius: 0px 0px 300px 300px;
|
||||||
|
position: relative;
|
||||||
|
.header-nav {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
.header-nav-box {
|
||||||
|
width: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
|
||||||
|
font-weight: 400;
|
||||||
|
position: relative;
|
||||||
|
.logo {
|
||||||
|
width: 143px;
|
||||||
|
height: 36px;
|
||||||
|
background: url("../images/index/indexlogo.png")
|
||||||
|
no-repeat center center;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
.header-right-one {
|
||||||
|
display: flex;
|
||||||
|
.header-right-one-language {
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
|
.header-right-one-dropdown {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-right-two {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 0 30px 0 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.header-right-three {
|
||||||
|
font-size: 16px;
|
||||||
|
min-width: 100px;
|
||||||
|
height: 36px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 10px 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header-content {
|
||||||
|
width: 950px;
|
||||||
|
margin: 0 auto;
|
||||||
|
.header-title {
|
||||||
|
font-size: 48px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 67px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.header-title-one {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.header-tips {
|
||||||
|
width: 950px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
margin-top: 22px;
|
||||||
|
}
|
||||||
|
.login-buttom {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
background: #ffa25a;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 34px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bg {
|
||||||
|
width: 100%;
|
||||||
|
height: 405px;
|
||||||
|
background: url("../images/index/decoration.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -40px;
|
||||||
|
}
|
||||||
|
.header-pic {
|
||||||
|
width: 920px;
|
||||||
|
height: 528px;
|
||||||
|
background: url("../images/index/pic.png") no-repeat center
|
||||||
|
center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -471px;
|
||||||
|
bottom: -236px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-main {
|
||||||
|
width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 388px;
|
||||||
|
.main-box-one {
|
||||||
|
height: 388px;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 180px;
|
||||||
|
.box-one-square {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: #8bcf70;
|
||||||
|
border-radius: 30px;
|
||||||
|
opacity: 0.15;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.box-one-pic1 {
|
||||||
|
width: 600px;
|
||||||
|
height: 338px;
|
||||||
|
background: url("../images/index/box-pic1.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
margin: 50px 0 0 50px;
|
||||||
|
-webkit-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
-moz-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box-one-pic3 {
|
||||||
|
width: 600px;
|
||||||
|
height: 338px;
|
||||||
|
background: url("../images/index/box-pic3.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
margin: 50px 0 0 50px;
|
||||||
|
-webkit-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
-moz-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box-one-tips {
|
||||||
|
width: 460px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.box-square {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
background: url("../images/index/square.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin-top: 119px;
|
||||||
|
}
|
||||||
|
.box-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 45px;
|
||||||
|
margin: 6px 0 18px 0;
|
||||||
|
}
|
||||||
|
.box-tips {
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #828282;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.main-box-two {
|
||||||
|
height: 388px;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 180px;
|
||||||
|
.box-two-square {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: #8bcf70;
|
||||||
|
border-radius: 30px;
|
||||||
|
opacity: 0.15;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.box-two-pic2 {
|
||||||
|
width: 600px;
|
||||||
|
height: 338px;
|
||||||
|
background: url("../images/index/box-pic2.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
right: 50px;
|
||||||
|
top: 50px;
|
||||||
|
-webkit-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
-moz-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box-two-pic4 {
|
||||||
|
width: 600px;
|
||||||
|
height: 338px;
|
||||||
|
background: url("../images/index/box-pic4.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
right: 50px;
|
||||||
|
top: 50px;
|
||||||
|
-webkit-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
-moz-box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
box-shadow: 0px 0px 10px #a9a4a4;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box-two-tips {
|
||||||
|
width: 460px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.box-square {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
background: url("../images/index/square.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
margin-top: 119px;
|
||||||
|
}
|
||||||
|
.box-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 45px;
|
||||||
|
margin: 6px 0 18px 0;
|
||||||
|
}
|
||||||
|
.box-tips {
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #828282;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-footer {
|
||||||
|
.footer-service {
|
||||||
|
width: 100%;
|
||||||
|
height: 188px;
|
||||||
|
background-color: #ffa25a;
|
||||||
|
position: relative;
|
||||||
|
.footer-bg-box {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 188px;
|
||||||
|
background: url("../images/index/footer-bg.png") no-repeat
|
||||||
|
center center;
|
||||||
|
background-size: contain;
|
||||||
|
.box-title {
|
||||||
|
height: 45px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 45px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 33px 0 22px 0;
|
||||||
|
}
|
||||||
|
.buttom-box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.login-btn {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffa25a;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.contact-btn {
|
||||||
|
width: 150px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: PingFangSC-Medium, PingFang SC;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
line-height: 48px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer-opyright {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
background: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: PingFangSC-Regular, PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #828282;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
resources/assets/sass/pages/page-manage.scss
vendored
@ -95,6 +95,11 @@
|
|||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.task-title {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
> ul {
|
> ul {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -196,6 +201,11 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-top {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.project-h2 {
|
.project-h2 {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
BIN
resources/assets/statics/public/images/index/box-pic1.png
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
resources/assets/statics/public/images/index/box-pic2.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
resources/assets/statics/public/images/index/box-pic3.png
Normal file
|
After Width: | Height: | Size: 348 KiB |
BIN
resources/assets/statics/public/images/index/box-pic4.png
Normal file
|
After Width: | Height: | Size: 624 KiB |
BIN
resources/assets/statics/public/images/index/decoration.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
resources/assets/statics/public/images/index/footer-bg.png
Normal file
|
After Width: | Height: | Size: 10 KiB |