Merge remote-tracking branch 'origin/develop' into develop
# Conflicts: # app/Http/Controllers/Api/FileController.php # public/js/build/208.js # public/js/build/252.js # public/js/build/400.js # public/js/build/76.js
This commit is contained in:
commit
230d1a1f86
@ -9,6 +9,7 @@ use App\Models\WebSocketDialog;
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use App\Models\WebSocketDialogMsgRead;
|
||||
use App\Module\Base;
|
||||
use Carbon\Carbon;
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
@ -269,7 +270,7 @@ class DialogController extends AbstractController
|
||||
} else {
|
||||
$data = Base::upload([
|
||||
"file" => Request::file('files'),
|
||||
"type" => 'file',
|
||||
"type" => 'more',
|
||||
"path" => $path,
|
||||
"fileName" => $fileName,
|
||||
]);
|
||||
@ -349,6 +350,9 @@ class DialogController extends AbstractController
|
||||
* @apiName msg__detail
|
||||
*
|
||||
* @apiParam {Number} msg_id 消息ID
|
||||
* @apiParam {String} only_update_at 仅获取update_at字段
|
||||
* - no (默认)
|
||||
* - yes
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -359,11 +363,20 @@ class DialogController extends AbstractController
|
||||
User::auth();
|
||||
//
|
||||
$msg_id = intval(Request::input('msg_id'));
|
||||
$only_update_at = Request::input('only_update_at', 'no');
|
||||
//
|
||||
$dialogMsg = WebSocketDialogMsg::whereId($msg_id)->first();
|
||||
if (empty($dialogMsg)) {
|
||||
return Base::retError("文件不存在");
|
||||
}
|
||||
//
|
||||
if ($only_update_at == 'yes') {
|
||||
return Base::retSuccess('success', [
|
||||
'id' => $dialogMsg->id,
|
||||
'update_at' => Carbon::parse($dialogMsg->updated_at)->toDateTimeString()
|
||||
]);
|
||||
}
|
||||
//
|
||||
$data = $dialogMsg->toArray();
|
||||
//
|
||||
if ($data['type'] == 'file') {
|
||||
|
@ -9,14 +9,11 @@ use App\Models\FileContent;
|
||||
use App\Models\FileLink;
|
||||
use App\Models\FileUser;
|
||||
use App\Models\User;
|
||||
use App\Models\WebSocketDialogMsg;
|
||||
use App\Module\Base;
|
||||
use App\Module\Ihttp;
|
||||
use App\Tasks\BatchRemoveFileTask;
|
||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Request;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* @apiDefine file
|
||||
@ -318,11 +315,11 @@ class FileController extends AbstractController
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function move($id = 0)
|
||||
public function move()
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
$id = empty($id) ? intval(Request::input('id')) : $id;
|
||||
$id = intval(Request::input('id'));
|
||||
$pid = intval(Request::input('pid'));
|
||||
//
|
||||
$file = File::permissionFind($id, 1000);
|
||||
@ -348,44 +345,6 @@ class FileController extends AbstractController
|
||||
return Base::retSuccess('操作成功', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/file/batch/move 批量移动文件
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup file
|
||||
* @apiName batch__move
|
||||
*
|
||||
* @apiParam {Array} ids 文件ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function batch__move(): array
|
||||
{
|
||||
$ids = Request::input('ids');
|
||||
if ( empty($ids) || !is_array($ids) ) {
|
||||
return Base::retError("请选择要移动的文件");
|
||||
}
|
||||
// 去重
|
||||
$ids = array_unique($ids);
|
||||
$data = [];
|
||||
// 暂时不考虑异步
|
||||
AbstractModel::transaction( function () use ($ids, &$data) {
|
||||
foreach ($ids as $id) {
|
||||
$res = $this->move($id);
|
||||
if ( Base::isError($res) )
|
||||
throw new ApiException($res["msg"]);
|
||||
|
||||
$data[] = $res["data"];
|
||||
}
|
||||
} );
|
||||
return Base::retSuccess('操作成功', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/file/remove 07. 删除文件(夹)
|
||||
*
|
||||
@ -412,33 +371,6 @@ class FileController extends AbstractController
|
||||
return Base::retSuccess('删除成功', $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/file/batch/remove 批量删除文件
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup file
|
||||
* @apiName batchRemove
|
||||
*
|
||||
* @apiParam {Array} ids 文件ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function batch__remove(): array
|
||||
{
|
||||
$ids = Request::input('ids');
|
||||
if ( empty($ids) || !is_array($ids) ) {
|
||||
return Base::retError("请选择要删除的文件");
|
||||
}
|
||||
$task = new BatchRemoveFileTask($ids, User::userid());
|
||||
Task::deliver($task);
|
||||
return Base::retSuccess('操作成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/file/content 08. 获取文件内容
|
||||
*
|
||||
@ -450,7 +382,10 @@ class FileController extends AbstractController
|
||||
* @apiParam {Number|String} id
|
||||
* - Number: 文件ID(需要登录)
|
||||
* - String: 链接码(不需要登录,用于预览)
|
||||
* @apiParam {String} down 直接下载
|
||||
* @apiParam {String} only_update_at 仅获取update_at字段
|
||||
* - no (默认)
|
||||
* - yes
|
||||
* @apiParam {String} down 直接下载
|
||||
* - no: 浏览(默认)
|
||||
* - yes: 下载(office文件直接下载)
|
||||
*
|
||||
@ -462,6 +397,7 @@ class FileController extends AbstractController
|
||||
{
|
||||
$id = Request::input('id');
|
||||
$down = Request::input('down', 'no');
|
||||
$only_update_at = Request::input('only_update_at', 'no');
|
||||
//
|
||||
if (Base::isNumber($id)) {
|
||||
User::auth();
|
||||
@ -476,6 +412,13 @@ class FileController extends AbstractController
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
//
|
||||
if ($only_update_at == 'yes') {
|
||||
return Base::retSuccess('success', [
|
||||
'id' => $file->id,
|
||||
'update_at' => Carbon::parse($file->updated_at)->toDateTimeString()
|
||||
]);
|
||||
}
|
||||
//
|
||||
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
||||
return FileContent::formatContent($file, $content?->content, $down == 'yes');
|
||||
}
|
||||
@ -631,10 +574,11 @@ class FileController extends AbstractController
|
||||
}
|
||||
//
|
||||
$dirs = explode("/", $webkitRelativePath);
|
||||
AbstractModel::transaction(function() use ($user, $userid, $dirs, &$pid) {
|
||||
while (count($dirs) > 1) {
|
||||
$dirName = array_shift($dirs);
|
||||
if ($dirName) {
|
||||
while (count($dirs) > 1) {
|
||||
$dirName = array_shift($dirs);
|
||||
if ($dirName) {
|
||||
$pushMsg = [];
|
||||
AbstractModel::transaction(function () use ($dirName, $user, $userid, &$pid, &$pushMsg) {
|
||||
$dirRow = File::wherePid($pid)->whereType('folder')->whereName($dirName)->lockForUpdate()->first();
|
||||
if (empty($dirRow)) {
|
||||
$dirRow = File::createInstance([
|
||||
@ -645,17 +589,19 @@ class FileController extends AbstractController
|
||||
'created_id' => $user->userid,
|
||||
]);
|
||||
if ($dirRow->save()) {
|
||||
$tmpRow = File::find($dirRow->id);
|
||||
$tmpRow->pushMsg('add', $tmpRow);
|
||||
$pushMsg[] = File::find($dirRow->id);
|
||||
}
|
||||
}
|
||||
if (empty($dirRow)) {
|
||||
throw new ApiException('创建文件夹失败');
|
||||
}
|
||||
$pid = $dirRow->id;
|
||||
});
|
||||
foreach ($pushMsg as $tmpRow) {
|
||||
$tmpRow->pushMsg('add', $tmpRow);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
$path = 'uploads/file/' . date("Ym") . '/u' . $user->userid . '/';
|
||||
$data = Base::upload([
|
||||
|
@ -204,6 +204,9 @@ class ProjectController extends AbstractController
|
||||
* @apiParam {String} name 项目名称
|
||||
* @apiParam {String} [desc] 项目介绍
|
||||
* @apiParam {String} [columns] 列表,格式:列表名称1,列表名称2
|
||||
* @apiParam {String} [flow] 开启流程
|
||||
* - open: 开启
|
||||
* - close: 关闭(默认)
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -215,6 +218,7 @@ class ProjectController extends AbstractController
|
||||
// 项目名称
|
||||
$name = trim(Request::input('name', ''));
|
||||
$desc = trim(Request::input('desc', ''));
|
||||
$flow = trim(Request::input('flow', 'close'));
|
||||
if (mb_strlen($name) < 2) {
|
||||
return Base::retError('项目名称不可以少于2个字');
|
||||
} elseif (mb_strlen($name) > 32) {
|
||||
@ -251,7 +255,7 @@ class ProjectController extends AbstractController
|
||||
'desc' => $desc,
|
||||
'userid' => $user->userid,
|
||||
]);
|
||||
AbstractModel::transaction(function() use ($insertColumns, $project) {
|
||||
AbstractModel::transaction(function() use ($flow, $insertColumns, $project) {
|
||||
$project->save();
|
||||
ProjectUser::createInstance([
|
||||
'project_id' => $project->id,
|
||||
@ -268,6 +272,10 @@ class ProjectController extends AbstractController
|
||||
}
|
||||
$project->dialog_id = $dialog->id;
|
||||
$project->save();
|
||||
//
|
||||
if ($flow == 'open') {
|
||||
$project->addFlow(Base::json2array('[{"id":"-10","name":"\u5f85\u5904\u7406","status":"start","turns":["-10","-11","-12","-13"],"usertype":"add","userlimit":"0","sort":"0"},{"id":"-11","name":"\u8fdb\u884c\u4e2d","status":"progress","turns":["-10","-11","-12","-13"],"usertype":"add","userlimit":"0","sort":"1"},{"id":"-12","name":"\u5df2\u5b8c\u6210","status":"end","turns":["-10","-11","-12","-13"],"usertype":"add","userlimit":"0","sort":"2"},{"id":"-13","name":"\u5df2\u53d6\u6d88","status":"end","turns":["-10","-11","-12","-13"],"usertype":"add","userlimit":"0","sort":"3"}]'));
|
||||
}
|
||||
});
|
||||
//
|
||||
$data = Project::find($project->id);
|
||||
@ -1091,7 +1099,10 @@ class ProjectController extends AbstractController
|
||||
* @apiGroup project
|
||||
* @apiName task__filedetail
|
||||
*
|
||||
* @apiParam {Number} file_id 文件ID
|
||||
* @apiParam {Number} file_id 文件ID
|
||||
* @apiParam {String} only_update_at 仅获取update_at字段
|
||||
* - no (默认)
|
||||
* - yes
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -1102,11 +1113,20 @@ class ProjectController extends AbstractController
|
||||
User::auth();
|
||||
//
|
||||
$file_id = intval(Request::input('file_id'));
|
||||
$only_update_at = Request::input('only_update_at', 'no');
|
||||
//
|
||||
$file = ProjectTaskFile::find($file_id);
|
||||
if (empty($file)) {
|
||||
return Base::retError("文件不存在");
|
||||
}
|
||||
//
|
||||
if ($only_update_at == 'yes') {
|
||||
return Base::retSuccess('success', [
|
||||
'id' => $file->id,
|
||||
'update_at' => Carbon::parse($file->updated_at)->toDateTimeString()
|
||||
]);
|
||||
}
|
||||
//
|
||||
$data = $file->toArray();
|
||||
$data['path'] = $file->getRawOriginal('path');
|
||||
//
|
||||
@ -1641,95 +1661,7 @@ class ProjectController extends AbstractController
|
||||
//
|
||||
$project = Project::userProject($project_id, true, true);
|
||||
//
|
||||
return AbstractModel::transaction(function() use ($project, $flows) {
|
||||
$projectFlow = ProjectFlow::whereProjectId($project->id)->first();
|
||||
if (empty($projectFlow)) {
|
||||
$projectFlow = ProjectFlow::createInstance([
|
||||
'project_id' => $project->id,
|
||||
'name' => 'Default'
|
||||
]);
|
||||
if (!$projectFlow->save()) {
|
||||
throw new ApiException('工作流创建失败');
|
||||
}
|
||||
}
|
||||
//
|
||||
$ids = [];
|
||||
$idc = [];
|
||||
$hasStart = false;
|
||||
$hasEnd = false;
|
||||
foreach ($flows as $item) {
|
||||
$id = intval($item['id']);
|
||||
$turns = Base::arrayRetainInt($item['turns'] ?: [], true);
|
||||
$userids = Base::arrayRetainInt($item['userids'] ?: [], true);
|
||||
$usertype = trim($item['usertype']);
|
||||
$userlimit = intval($item['userlimit']);
|
||||
if ($usertype == 'replace' && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置流转模式时必须填写状态负责人");
|
||||
}
|
||||
if ($usertype == 'merge' && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置剔除模式时必须填写状态负责人");
|
||||
}
|
||||
if ($userlimit && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置限制负责人时必须填写状态负责人");
|
||||
}
|
||||
$flow = ProjectFlowItem::updateInsert([
|
||||
'id' => $id,
|
||||
'project_id' => $project->id,
|
||||
'flow_id' => $projectFlow->id,
|
||||
], [
|
||||
'name' => trim($item['name']),
|
||||
'status' => trim($item['status']),
|
||||
'sort' => intval($item['sort']),
|
||||
'turns' => $turns,
|
||||
'userids' => $userids,
|
||||
'usertype' => trim($item['usertype']),
|
||||
'userlimit' => $userlimit,
|
||||
]);
|
||||
if ($flow) {
|
||||
$ids[] = $flow->id;
|
||||
if ($flow->id != $id) {
|
||||
$idc[$id] = $flow->id;
|
||||
}
|
||||
if ($flow->status == 'start') {
|
||||
$hasStart = true;
|
||||
}
|
||||
if ($flow->status == 'end') {
|
||||
$hasEnd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$hasStart) {
|
||||
throw new ApiException('至少需要1个开始状态');
|
||||
}
|
||||
if (!$hasEnd) {
|
||||
throw new ApiException('至少需要1个结束状态');
|
||||
}
|
||||
ProjectFlowItem::whereFlowId($projectFlow->id)->whereNotIn('id', $ids)->chunk(100, function($list) {
|
||||
foreach ($list as $item) {
|
||||
$item->deleteFlowItem();
|
||||
}
|
||||
});
|
||||
//
|
||||
$projectFlow = ProjectFlow::with(['projectFlowItem'])->whereProjectId($project->id)->find($projectFlow->id);
|
||||
$itemIds = $projectFlow->projectFlowItem->pluck('id')->toArray();
|
||||
foreach ($projectFlow->projectFlowItem as $item) {
|
||||
$turns = $item->turns;
|
||||
foreach ($idc as $oid => $nid) {
|
||||
if (in_array($oid, $turns)) {
|
||||
$turns = array_diff($turns, [$oid]);
|
||||
$turns[] = $nid;
|
||||
}
|
||||
}
|
||||
if (!in_array($item->id, $turns)) {
|
||||
$turns[] = $item->id;
|
||||
}
|
||||
$turns = array_values(array_filter(array_unique(array_intersect($turns, $itemIds))));
|
||||
sort($turns);
|
||||
$item->turns = $turns;
|
||||
ProjectFlowItem::whereId($item->id)->update([ 'turns' => Base::array2json($turns) ]);
|
||||
}
|
||||
return Base::retSuccess('保存成功', $projectFlow);
|
||||
});
|
||||
return Base::retSuccess('保存成功', $project->addFlow($flows));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,12 +101,16 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/system/priority 03. 获取优先级、保存优先级
|
||||
* @api {post} api/system/priority 03. 任务优先级
|
||||
*
|
||||
* @apiDescription 获取任务优先级、保存任务优先级
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
* @apiName priority
|
||||
*
|
||||
* @apiParam {String} type
|
||||
* - get: 获取(默认)
|
||||
* - save: 保存(限管理员)
|
||||
* @apiParam {Array} list 优先级数据,格式:[{name,color,days,priority}]
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
@ -145,6 +149,53 @@ class SystemController extends AbstractController
|
||||
return Base::retSuccess('success', $setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/system/column/template 03. 创建项目模板
|
||||
*
|
||||
* @apiDescription 获取创建项目模板、保存创建项目模板
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
* @apiName column__template
|
||||
*
|
||||
* @apiParam {String} type
|
||||
* - get: 获取(默认)
|
||||
* - save: 保存(限管理员)
|
||||
* @apiParam {Array} list 优先级数据,格式:[{name,columns}]
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function column__template()
|
||||
{
|
||||
$type = trim(Request::input('type'));
|
||||
if ($type == 'save') {
|
||||
User::auth('admin');
|
||||
$list = Base::getPostValue('list');
|
||||
$array = [];
|
||||
if (empty($list) || !is_array($list)) {
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
foreach ($list AS $item) {
|
||||
if (empty($item['name']) || empty($item['columns'])) {
|
||||
continue;
|
||||
}
|
||||
$array[] = [
|
||||
'name' => $item['name'],
|
||||
'columns' => array_values(array_filter(array_unique(explode(",", $item['columns']))))
|
||||
];
|
||||
}
|
||||
if (empty($array)) {
|
||||
return Base::retError('参数为空');
|
||||
}
|
||||
$setting = Base::setting('columnTemplate', $array);
|
||||
} else {
|
||||
$setting = Base::setting('columnTemplate');
|
||||
}
|
||||
//
|
||||
return Base::retSuccess('success', $setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/info 04. 获取终端详细信息
|
||||
*
|
||||
|
@ -21,6 +21,9 @@ class VerifyCsrfToken extends Middleware
|
||||
// 保存任务优先级
|
||||
'api/system/priority/',
|
||||
|
||||
// 保存创建项目列表模板
|
||||
'api/system/column/template/',
|
||||
|
||||
// 添加任务
|
||||
'api/project/task/add/',
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Module\Base;
|
||||
use App\Tasks\PushTask;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
@ -211,7 +212,7 @@ class Project extends AbstractModel
|
||||
*/
|
||||
public function relationUserids()
|
||||
{
|
||||
return $this->projectUser->pluck('userid')->toArray();
|
||||
return ProjectUser::whereProjectId($this->id)->orderBy('id')->pluck('userid')->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,6 +351,104 @@ class Project extends AbstractModel
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加工作流
|
||||
* @param $flows
|
||||
* @return mixed
|
||||
*/
|
||||
public function addFlow($flows)
|
||||
{
|
||||
return AbstractModel::transaction(function() use ($flows) {
|
||||
$projectFlow = ProjectFlow::whereProjectId($this->id)->first();
|
||||
if (empty($projectFlow)) {
|
||||
$projectFlow = ProjectFlow::createInstance([
|
||||
'project_id' => $this->id,
|
||||
'name' => 'Default'
|
||||
]);
|
||||
if (!$projectFlow->save()) {
|
||||
throw new ApiException('工作流创建失败');
|
||||
}
|
||||
}
|
||||
//
|
||||
$ids = [];
|
||||
$idc = [];
|
||||
$hasStart = false;
|
||||
$hasEnd = false;
|
||||
foreach ($flows as $item) {
|
||||
$id = intval($item['id']);
|
||||
$turns = Base::arrayRetainInt($item['turns'] ?: [], true);
|
||||
$userids = Base::arrayRetainInt($item['userids'] ?: [], true);
|
||||
$usertype = trim($item['usertype']);
|
||||
$userlimit = intval($item['userlimit']);
|
||||
if ($usertype == 'replace' && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置流转模式时必须填写状态负责人");
|
||||
}
|
||||
if ($usertype == 'merge' && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置剔除模式时必须填写状态负责人");
|
||||
}
|
||||
if ($userlimit && empty($userids)) {
|
||||
throw new ApiException("状态[{$item['name']}]设置错误,设置限制负责人时必须填写状态负责人");
|
||||
}
|
||||
$flow = ProjectFlowItem::updateInsert([
|
||||
'id' => $id,
|
||||
'project_id' => $this->id,
|
||||
'flow_id' => $projectFlow->id,
|
||||
], [
|
||||
'name' => trim($item['name']),
|
||||
'status' => trim($item['status']),
|
||||
'sort' => intval($item['sort']),
|
||||
'turns' => $turns,
|
||||
'userids' => $userids,
|
||||
'usertype' => trim($item['usertype']),
|
||||
'userlimit' => $userlimit,
|
||||
]);
|
||||
if ($flow) {
|
||||
$ids[] = $flow->id;
|
||||
if ($flow->id != $id) {
|
||||
$idc[$id] = $flow->id;
|
||||
}
|
||||
if ($flow->status == 'start') {
|
||||
$hasStart = true;
|
||||
}
|
||||
if ($flow->status == 'end') {
|
||||
$hasEnd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$hasStart) {
|
||||
throw new ApiException('至少需要1个开始状态');
|
||||
}
|
||||
if (!$hasEnd) {
|
||||
throw new ApiException('至少需要1个结束状态');
|
||||
}
|
||||
ProjectFlowItem::whereFlowId($projectFlow->id)->whereNotIn('id', $ids)->chunk(100, function($list) {
|
||||
foreach ($list as $item) {
|
||||
$item->deleteFlowItem();
|
||||
}
|
||||
});
|
||||
//
|
||||
$projectFlow = ProjectFlow::with(['projectFlowItem'])->whereProjectId($this->id)->find($projectFlow->id);
|
||||
$itemIds = $projectFlow->projectFlowItem->pluck('id')->toArray();
|
||||
foreach ($projectFlow->projectFlowItem as $item) {
|
||||
$turns = $item->turns;
|
||||
foreach ($idc as $oid => $nid) {
|
||||
if (in_array($oid, $turns)) {
|
||||
$turns = array_diff($turns, [$oid]);
|
||||
$turns[] = $nid;
|
||||
}
|
||||
}
|
||||
if (!in_array($item->id, $turns)) {
|
||||
$turns[] = $item->id;
|
||||
}
|
||||
$turns = array_values(array_filter(array_unique(array_intersect($turns, $itemIds))));
|
||||
sort($turns);
|
||||
$item->turns = $turns;
|
||||
ProjectFlowItem::whereId($item->id)->update([ 'turns' => Base::array2json($turns) ]);
|
||||
}
|
||||
return $projectFlow;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目信息(用于判断会员是否存在项目内)
|
||||
* @param int $project_id
|
||||
|
@ -851,7 +851,7 @@ class ProjectTask extends AbstractModel
|
||||
*/
|
||||
public function relationUserids()
|
||||
{
|
||||
$userids = $this->taskUser->pluck('userid')->toArray();
|
||||
$userids = ProjectTaskUser::whereTaskId($this->id)->orderByDesc('owner')->orderByDesc('id')->pluck('userid')->toArray();
|
||||
$items = ProjectTask::with(['taskUser'])->where('parent_id', $this->id)->whereNull('archived_at')->get();
|
||||
foreach ($items as $item) {
|
||||
$userids = array_merge($userids, $item->taskUser->pluck('userid')->toArray());
|
||||
|
@ -2236,7 +2236,7 @@ class Base
|
||||
$type = ['zip'];
|
||||
break;
|
||||
case 'file':
|
||||
$type = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz'];
|
||||
$type = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz', 'ai', 'avi', 'bmp', 'cdr', 'eps', 'mov', 'mp3', 'mp4', 'pr', 'psd', 'svg', 'tif'];
|
||||
break;
|
||||
case 'firmware':
|
||||
$type = ['img', 'tar', 'bin'];
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class InsertSettingColumnTemplate extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$array = \App\Module\Base::setting('columnTemplate');
|
||||
if (empty($array)) {
|
||||
\App\Module\Base::setting('columnTemplate', [
|
||||
[
|
||||
'name' => '软件开发',
|
||||
'columns' => ['产品规划', '前端开发', '后端开发', '测试', '发布', '其他'],
|
||||
],
|
||||
[
|
||||
'name' => '产品开发',
|
||||
'columns' => ['产品计划', '正在设计', '正在研发', '测试', '准备发布', '发布成功'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -16,14 +16,13 @@ class SettingsTableSeeder extends Seeder
|
||||
{
|
||||
|
||||
|
||||
if (\DB::table('settings')->count() > 0) {
|
||||
if (\DB::table('settings')->where('name', 'system')->count() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
\DB::table('settings')->insert(array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 1,
|
||||
'name' => 'system',
|
||||
'desc' => '',
|
||||
'setting' => '{"reg":"open","project_invite":"open","login_code":"auto"}',
|
||||
@ -32,7 +31,6 @@ class SettingsTableSeeder extends Seeder
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 2,
|
||||
'name' => 'priority',
|
||||
'desc' => '',
|
||||
'setting' => '[{"name":"\\u91cd\\u8981\\u4e14\\u7d27\\u6025","color":"#ED4014","days":1,"priority":1},{"name":"\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#F16B62","days":3,"priority":2},{"name":"\\u7d27\\u6025\\u4e0d\\u91cd\\u8981","color":"#19C919","days":5,"priority":3},{"name":"\\u4e0d\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#2D8CF0","days":0,"priority":4}]',
|
||||
|
@ -87,6 +87,9 @@ services:
|
||||
- ./docker/office/resources/documenteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/documenteditor/main/resources/css/app.css
|
||||
- ./docker/office/resources/presentationeditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/presentationeditor/main/resources/css/app.css
|
||||
- ./docker/office/resources/spreadsheeteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/spreadsheeteditor/main/resources/css/app.css
|
||||
- ./docker/office/resources/documenteditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/documenteditor/mobile/css/app.css
|
||||
- ./docker/office/resources/presentationeditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/presentationeditor/mobile/css/app.css
|
||||
- ./docker/office/resources/spreadsheeteditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/spreadsheeteditor/mobile/css/app.css
|
||||
environment:
|
||||
TZ: "Asia/Shanghai"
|
||||
networks:
|
||||
|
7
docker/office/resources/documenteditor/mobile/css/app.css
vendored
Normal file
7
docker/office/resources/documenteditor/mobile/css/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
docker/office/resources/presentationeditor/mobile/css/app.css
vendored
Normal file
7
docker/office/resources/presentationeditor/mobile/css/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
8
docker/office/resources/spreadsheeteditor/mobile/css/app.css
vendored
Normal file
8
docker/office/resources/spreadsheeteditor/mobile/css/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
electron/build.js
vendored
2
electron/build.js
vendored
@ -33,7 +33,7 @@ function startBuild(data, publish) {
|
||||
// index.html
|
||||
let indexFile = path.resolve(electronDir, "index.html");
|
||||
let indexString = fs.readFileSync(indexFile, 'utf8');
|
||||
indexString = indexString.replace(`<title></title>`, `<title>${data.name}</title>`);
|
||||
indexString = indexString.replace(/<title>(.*?)<\/title>/g, `<title>${data.name}</title>`);
|
||||
fs.writeFileSync(indexFile, indexString, 'utf8');
|
||||
// package.json Backup
|
||||
fse.copySync(packageFile, packageBakFile)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.7.72",
|
||||
"version": "0.7.94",
|
||||
"description": "DooTask is task management system.",
|
||||
"main": "main.js",
|
||||
"license": "MIT",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.7.72",
|
||||
"version": "0.7.94",
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
"start": "./cmd dev",
|
||||
|
2
public/css/app.css
vendored
2
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
38
public/docs/assets/main.bundle.js
vendored
38
public/docs/assets/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/120.js
vendored
2
public/js/build/120.js
vendored
File diff suppressed because one or more lines are too long
@ -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>
|
||||
* Released under MIT License
|
||||
*/
|
||||
|
1
public/js/build/135.js
vendored
Normal file
1
public/js/build/135.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/159.js
vendored
1
public/js/build/159.js
vendored
@ -1 +0,0 @@
|
||||
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[159],{26071:(e,t,i)=>{i.d(t,{Z:()=>r});var n=i(1519),o=i.n(n)()((function(e){return e[1]}));o.push([e.id,".component-only-office[data-v-c9bf06c2]{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.component-only-office .placeholder[data-v-c9bf06c2]{flex:1;height:100%;width:100%}.component-only-office .office-loading[data-v-c9bf06c2]{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0;z-index:2}",""]);const r=o},36159:(e,t,i)=>{i.r(t),i.d(t,{default:()=>u});var n=i(20629);function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?o(Object(i),!0).forEach((function(t){s(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):o(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function s(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}const l={name:"OnlyOffice",props:{id:{type:String,default:function(){return"office_"+Math.round(1e4*Math.random())}},code:{type:String,default:""},value:{type:[Object,Array],default:function(){return{}}},readOnly:{type:Boolean,default:!1}},data:function(){return{loadIng:0,docEditor:null}},mounted:function(){},beforeDestroy:function(){null!==this.docEditor&&(this.docEditor.destroyEditor(),this.docEditor=null)},computed:r(r({},(0,n.rn)(["userToken","userInfo","themeIsDark"])),{},{fileType:function(){return this.getType(this.value.type)},fileName:function(){return this.value.name}}),watch:{"value.id":{handler:function(e){var t=this;e&&(this.loadIng++,$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"),(function(e){t.loadIng--,null!==e?$A.modalAlert("组件加载失败!"):t.loadFile()})))},immediate:!0}},methods:{getType:function(e){switch(e){case"word":return"docx";case"excel":return"xlsx";case"ppt":return"pptx"}return e},loadFile:function(){var e=this;null!==this.docEditor&&(this.docEditor.destroyEditor(),this.docEditor=null);var t="zh";switch(this.getLanguage()){case"CN":case"TC":t="zh";break;default:t="en"}var i=this.code||this.value.id,n=$A.strExists(this.fileName,".")?this.fileName:this.fileName+"."+this.fileType,o={document:{fileType:this.fileType,key:this.fileType+"-"+i,title:n,url:"http://nginx/api/file/content/?id="+i+"&token="+this.userToken},editorConfig:{mode:"edit",lang:t,user:{id:this.userInfo.userid,name:this.userInfo.nickname},customization:{uiTheme:this.themeIsDark?"theme-dark":"theme-classic-light"},callbackUrl:"http://nginx/api/file/content/office?id="+i+"&token="+this.userToken}};if(/\/hideenOfficeTitle\//.test(window.navigator.userAgent)&&(o.document.title=" "),$A.leftExists(i,"msgFile_")?o.document.url="http://nginx/api/dialog/msg/download/?msg_id="+$A.leftDelete(i,"msgFile_")+"&token="+this.userToken:$A.leftExists(i,"taskFile_")&&(o.document.url="http://nginx/api/project/task/filedown/?file_id="+$A.leftDelete(i,"taskFile_")+"&token="+this.userToken),this.readOnly&&(o.editorConfig.mode="view",o.editorConfig.callbackUrl=null,!o.editorConfig.user.id)){var r=$A.getStorageInt("viewer");r||(r=$A.randNum(1e3,99999),$A.setStorage("viewer",r)),o.editorConfig.user.id="viewer_"+r,o.editorConfig.user.name="Viewer_"+r}this.$nextTick((function(){e.docEditor=new DocsAPI.DocEditor(e.id,o)}))}}};var a=i(93379),c=i.n(a),d=i(26071),f={insert:"head",singleton:!1};c()(d.Z,f);d.Z.locals;const u=(0,i(51900).Z)(l,(function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"component-only-office"},[i("div",{staticClass:"placeholder",attrs:{id:this.id}}),e._v(" "),e.loadIng>0?i("div",{staticClass:"office-loading"},[i("Loading")],1):e._e()])}),[],!1,null,"c9bf06c2",null).exports}}]);
|
1
public/js/build/189.js
vendored
1
public/js/build/189.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/build/252.js
vendored
2
public/js/build/252.js
vendored
File diff suppressed because one or more lines are too long
1
public/js/build/258.js
vendored
Normal file
1
public/js/build/258.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[258],{98258:(t,e,s)=>{s.r(e),s.d(e,{default:()=>o});function n(t,e){var s=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),s.push.apply(s,n)}return s}function i(t){for(var e=1;e<arguments.length;e++){var s=null!=arguments[e]?arguments[e]:{};e%2?n(Object(s),!0).forEach((function(e){r(t,e,s[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(s)):n(Object(s)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(s,e))}))}return t}function r(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const a={data:function(){return{curPath:this.$route.path,show768Menu:!0,version:window.systemInfo.version}},mounted:function(){},computed:i(i({},(0,s(20629).rn)(["userInfo","userIsAdmin"])),{},{menu:function(){var t=[{path:"personal",name:"个人设置"},{path:"password",name:"密码设置"}];return this.userIsAdmin&&t.push.apply(t,[{path:"system",name:"系统设置",divided:!0}]),t},titleNameRoute:function(){var t=this.curPath,e=this.menu,s="";return e.some((function(e){if($A.leftExists(t,"/manage/setting/"+e.path))return s=e.name,!0})),s||"设置"}}),watch:{$route:function(t){this.curPath=t.path}},methods:{toggleRoute:function(t){this.show768Menu=!1,this.goForward({path:"/manage/setting/"+t})},classNameRoute:function(t,e){return{active:$A.leftExists(this.curPath,"/manage/setting/"+t),divided:!!e}}}};const o=(0,s(51900).Z)(a,(function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",{staticClass:"page-setting"},[s("PageTitle",{attrs:{title:t.$L(t.titleNameRoute)}}),t._v(" "),s("div",{staticClass:"setting-head"},[s("div",{staticClass:"setting-titbox"},[s("div",{staticClass:"setting-title"},[s("h1",[t._v(t._s(t.$L("设置")))]),t._v(" "),s("div",{staticClass:"setting-more",on:{click:function(e){t.show768Menu=!t.show768Menu}}},[s("Icon",{attrs:{type:t.show768Menu?"md-close":"md-more"}})],1)])])]),t._v(" "),s("div",{staticClass:"setting-box"},[s("div",{staticClass:"setting-menu",class:{"show768-menu":t.show768Menu}},[s("ul",[t._l(t.menu,(function(e,n){return s("li",{key:n,class:t.classNameRoute(e.path,e.divided),on:{click:function(s){return t.toggleRoute(e.path)}}},[t._v(t._s(t.$L(e.name)))])})),t._v(" "),s("li",{staticClass:"version divided"},[s("AutoTip",[t._v(t._s(t.$L("版本"))+": "+t._s(t.version))])],1)],2)]),t._v(" "),s("div",{staticClass:"setting-content"},[s("div",{staticClass:"setting-content-title"},[t._v(t._s(t.$L(t.titleNameRoute)))]),t._v(" "),s("div",{staticClass:"setting-content-view"},[s("router-view",{staticClass:"setting-router-view"})],1)])])],1)}),[],!1,null,null,null).exports}}]);
|
File diff suppressed because one or more lines are too long
2
public/js/build/400.js
vendored
Normal file
2
public/js/build/400.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/build/405.js
vendored
1
public/js/build/405.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/js/build/423.js
vendored
2
public/js/build/423.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/43.js
vendored
2
public/js/build/43.js
vendored
File diff suppressed because one or more lines are too long
2
public/js/build/525.js
vendored
2
public/js/build/525.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/755.js
vendored
Normal file
1
public/js/build/755.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/js/build/805.js
vendored
1
public/js/build/805.js
vendored
@ -1 +0,0 @@
|
||||
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[805],{80805:(t,e,o)=>{o.r(e),o.d(e,{default:()=>s});function n(t,e){var o=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),o.push.apply(o,n)}return o}function r(t,e,o){return e in t?Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0,writable:!0}):t[e]=o,t}const a={data:function(){return{loadIng:0,formDatum:[],nullDatum:{name:"",priority:1,days:1,color:"#8bcf70"}}},mounted:function(){this.systemSetting()},computed:function(t){for(var e=1;e<arguments.length;e++){var o=null!=arguments[e]?arguments[e]:{};e%2?n(Object(o),!0).forEach((function(e){r(t,e,o[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):n(Object(o)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e))}))}return t}({},(0,o(20629).rn)(["taskPriority"])),watch:{taskPriority:{handler:function(t){this.formDatum=$A.cloneJSON(t),0===this.formDatum.length&&this.addDatum()},immediate:!0}},methods:{submitForm:function(){var t=this;this.$refs.formDatum.validate((function(e){e&&t.systemSetting(!0)}))},resetForm:function(){this.formDatum=$A.cloneJSON(this.taskPriority)},addDatum:function(){this.formDatum.push($A.cloneJSON(this.nullDatum))},delDatum:function(t){this.formDatum.splice(t,1),0===this.formDatum.length&&this.addDatum()},systemSetting:function(t){var e=this;this.loadIng++,this.$store.dispatch("call",{url:"system/priority?type="+(t?"save":"get"),method:"post",data:{list:this.formDatum}}).then((function(o){var n=o.data;t&&$A.messageSuccess("修改成功"),e.loadIng--,e.$store.state.taskPriority=$A.cloneJSON(n)})).catch((function(o){var n=o.msg;t&&$A.modalError(n),e.loadIng--}))}}};const s=(0,o(51900).Z)(a,(function(){var t=this,e=t.$createElement,o=t._self._c||e;return o("div",{staticClass:"setting-item submit"},[o("Form",{ref:"formDatum",attrs:{"label-width":"auto"},nativeOn:{submit:function(t){t.preventDefault()}}},[o("Row",{staticClass:"setting-color"},[o("Col",{attrs:{span:"12"}},[t._v(t._s(t.$L("名称")))]),t._v(" "),o("Col",{attrs:{span:"4"}},[o("ETooltip",{attrs:{content:t.$L("数值越小级别越高"),"max-width":"auto",placement:"top",transfer:""}},[o("div",[o("Icon",{staticClass:"information",attrs:{type:"ios-information-circle-outline"}}),t._v(" "+t._s(t.$L("级别")))],1)])],1),t._v(" "),o("Col",{attrs:{span:"4"}},[o("ETooltip",{attrs:{content:t.$L("任务完成时间"),"max-width":"auto",placement:"top",transfer:""}},[o("div",[o("Icon",{staticClass:"information",attrs:{type:"ios-information-circle-outline"}}),t._v(" "+t._s(t.$L("天数")))],1)])],1),t._v(" "),o("Col",{attrs:{span:"4"}},[t._v(t._s(t.$L("颜色")))])],1),t._v(" "),t._l(t.formDatum,(function(e,n){return o("Row",{key:n,staticClass:"setting-color"},[o("Col",{attrs:{span:"12"}},[o("Input",{attrs:{maxlength:20,placeholder:t.$L("请输入名称"),clearable:""},on:{"on-clear":function(e){return t.delDatum(n)}},model:{value:e.name,callback:function(o){t.$set(e,"name",o)},expression:"item.name"}})],1),t._v(" "),o("Col",{attrs:{span:"4"}},[o("Input",{attrs:{type:"number"},model:{value:e.priority,callback:function(o){t.$set(e,"priority",o)},expression:"item.priority"}})],1),t._v(" "),o("Col",{attrs:{span:"4"}},[o("Input",{attrs:{type:"number"},model:{value:e.days,callback:function(o){t.$set(e,"days",o)},expression:"item.days"}})],1),t._v(" "),o("Col",{attrs:{span:"4"}},[o("ColorPicker",{attrs:{recommend:"",transfer:""},model:{value:e.color,callback:function(o){t.$set(e,"color",o)},expression:"item.color"}})],1)],1)})),t._v(" "),o("Button",{attrs:{type:"default",icon:"md-add"},on:{click:t.addDatum}},[t._v(t._s(t.$L("添加优先级")))])],2),t._v(" "),o("div",{staticClass:"setting-footer"},[o("Button",{attrs:{loading:t.loadIng>0,type:"primary"},on:{click:t.submitForm}},[t._v(t._s(t.$L("提交")))]),t._v(" "),o("Button",{staticStyle:{"margin-left":"8px"},attrs:{loading:t.loadIng>0},on:{click:t.resetForm}},[t._v(t._s(t.$L("重置")))])],1)],1)}),[],!1,null,null,null).exports}}]);
|
File diff suppressed because one or more lines are too long
1
public/js/build/942.js
vendored
Normal file
1
public/js/build/942.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
"use strict";(self.webpackChunkDooTask=self.webpackChunkDooTask||[]).push([[942],{85916:(e,t,i)=>{i.d(t,{Z:()=>r});var n=i(1519),o=i.n(n)()((function(e){return e[1]}));o.push([e.id,".component-only-office[data-v-1ec144f0]{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.component-only-office .placeholder[data-v-1ec144f0]{flex:1;height:100%;width:100%}.component-only-office .office-loading[data-v-1ec144f0]{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0;z-index:2}",""]);const r=o},17942:(e,t,i)=>{i.r(t),i.d(t,{default:()=>f});var n=i(20629);function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?o(Object(i),!0).forEach((function(t){c(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):o(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function c(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}const a={name:"OnlyOffice",props:{id:{type:String,default:function(){return"office_"+Math.round(1e4*Math.random())}},code:{type:String,default:""},value:{type:[Object,Array],default:function(){return{}}},readOnly:{type:Boolean,default:!1},documentKey:Function},data:function(){return{loadIng:0,docEditor:null}},mounted:function(){},beforeDestroy:function(){null!==this.docEditor&&(this.docEditor.destroyEditor(),this.docEditor=null)},computed:r(r({},(0,n.rn)(["userToken","userInfo","themeIsDark"])),{},{fileType:function(){return this.getType(this.value.type)},fileName:function(){return this.value.name}}),watch:{"value.id":{handler:function(e){var t=this;e&&(this.loadIng++,$A.loadScript($A.apiUrl("../office/web-apps/apps/api/documents/api.js"),(function(e){if(t.loadIng--,null===e)if(t.documentKey){var i=t.documentKey();i&&i.then?i.then(t.loadFile):t.loadFile()}else t.handleClose();else $A.modalAlert("组件加载失败!")})))},immediate:!0}},methods:{getType:function(e){switch(e){case"word":return"docx";case"excel":return"xlsx";case"ppt":return"pptx"}return e},loadFile:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";null!==this.docEditor&&(this.docEditor.destroyEditor(),this.docEditor=null);var i="zh";switch(this.getLanguage()){case"CN":case"TC":i="zh";break;default:i="en"}var n=this.code||this.value.id,o=$A.strExists(this.fileName,".")?this.fileName:this.fileName+"."+this.fileType,r={document:{fileType:this.fileType,key:"".concat(this.fileType,"-").concat(n,"-").concat(t),title:o,url:"http://nginx/api/file/content/?id=".concat(n,"&token=").concat(this.userToken)},editorConfig:{mode:"edit",lang:i,user:{id:this.userInfo.userid,name:this.userInfo.nickname},customization:{uiTheme:this.themeIsDark?"theme-dark":"theme-classic-light"},callbackUrl:"http://nginx/api/file/content/office?id=".concat(n,"&token=").concat(this.userToken)}};if(/\/hideenOfficeTitle\//.test(window.navigator.userAgent)&&(r.document.title=" "),$A.leftExists(n,"msgFile_")?r.document.url="http://nginx/api/dialog/msg/download/?msg_id=".concat($A.leftDelete(n,"msgFile_"),"&token=").concat(this.userToken):$A.leftExists(n,"taskFile_")&&(r.document.url="http://nginx/api/project/task/filedown/?file_id=".concat($A.leftDelete(n,"taskFile_"),"&token=").concat(this.userToken)),this.readOnly&&(r.editorConfig.mode="view",r.editorConfig.callbackUrl=null,!r.editorConfig.user.id)){var c=$A.getStorageInt("viewer");c||(c=$A.randNum(1e3,99999),$A.setStorage("viewer",c)),r.editorConfig.user.id="viewer_"+c,r.editorConfig.user.name="Viewer_"+c}this.$nextTick((function(){e.docEditor=new DocsAPI.DocEditor(e.id,r)}))}}};var l=i(93379),s=i.n(l),d=i(85916),u={insert:"head",singleton:!1};s()(d.Z,u);d.Z.locals;const f=(0,i(51900).Z)(a,(function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"component-only-office"},[i("div",{staticClass:"placeholder",attrs:{id:this.id}}),e._v(" "),e.loadIng>0?i("div",{staticClass:"office-loading"},[i("Loading")],1):e._e()])}),[],!1,null,"1ec144f0",null).exports}}]);
|
@ -45,13 +45,14 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'isDesktop',
|
||||
'wsOpenNum',
|
||||
]),
|
||||
repoTitle() {
|
||||
return this.repoStatus == 2 ? '更新客户端' : '客户端下载';
|
||||
},
|
||||
showButton() {
|
||||
return this.repoStatus && !this.$store.state.windowMax768 && ['login', 'manage-dashboard'].includes(this.$route.name)
|
||||
return this.repoStatus && this.isDesktop && ['login', 'manage-dashboard'].includes(this.$route.name)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -225,9 +225,12 @@
|
||||
this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
|
||||
this.$emit('input', this.$refs.upload.fileList);
|
||||
},
|
||||
handleProgress() {
|
||||
handleProgress(event, file) {
|
||||
//开始上传
|
||||
this.$emit('update:uploadIng', this.uploadIng + 1);
|
||||
if (file._uploadIng === undefined) {
|
||||
file._uploadIng = true;
|
||||
this.$emit('update:uploadIng', this.uploadIng + 1);
|
||||
}
|
||||
},
|
||||
handleSuccess (res, file) {
|
||||
//上传完成
|
||||
|
@ -248,9 +248,12 @@
|
||||
|
||||
/********************文件上传部分************************/
|
||||
|
||||
handleProgress() {
|
||||
handleProgress(event, file) {
|
||||
//开始上传
|
||||
this.uploadIng++;
|
||||
if (file._uploadIng === undefined) {
|
||||
file._uploadIng = true;
|
||||
this.uploadIng++;
|
||||
}
|
||||
},
|
||||
|
||||
handleSuccess(res, file) {
|
||||
|
@ -60,6 +60,7 @@ export default {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
documentKey: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -90,7 +91,7 @@ export default {
|
||||
|
||||
fileName() {
|
||||
return this.value.name;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
@ -104,8 +105,17 @@ export default {
|
||||
this.loadIng--;
|
||||
if (e !== null) {
|
||||
$A.modalAlert("组件加载失败!");
|
||||
return;
|
||||
}
|
||||
if (!this.documentKey) {
|
||||
this.handleClose();
|
||||
return
|
||||
}
|
||||
const documentKey = this.documentKey();
|
||||
if (documentKey && documentKey.then) {
|
||||
documentKey.then(this.loadFile);
|
||||
} else {
|
||||
this.loadFile()
|
||||
this.loadFile();
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -126,7 +136,7 @@ export default {
|
||||
return type;
|
||||
},
|
||||
|
||||
loadFile() {
|
||||
loadFile(keyAppend = '') {
|
||||
if (this.docEditor !== null) {
|
||||
this.docEditor.destroyEditor();
|
||||
this.docEditor = null;
|
||||
@ -148,9 +158,9 @@ export default {
|
||||
const config = {
|
||||
"document": {
|
||||
"fileType": this.fileType,
|
||||
"key": this.fileType + '-' + fileKey,
|
||||
"key": `${this.fileType}-${fileKey}-${keyAppend}`,
|
||||
"title": fileName,
|
||||
"url": 'http://nginx/api/file/content/?id=' + fileKey + '&token=' + this.userToken,
|
||||
"url": `http://nginx/api/file/content/?id=${fileKey}&token=${this.userToken}`,
|
||||
},
|
||||
"editorConfig": {
|
||||
"mode": "edit",
|
||||
@ -162,16 +172,16 @@ export default {
|
||||
"customization": {
|
||||
"uiTheme": this.themeIsDark ? "theme-dark" : "theme-classic-light",
|
||||
},
|
||||
"callbackUrl": 'http://nginx/api/file/content/office?id=' + fileKey + '&token=' + this.userToken,
|
||||
"callbackUrl": `http://nginx/api/file/content/office?id=${fileKey}&token=${this.userToken}`,
|
||||
}
|
||||
};
|
||||
if (/\/hideenOfficeTitle\//.test(window.navigator.userAgent)) {
|
||||
config.document.title = " ";
|
||||
}
|
||||
if ($A.leftExists(fileKey, "msgFile_")) {
|
||||
config.document.url = 'http://nginx/api/dialog/msg/download/?msg_id=' + $A.leftDelete(fileKey, "msgFile_") + '&token=' + this.userToken;
|
||||
config.document.url = `http://nginx/api/dialog/msg/download/?msg_id=${$A.leftDelete(fileKey, "msgFile_")}&token=${this.userToken}`;
|
||||
} else if ($A.leftExists(fileKey, "taskFile_")) {
|
||||
config.document.url = 'http://nginx/api/project/task/filedown/?file_id=' + $A.leftDelete(fileKey, "taskFile_") + '&token=' + this.userToken;
|
||||
config.document.url = `http://nginx/api/project/task/filedown/?file_id=${$A.leftDelete(fileKey, "taskFile_")}&token=${this.userToken}`;
|
||||
}
|
||||
if (this.readOnly) {
|
||||
config.editorConfig.mode = "view";
|
||||
|
@ -145,7 +145,7 @@
|
||||
transfer: false,
|
||||
|
||||
uploadIng: 0,
|
||||
uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz'],
|
||||
uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz', 'ai', 'avi', 'bmp', 'cdr', 'eps', 'mov', 'mp3', 'mp4', 'pr', 'psd', 'svg', 'tif'],
|
||||
actionUrl: $A.apiUrl('system/fileupload'),
|
||||
maxSize: 10240
|
||||
};
|
||||
@ -474,9 +474,12 @@
|
||||
|
||||
/********************文件上传部分************************/
|
||||
|
||||
handleProgress() {
|
||||
handleProgress(event, file) {
|
||||
//开始上传
|
||||
this.uploadIng++;
|
||||
if (file._uploadIng === undefined) {
|
||||
file._uploadIng = true;
|
||||
this.uploadIng++;
|
||||
}
|
||||
},
|
||||
|
||||
handleSuccess(res, file) {
|
||||
|
9
resources/assets/js/functions/common.js
vendored
9
resources/assets/js/functions/common.js
vendored
@ -520,6 +520,15 @@
|
||||
return (ua.match(/Chrome/i) + '' === 'chrome');
|
||||
},
|
||||
|
||||
/**
|
||||
* 是否桌面端
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isDesktop(){
|
||||
let ua = typeof window !== 'undefined' && window.navigator.userAgent;
|
||||
return !ua.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取对象
|
||||
* @param obj
|
||||
|
3
resources/assets/js/language/index.js
vendored
3
resources/assets/js/language/index.js
vendored
@ -118,6 +118,9 @@ export default {
|
||||
* @param language
|
||||
*/
|
||||
setLanguage(language) {
|
||||
if (language === undefined) {
|
||||
return
|
||||
}
|
||||
this.__initLanguageData();
|
||||
setTimeout(() => {
|
||||
window.localStorage['__language:type__'] = language;
|
||||
|
@ -138,9 +138,15 @@
|
||||
</FormItem>
|
||||
<FormItem v-else :label="$L('项目模板')">
|
||||
<Select :value="0" @on-change="selectChange" :placeholder="$L('请选择模板')">
|
||||
<Option v-for="(item, index) in columns" :value="index" :key="index">{{ item.label }}</Option>
|
||||
<Option v-for="(item, index) in columns" :value="index" :key="index">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem prop="flow" :label="$L('开启工作流')">
|
||||
<RadioGroup v-model="addData.flow">
|
||||
<Radio label="open">{{$L('开启')}}</Radio>
|
||||
<Radio label="close">{{$L('关闭')}}</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
<Button type="default" @click="addShow=false">{{$L('取消')}}</Button>
|
||||
@ -250,6 +256,7 @@ export default {
|
||||
addData: {
|
||||
name: '',
|
||||
columns: '',
|
||||
flow: 'open',
|
||||
},
|
||||
addRule: {},
|
||||
|
||||
@ -258,8 +265,6 @@ export default {
|
||||
|
||||
dialogMsgSubscribe: null,
|
||||
|
||||
columns: [],
|
||||
|
||||
projectKeyValue: '',
|
||||
projectKeyAlready: {},
|
||||
projectKeyLoading: 0,
|
||||
@ -331,6 +336,7 @@ export default {
|
||||
'projectTotal',
|
||||
'taskId',
|
||||
'wsOpenNum',
|
||||
'columnTemplate',
|
||||
|
||||
'themeMode',
|
||||
'themeList',
|
||||
@ -370,7 +376,6 @@ export default {
|
||||
{path: 'password', name: '密码设置'},
|
||||
{path: 'clearCache', name: '清除缓存'},
|
||||
{path: 'system', name: '系统设置', divided: true},
|
||||
{path: 'priority', name: '任务等级'},
|
||||
{path: 'workReport', name: '工作报告', divided: true},
|
||||
{path: 'allUser', name: '团队管理'},
|
||||
{path: 'allProject', name: '所有项目'},
|
||||
@ -387,6 +392,15 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
columns() {
|
||||
const array = $A.cloneJSON(this.columnTemplate);
|
||||
array.unshift({
|
||||
name: this.$L('空白模板'),
|
||||
columns: [],
|
||||
})
|
||||
return array
|
||||
},
|
||||
|
||||
projectLists() {
|
||||
const {projectKeyValue, cacheProjects} = this;
|
||||
const data = cacheProjects.sort((a, b) => {
|
||||
@ -483,16 +497,6 @@ export default {
|
||||
|
||||
methods: {
|
||||
initLanguage() {
|
||||
this.columns = [{
|
||||
label: this.$L('空白模板'),
|
||||
value: [],
|
||||
}, {
|
||||
label: this.$L('软件开发'),
|
||||
value: [this.$L('产品规划'), this.$L('前端开发'), this.$L('后端开发'), this.$L('测试'), this.$L('发布'), this.$L('其它')],
|
||||
}, {
|
||||
label: this.$L('产品开发'),
|
||||
value: [this.$L('产品计划'), this.$L('正在设计'), this.$L('正在研发'), this.$L('测试'), this.$L('准备发布'), this.$L('发布成功')],
|
||||
}];
|
||||
this.addRule = {
|
||||
name: [
|
||||
{ required: true, message: this.$L('请填写项目名称!'), trigger: 'change' },
|
||||
@ -512,6 +516,9 @@ export default {
|
||||
},
|
||||
|
||||
setTheme(mode) {
|
||||
if (mode === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!$A.isChrome()) {
|
||||
$A.modalWarning("仅客户端或Chrome浏览器支持主题功能");
|
||||
return;
|
||||
@ -571,7 +578,7 @@ export default {
|
||||
title: '退出登录',
|
||||
content: '你确定要登出系统?',
|
||||
onOk: () => {
|
||||
this.$store.dispatch("logout")
|
||||
this.$store.dispatch("logout", false)
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -593,6 +600,7 @@ export default {
|
||||
},
|
||||
|
||||
onAddShow() {
|
||||
this.$store.dispatch("getColumnTemplate").catch(() => {})
|
||||
this.addShow = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.projectName.focus();
|
||||
@ -643,7 +651,7 @@ export default {
|
||||
|
||||
selectChange(index) {
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.addData, 'columns', this.columns[index].value.join(','));
|
||||
this.$set(this.addData, 'columns', this.columns[index].columns.join(','));
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -34,7 +34,27 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
uploadFormat: ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz', 'ai', 'avi', 'bmp', 'cdr', 'eps', 'mov', 'mp3', 'mp4', 'pr', 'psd', 'svg', 'tif'],
|
||||
uploadFormat: [
|
||||
'docx', 'wps', 'doc', 'xls', 'xlsx', 'ppt', 'pptx',
|
||||
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'raw',
|
||||
'rar', 'zip', 'jar', '7-zip', 'tar', 'gzip', '7z',
|
||||
'tif', 'tiff',
|
||||
'dwg', 'dxf',
|
||||
'ofd',
|
||||
'pdf',
|
||||
'txt',
|
||||
'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css',
|
||||
'dockerfile', 'go', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile',
|
||||
'ocamlmakefile', 'make', 'md', 'markdown', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php',
|
||||
'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile',
|
||||
'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml',
|
||||
'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml',
|
||||
'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx',
|
||||
'mp3', 'wav', 'mp4', 'flv',
|
||||
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm',
|
||||
'xmind',
|
||||
'rp',
|
||||
],
|
||||
actionUrl: $A.apiUrl('dialog/msg/sendfile'),
|
||||
}
|
||||
},
|
||||
@ -59,7 +79,7 @@ export default {
|
||||
methods: {
|
||||
handleProgress(event, file) {
|
||||
//上传时
|
||||
if (typeof file.tempId === "undefined") {
|
||||
if (file.tempId === undefined) {
|
||||
file.tempId = $A.randomString(8);
|
||||
this.$emit('on-progress', file);
|
||||
}
|
||||
|
@ -159,10 +159,10 @@ export default {
|
||||
|
||||
computed: {
|
||||
...mapState([
|
||||
'isDesktop',
|
||||
'userId',
|
||||
'cacheDialogs',
|
||||
'dialogMsgs',
|
||||
'windowMax768',
|
||||
]),
|
||||
|
||||
dialogData() {
|
||||
@ -181,7 +181,7 @@ export default {
|
||||
},
|
||||
|
||||
isAutoBottom() {
|
||||
if (this.windowMax768 && this.inputFocus) {
|
||||
if (this.inputFocus && !this.isDesktop) {
|
||||
return false;
|
||||
}
|
||||
return this.autoBottom
|
||||
@ -268,7 +268,7 @@ export default {
|
||||
text: this.msgText,
|
||||
},
|
||||
});
|
||||
if (this.windowMax768) {
|
||||
if (!this.isDesktop) {
|
||||
this.$refs.input.blur();
|
||||
}
|
||||
this.autoToBottom();
|
||||
@ -368,7 +368,7 @@ export default {
|
||||
userid: this.userId,
|
||||
msg: { },
|
||||
});
|
||||
if (this.windowMax768) {
|
||||
if (!this.isDesktop) {
|
||||
this.$refs.input.blur();
|
||||
}
|
||||
this.autoToBottom();
|
||||
|
@ -52,7 +52,7 @@
|
||||
</template>
|
||||
<Flow v-else-if="file.type=='flow'" ref="myFlow" v-model="contentDetail" @saveData="handleClick('saveBefore')"/>
|
||||
<Minder v-else-if="file.type=='mind'" ref="myMind" v-model="contentDetail" @saveData="handleClick('saveBefore')"/>
|
||||
<OnlyOffice v-else-if="['word', 'excel', 'ppt'].includes(file.type)" v-model="contentDetail"/>
|
||||
<OnlyOffice v-else-if="['word', 'excel', 'ppt'].includes(file.type)" v-model="contentDetail" :documentKey="documentKey"/>
|
||||
<AceEditor v-else-if="['code', 'txt'].includes(file.type)" v-model="contentDetail.content" :ext="file.ext" @saveData="handleClick('saveBefore')"/>
|
||||
</div>
|
||||
</template>
|
||||
@ -330,6 +330,22 @@ export default {
|
||||
this.unsaveTip = false;
|
||||
},
|
||||
|
||||
documentKey() {
|
||||
return new Promise(resolve => {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'file/content',
|
||||
data: {
|
||||
id: this.fileId,
|
||||
only_update_at: 'yes'
|
||||
},
|
||||
}).then(({data}) => {
|
||||
resolve($A.Date(data.update_at, true))
|
||||
}).catch(() => {
|
||||
resolve(0)
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
formatName(file) {
|
||||
let {name, ext} = file;
|
||||
if (ext != '') {
|
||||
|
@ -29,7 +29,7 @@
|
||||
</template>
|
||||
<Flow v-else-if="file.type=='flow'" ref="myFlow" v-model="contentDetail" readOnly/>
|
||||
<Minder v-else-if="file.type=='mind'" ref="myMind" v-model="contentDetail" readOnly/>
|
||||
<OnlyOffice v-else-if="['word', 'excel', 'ppt'].includes(file.type)" v-model="contentDetail" :code="code" readOnly/>
|
||||
<OnlyOffice v-else-if="['word', 'excel', 'ppt'].includes(file.type)" v-model="contentDetail" :code="code" :documentKey="documentKey" readOnly/>
|
||||
<AceEditor v-else-if="['code', 'txt'].includes(file.type)" v-model="contentDetail.content" :ext="file.ext" readOnly/>
|
||||
</div>
|
||||
</template>
|
||||
@ -144,6 +144,22 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
documentKey() {
|
||||
return new Promise(resolve => {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'file/content',
|
||||
data: {
|
||||
id: this.code || this.file.id,
|
||||
only_update_at: 'yes'
|
||||
},
|
||||
}).then(({data}) => {
|
||||
resolve($A.Date(data.update_at, true))
|
||||
}).catch(() => {
|
||||
resolve(0)
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
exportMenu(act) {
|
||||
switch (this.file.type) {
|
||||
case 'mind':
|
||||
|
@ -91,7 +91,7 @@
|
||||
<Draggable
|
||||
:list="columnList"
|
||||
:animation="150"
|
||||
:disabled="sortDisabled || windowMax768"
|
||||
:disabled="sortDisabled || !isDesktop"
|
||||
class="column-list"
|
||||
tag="ul"
|
||||
draggable=".column-item"
|
||||
@ -146,7 +146,7 @@
|
||||
<Draggable
|
||||
:list="column.tasks"
|
||||
:animation="150"
|
||||
:disabled="sortDisabled || windowMax768"
|
||||
:disabled="sortDisabled || !isDesktop"
|
||||
class="task-list"
|
||||
draggable=".task-draggable"
|
||||
group="task"
|
||||
@ -528,8 +528,8 @@ export default {
|
||||
|
||||
computed: {
|
||||
...mapState([
|
||||
'isDesktop',
|
||||
'windowWidth',
|
||||
'windowMax768',
|
||||
|
||||
'userId',
|
||||
'cacheDialogs',
|
||||
|
@ -61,6 +61,7 @@
|
||||
<Draggable
|
||||
:list="data.project_flow_item"
|
||||
:animation="150"
|
||||
:disabled="!isDesktop"
|
||||
class="taskflow-config-table-list-wrapper"
|
||||
tag="div"
|
||||
draggable=".column-border"
|
||||
@ -172,6 +173,7 @@
|
||||
<script>
|
||||
import Draggable from "vuedraggable";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "ProjectWorkflow",
|
||||
@ -199,7 +201,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
...mapState(['isDesktop'])
|
||||
},
|
||||
|
||||
watch: {
|
||||
|
@ -30,7 +30,7 @@
|
||||
:plugins="taskPlugins"
|
||||
:options="taskOptions"
|
||||
:option-full="taskOptionFull"
|
||||
:placeholder="$L($store.state.windowMax768 ? '详细描述,选填...' : '详细描述,选填...(点击右键使用工具栏)')"
|
||||
:placeholder="$L(isDesktop ? '详细描述,选填...(点击右键使用工具栏)' : '详细描述,选填...')"
|
||||
:placeholderFull="$L('详细描述...')"
|
||||
inline/>
|
||||
</div>
|
||||
@ -82,7 +82,8 @@
|
||||
v-model="addData.owner"
|
||||
:multiple-max="10"
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:project-id="addData.project_id"/>
|
||||
:project-id="addData.project_id"
|
||||
:transfer="false"/>
|
||||
<div v-if="showAddAssist" class="task-add-assist">
|
||||
<Checkbox v-model="addData.add_assist" :true-value="1" :false-value="0">{{$L('加入任务协助人员列表')}}</Checkbox>
|
||||
<ETooltip :content="$L('你不是任务负责人时建议加入任务协助人员列表')">
|
||||
@ -231,7 +232,7 @@ export default {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(['userId', 'cacheProjects', 'projectId', 'cacheColumns', 'taskPriority']),
|
||||
...mapState(['isDesktop', 'userId', 'cacheProjects', 'projectId', 'cacheColumns', 'taskPriority']),
|
||||
|
||||
taskDays() {
|
||||
const {times} = this.addData;
|
||||
|
@ -41,6 +41,7 @@
|
||||
<Poptip
|
||||
ref="owner"
|
||||
class="subtask-avatar"
|
||||
popper-class="task-detail-user-popper"
|
||||
:title="$L('修改负责人')"
|
||||
:width="240"
|
||||
placement="bottom"
|
||||
@ -52,7 +53,8 @@
|
||||
v-model="ownerData.owner_userid"
|
||||
:multiple-max="1"
|
||||
:project-id="taskDetail.project_id"
|
||||
:placeholder="$L('选择任务负责人')"/>
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:transfer="false"/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
@ -189,6 +191,7 @@
|
||||
:title="$L('修改负责人')"
|
||||
:width="240"
|
||||
class="item-content user"
|
||||
popper-class="task-detail-user-popper"
|
||||
placement="bottom"
|
||||
@on-popper-show="openOwner"
|
||||
@on-ok="onOwner"
|
||||
@ -198,7 +201,8 @@
|
||||
v-model="ownerData.owner_userid"
|
||||
:multiple-max="10"
|
||||
:project-id="taskDetail.project_id"
|
||||
:placeholder="$L('选择任务负责人')"/>
|
||||
:placeholder="$L('选择任务负责人')"
|
||||
:transfer="false"/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
@ -217,6 +221,7 @@
|
||||
:title="$L(getAssist.length > 0 ? '修改协助人员' : '添加协助人员')"
|
||||
:width="280"
|
||||
class="item-content user"
|
||||
popper-class="task-detail-user-popper"
|
||||
placement="bottom"
|
||||
@on-popper-show="openAssist"
|
||||
@on-ok="onAssist"
|
||||
@ -227,7 +232,8 @@
|
||||
:multiple-max="10"
|
||||
:project-id="taskDetail.project_id"
|
||||
:disabled-choice="assistData.disabled"
|
||||
:placeholder="$L('选择任务协助人员')"/>
|
||||
:placeholder="$L('选择任务协助人员')"
|
||||
:transfer="false"/>
|
||||
<div class="task-detail-avatar-buttons">
|
||||
<Button size="small" type="primary" @click="$refs.assist.ok()">{{$L('确定')}}</Button>
|
||||
</div>
|
||||
|
@ -41,6 +41,8 @@
|
||||
<Option value="">{{$L('全部')}}</Option>
|
||||
<Option value="admin">{{$L('管理员')}}</Option>
|
||||
<Option value="disable">{{$L('禁用')}}</Option>
|
||||
<Option value="noadmin">{{$L('非管理员')}}</Option>
|
||||
<Option value="nodisable">{{$L('非禁用')}}</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -657,7 +657,7 @@ export default {
|
||||
const file = this.files.find(({id}) => id == row.id);
|
||||
if (file) {
|
||||
setTimeout(() => {
|
||||
this.$set(file, '_edit', b);
|
||||
this.setEdit(file.id, b)
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
@ -909,7 +909,7 @@ export default {
|
||||
|
||||
case 'rename':
|
||||
this.$set(item, 'newname', item.name);
|
||||
this.$set(item, '_edit', true);
|
||||
this.setEdit(item.id, true)
|
||||
this.autoBlur(item.id)
|
||||
break;
|
||||
|
||||
@ -1107,18 +1107,18 @@ export default {
|
||||
if (isCreate) {
|
||||
this.$store.dispatch("forgetFile", item.id);
|
||||
} else {
|
||||
this.$set(item, '_edit', false);
|
||||
this.setEdit(item.id, false)
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (item.newname == item.name) {
|
||||
this.$set(item, '_edit', false);
|
||||
this.setEdit(item.id, false)
|
||||
return;
|
||||
}
|
||||
if (item._load) {
|
||||
return;
|
||||
}
|
||||
this.$set(item, '_load', true);
|
||||
this.setLoad(item.id, true)
|
||||
this.$store.dispatch("call", {
|
||||
url: 'file/add',
|
||||
data: {
|
||||
@ -1129,21 +1129,35 @@ export default {
|
||||
},
|
||||
}).then(({data, msg}) => {
|
||||
$A.messageSuccess(msg)
|
||||
this.$set(item, '_load', false);
|
||||
this.$set(item, '_edit', false);
|
||||
this.setLoad(item.id, false)
|
||||
this.setEdit(item.id, false)
|
||||
this.$store.dispatch("saveFile", data);
|
||||
if (isCreate) {
|
||||
this.$store.dispatch("forgetFile", item.id);
|
||||
}
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg)
|
||||
this.$set(item, '_load', false);
|
||||
this.setLoad(item.id, false)
|
||||
if (isCreate) {
|
||||
this.$store.dispatch("forgetFile", item.id);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setEdit(fileId, is) {
|
||||
let item = this.$store.state.files.find(({id}) => id == fileId)
|
||||
if (item) {
|
||||
this.$set(item, '_edit', is);
|
||||
}
|
||||
},
|
||||
|
||||
setLoad(fileId, is) {
|
||||
let item = this.$store.state.files.find(({id}) => id == fileId)
|
||||
if (item) {
|
||||
this.$set(item, '_load', is);
|
||||
}
|
||||
},
|
||||
|
||||
onSearchFocus() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.searchInput.focus({
|
||||
@ -1267,7 +1281,10 @@ export default {
|
||||
|
||||
handleProgress(event, file, fileList) {
|
||||
//开始上传
|
||||
this.uploadIng++;
|
||||
if (file._uploadIng === undefined) {
|
||||
file._uploadIng = true;
|
||||
this.uploadIng++;
|
||||
}
|
||||
this.uploadUpdate(fileList);
|
||||
},
|
||||
|
||||
|
@ -56,7 +56,6 @@ export default {
|
||||
if (this.userIsAdmin) {
|
||||
menu.push(...[
|
||||
{path: 'system', name: '系统设置', divided: true},
|
||||
{path: 'priority', name: '任务等级'},
|
||||
])
|
||||
}
|
||||
return menu;
|
||||
|
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div class="setting-system-item">
|
||||
<Form ref="formDatum" label-width="auto" @submit.native.prevent>
|
||||
<Row class="setting-template">
|
||||
<Col span="8">{{$L('名称')}}</Col>
|
||||
<Col span="16">{{$L('项目模板')}}</Col>
|
||||
</Row>
|
||||
<Row v-for="(item, key) in formDatum" :key="key" class="setting-template">
|
||||
<Col span="8">
|
||||
<Input
|
||||
v-model="item.name"
|
||||
:maxlength="20"
|
||||
:placeholder="$L('请输入名称')"
|
||||
clearable
|
||||
@on-clear="delDatum(key)"/>
|
||||
</Col>
|
||||
<Col span="16">
|
||||
<TagInput v-model="item.columns"/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Button type="default" icon="md-add" @click="addDatum">{{$L('添加模板')}}</Button>
|
||||
</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>
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: 'SystemColumnTemplate',
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
|
||||
formDatum: [],
|
||||
|
||||
nullDatum: {
|
||||
'name': '',
|
||||
'columns': '',
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.systemSetting();
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['columnTemplate']),
|
||||
},
|
||||
|
||||
watch: {
|
||||
columnTemplate: {
|
||||
handler(data) {
|
||||
this.formDatum = $A.cloneJSON(data);
|
||||
if (this.formDatum.length === 0) {
|
||||
this.addDatum();
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submitForm() {
|
||||
this.$refs.formDatum.validate((valid) => {
|
||||
if (valid) {
|
||||
this.systemSetting(true);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.formDatum = $A.cloneJSON(this.columnTemplate);
|
||||
},
|
||||
|
||||
addDatum() {
|
||||
this.formDatum.push($A.cloneJSON(this.nullDatum));
|
||||
},
|
||||
|
||||
delDatum(key) {
|
||||
this.formDatum.splice(key, 1);
|
||||
if (this.formDatum.length === 0) {
|
||||
this.addDatum();
|
||||
}
|
||||
},
|
||||
|
||||
systemSetting(save) {
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'system/column/template?type=' + (save ? 'save' : 'get'),
|
||||
method: 'post',
|
||||
data: {
|
||||
list: this.formDatum
|
||||
},
|
||||
}).then(({data}) => {
|
||||
if (save) {
|
||||
$A.messageSuccess('修改成功');
|
||||
}
|
||||
this.loadIng--;
|
||||
this.$store.state.columnTemplate = $A.cloneJSON(data).map(item => {
|
||||
if ($A.isArray(item.columns)) {
|
||||
item.columns = item.columns.join(",")
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}).catch(({msg}) => {
|
||||
if (save) {
|
||||
$A.modalError(msg);
|
||||
}
|
||||
this.loadIng--;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
29
resources/assets/js/pages/manage/setting/system/index.vue
Normal file
29
resources/assets/js/pages/manage/setting/system/index.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="setting-item submit">
|
||||
<Tabs v-model="tabAction">
|
||||
<TabPane :label="$L('系统设置')" name="setting">
|
||||
<SystemSetting/>
|
||||
</TabPane>
|
||||
<TabPane :label="$L('任务优先级')" name="taskPriority">
|
||||
<SystemTaskPriority/>
|
||||
</TabPane>
|
||||
<TabPane :label="$L('项目模板')" name="columnTemplate">
|
||||
<SystemColumnTemplate/>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SystemSetting from "./setting";
|
||||
import SystemTaskPriority from "./taskPriority";
|
||||
import SystemColumnTemplate from "./columnTemplate";
|
||||
export default {
|
||||
components: {SystemColumnTemplate, SystemTaskPriority, SystemSetting},
|
||||
data() {
|
||||
return {
|
||||
tabAction: 'setting',
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="setting-item submit">
|
||||
<div class="setting-system-item">
|
||||
<Form ref="formDatum" :model="formDatum" label-width="auto" @submit.native.prevent>
|
||||
<FormItem :label="$L('允许注册')" prop="reg">
|
||||
<RadioGroup v-model="formDatum.reg">
|
||||
@ -69,6 +69,8 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SystemSetting',
|
||||
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="setting-item submit">
|
||||
<div class="setting-system-item">
|
||||
<Form ref="formDatum" label-width="auto" @submit.native.prevent>
|
||||
<Row class="setting-color">
|
||||
<Col span="12">{{$L('名称')}}</Col>
|
||||
@ -47,6 +47,7 @@
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: 'SystemTaskPriority',
|
||||
data() {
|
||||
return {
|
||||
loadIng: 0,
|
||||
@ -66,8 +67,6 @@ export default {
|
||||
this.systemSetting();
|
||||
},
|
||||
|
||||
|
||||
|
||||
computed: {
|
||||
...mapState(['taskPriority']),
|
||||
},
|
@ -4,7 +4,7 @@
|
||||
<Loading v-if="loadIng > 0"/>
|
||||
<template v-else>
|
||||
<AceEditor v-if="isCode" v-model="codeContent" :ext="codeExt" class="view-editor" readOnly/>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" readOnly/>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" :documentKey="documentKey" readOnly/>
|
||||
<iframe v-else-if="isPreview" class="preview-iframe" :src="previewUrl"/>
|
||||
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
|
||||
</template>
|
||||
@ -68,6 +68,10 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
msgId() {
|
||||
return $A.runNum(this.$route.params.id);
|
||||
},
|
||||
|
||||
title() {
|
||||
const {msg} = this.msgDetail;
|
||||
if (msg && msg.name) {
|
||||
@ -99,7 +103,7 @@ export default {
|
||||
return {
|
||||
id: this.isOffice ? this.msgDetail.id : 0,
|
||||
type: this.msgDetail.msg.ext,
|
||||
name: this.title
|
||||
name: this.title,
|
||||
}
|
||||
},
|
||||
officeCode() {
|
||||
@ -121,15 +125,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
let msg_id = $A.runNum(this.$route.params.id);
|
||||
if (msg_id <= 0) {
|
||||
if (this.msgId <= 0) {
|
||||
return;
|
||||
}
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/detail',
|
||||
data: {
|
||||
msg_id,
|
||||
msg_id: this.msgId,
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.loadIng--;
|
||||
@ -145,6 +148,21 @@ export default {
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
documentKey() {
|
||||
return new Promise(resolve => {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'dialog/msg/detail',
|
||||
data: {
|
||||
msg_id: this.msgId,
|
||||
only_update_at: 'yes'
|
||||
},
|
||||
}).then(({data}) => {
|
||||
resolve($A.Date(data.update_at, true))
|
||||
}).catch(() => {
|
||||
resolve(0)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<Loading v-if="loadIng > 0"/>
|
||||
<template v-else>
|
||||
<AceEditor v-if="isCode" v-model="codeContent" :ext="codeExt" class="view-editor" readOnly/>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" readOnly/>
|
||||
<OnlyOffice v-else-if="isOffice" v-model="officeContent" :code="officeCode" :documentKey="documentKey" readOnly/>
|
||||
<iframe v-else-if="isPreview" class="preview-iframe" :src="previewUrl"/>
|
||||
<div v-else class="no-support">{{$L('不支持单独查看此消息')}}</div>
|
||||
</template>
|
||||
@ -68,6 +68,10 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
fileId() {
|
||||
return $A.runNum(this.$route.params.id);
|
||||
},
|
||||
|
||||
title() {
|
||||
const {name} = this.fileDetail;
|
||||
if (name) {
|
||||
@ -99,7 +103,7 @@ export default {
|
||||
return {
|
||||
id: this.isOffice ? this.fileDetail.id : 0,
|
||||
type: this.fileDetail.ext,
|
||||
name: this.title
|
||||
name: this.title,
|
||||
}
|
||||
},
|
||||
officeCode() {
|
||||
@ -121,15 +125,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
let file_id = $A.runNum(this.$route.params.id);
|
||||
if (file_id <= 0) {
|
||||
if (this.fileId <= 0) {
|
||||
return;
|
||||
}
|
||||
this.loadIng++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'project/task/filedetail',
|
||||
data: {
|
||||
file_id,
|
||||
file_id: this.fileId,
|
||||
},
|
||||
}).then(({data}) => {
|
||||
this.loadIng--;
|
||||
@ -145,6 +148,21 @@ export default {
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
documentKey() {
|
||||
return new Promise(resolve => {
|
||||
this.$store.dispatch("call", {
|
||||
url: 'project/task/filedetail',
|
||||
data: {
|
||||
file_id: this.fileId,
|
||||
only_update_at: 'yes'
|
||||
},
|
||||
}).then(({data}) => {
|
||||
resolve($A.Date(data.update_at, true))
|
||||
}).catch(() => {
|
||||
resolve(0)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
resources/assets/js/routes.js
vendored
7
resources/assets/js/routes.js
vendored
@ -49,12 +49,7 @@ export default [
|
||||
{
|
||||
name: 'manage-setting-system',
|
||||
path: 'system',
|
||||
component: () => import('./pages/manage/setting/system.vue'),
|
||||
},
|
||||
{
|
||||
name: 'manage-setting-priority',
|
||||
path: 'priority',
|
||||
component: () => import('./pages/manage/setting/priority.vue'),
|
||||
component: () => import('./pages/manage/setting/system/index.vue'),
|
||||
},
|
||||
]
|
||||
},
|
||||
|
36
resources/assets/js/store/actions.js
vendored
36
resources/assets/js/store/actions.js
vendored
@ -367,10 +367,14 @@ export default {
|
||||
* 登出(打开登录页面)
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param appendFrom
|
||||
*/
|
||||
logout({state, dispatch}) {
|
||||
logout({state, dispatch}, appendFrom = true) {
|
||||
dispatch("handleClearCache", {}).then(() => {
|
||||
const from = ["/", "/login"].includes(window.location.pathname) ? "" : encodeURIComponent(window.location.href);
|
||||
let from = ["/", "/login"].includes(window.location.pathname) ? "" : encodeURIComponent(window.location.href);
|
||||
if (appendFrom === false) {
|
||||
from = null;
|
||||
}
|
||||
$A.goForward({name: 'login', query: from ? {from: from} : {}}, true);
|
||||
});
|
||||
},
|
||||
@ -427,11 +431,12 @@ export default {
|
||||
dispatch("saveFile", file);
|
||||
});
|
||||
} else if ($A.isJson(data)) {
|
||||
let base = {_load: false, _edit: false};
|
||||
let index = state.files.findIndex(({id}) => id == data.id);
|
||||
if (index > -1) {
|
||||
state.files.splice(index, 1, Object.assign({}, state.files[index], data));
|
||||
state.files.splice(index, 1, Object.assign(base, state.files[index], data));
|
||||
} else {
|
||||
state.files.push(data)
|
||||
state.files.push(Object.assign(base, data))
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1623,6 +1628,26 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取添加项目列表预设数据
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
getColumnTemplate({state, dispatch}) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
dispatch("call", {
|
||||
url: 'system/column/template',
|
||||
}).then(result => {
|
||||
state.columnTemplate = result.data;
|
||||
resolve(result)
|
||||
}).catch(e => {
|
||||
console.warn(e);
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存完成任务临时表
|
||||
* @param state
|
||||
@ -2082,8 +2107,9 @@ export default {
|
||||
}
|
||||
let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id);
|
||||
// 更新对话列表
|
||||
if (dialog) {
|
||||
if (dialog && state.cacheUnreads[data.id] === undefined) {
|
||||
// 新增未读数
|
||||
state.cacheUnreads[data.id] = true;
|
||||
dialog.unread++;
|
||||
}
|
||||
Store.set('dialogMsgPush', data);
|
||||
|
7
resources/assets/js/store/state.js
vendored
7
resources/assets/js/store/state.js
vendored
@ -1,4 +1,7 @@
|
||||
const stateData = {
|
||||
// 是否桌面端
|
||||
isDesktop: $A.isDesktop(),
|
||||
|
||||
// 浏览器宽度
|
||||
windowWidth: window.innerWidth,
|
||||
|
||||
@ -19,6 +22,7 @@ const stateData = {
|
||||
|
||||
// Dialog
|
||||
cacheDialogs: $A.getStorageArray("cacheDialogs"),
|
||||
cacheUnreads: {},
|
||||
|
||||
// Project
|
||||
cacheProjects: $A.getStorageArray("cacheProjects"),
|
||||
@ -78,6 +82,9 @@ const stateData = {
|
||||
// 任务优先级
|
||||
taskPriority: [],
|
||||
|
||||
// 项目创建列表模板
|
||||
columnTemplate: [],
|
||||
|
||||
// 列表背景色
|
||||
columnColorList: [
|
||||
{name: '默认', color: ''},
|
||||
|
@ -35,6 +35,11 @@
|
||||
align-items: center;
|
||||
margin-top: 14px;
|
||||
overflow: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> li {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
|
@ -333,6 +333,7 @@
|
||||
display: inline-block;
|
||||
margin-right: 3px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
&.start {
|
||||
background-color: rgba(38, 38, 38, 0.05);
|
||||
border-color: rgba(38, 38, 38, 0.05);
|
||||
@ -762,6 +763,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-user-popper {
|
||||
.ivu-poptip-body-content {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.task-detail-avatar-buttons {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 4px;
|
||||
|
44
resources/assets/sass/pages/page-setting.scss
vendored
44
resources/assets/sass/pages/page-setting.scss
vendored
@ -113,7 +113,8 @@
|
||||
.ivu-form {
|
||||
overflow: auto;
|
||||
}
|
||||
.setting-color {
|
||||
.setting-color,
|
||||
.setting-template {
|
||||
min-width: 400px;
|
||||
max-width: 600px;
|
||||
margin-bottom: 12px;
|
||||
@ -128,7 +129,6 @@
|
||||
width: 60px;
|
||||
flex: auto;
|
||||
flex-shrink: 0;
|
||||
max-width: 60px;
|
||||
}
|
||||
.ivu-color-picker {
|
||||
width: 100%;
|
||||
@ -138,6 +138,17 @@
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.setting-template {
|
||||
> div {
|
||||
flex-shrink: 0;
|
||||
text-align: left;
|
||||
&:last-child {
|
||||
flex: 1;
|
||||
width: auto;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.setting-footer {
|
||||
> button {
|
||||
height: 34px;
|
||||
@ -166,6 +177,35 @@
|
||||
padding: 24px 40px;
|
||||
overflow: auto;
|
||||
}
|
||||
.ivu-tabs {
|
||||
flex: 1;
|
||||
padding: 16px 32px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.ivu-tabs-content {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
.ivu-tabs-tabpane {
|
||||
position: relative;
|
||||
.setting-system-item {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.ivu-form {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
.setting-footer {
|
||||
margin: 0 -32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.setting-footer {
|
||||
flex-shrink: 0;
|
||||
position: static;
|
||||
|
Loading…
x
Reference in New Issue
Block a user