mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 03:01:12 +00:00
perf: 支持查看任务描述修改历史
This commit is contained in:
parent
bd61b8c948
commit
dbdb805269
@ -32,6 +32,7 @@ use App\Models\ProjectTaskUser;
|
|||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
use App\Exceptions\ApiException;
|
use App\Exceptions\ApiException;
|
||||||
use App\Models\ProjectPermission;
|
use App\Models\ProjectPermission;
|
||||||
|
use App\Models\ProjectTaskContent;
|
||||||
use App\Models\WebSocketDialogMsg;
|
use App\Models\WebSocketDialogMsg;
|
||||||
use App\Module\BillMultipleExport;
|
use App\Module\BillMultipleExport;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@ -1577,6 +1578,7 @@ class ProjectController extends AbstractController
|
|||||||
* @apiName task__content
|
* @apiName task__content
|
||||||
*
|
*
|
||||||
* @apiParam {Number} task_id 任务ID
|
* @apiParam {Number} task_id 任务ID
|
||||||
|
* @apiParam {Number} [history_id] 历史ID(获取历史版本)
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -1587,15 +1589,57 @@ class ProjectController extends AbstractController
|
|||||||
User::auth();
|
User::auth();
|
||||||
//
|
//
|
||||||
$task_id = intval(Request::input('task_id'));
|
$task_id = intval(Request::input('task_id'));
|
||||||
|
$history_id = intval(Request::input('history_id'));
|
||||||
//
|
//
|
||||||
$task = ProjectTask::userTask($task_id, null);
|
$task = ProjectTask::userTask($task_id, null);
|
||||||
//
|
//
|
||||||
|
if ($history_id > 0) {
|
||||||
|
$taskContent = ProjectTaskContent::whereTaskId($task->id)->whereId($history_id)->first();
|
||||||
|
if (empty($taskContent)) {
|
||||||
|
return Base::retError('历史版本不存在');
|
||||||
|
}
|
||||||
|
return Base::retSuccess('success', array_merge($taskContent->getContentInfo(), [
|
||||||
|
'name' => $task->name,
|
||||||
|
]));
|
||||||
|
}
|
||||||
if (empty($task->content)) {
|
if (empty($task->content)) {
|
||||||
return Base::retSuccess('success', json_decode('{}'));
|
return Base::retSuccess('success', json_decode('{}'));
|
||||||
}
|
}
|
||||||
return Base::retSuccess('success', $task->content->getContentInfo());
|
return Base::retSuccess('success', $task->content->getContentInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/project/task/content_history 25. 获取任务详细历史描述
|
||||||
|
*
|
||||||
|
* @apiDescription 需要token身份
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup project
|
||||||
|
* @apiName task__content_history
|
||||||
|
*
|
||||||
|
* @apiParam {Number} task_id 任务ID
|
||||||
|
*
|
||||||
|
* @apiParam {Number} [page] 当前页,默认:1
|
||||||
|
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:100
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function task__content_history()
|
||||||
|
{
|
||||||
|
User::auth();
|
||||||
|
//
|
||||||
|
$task_id = intval(Request::input('task_id'));
|
||||||
|
//
|
||||||
|
$task = ProjectTask::userTask($task_id, null);
|
||||||
|
//
|
||||||
|
$data = ProjectTaskContent::select(['id', 'task_id', 'desc', 'userid', 'created_at'])
|
||||||
|
->whereTaskId($task->id)
|
||||||
|
->orderByDesc('id')
|
||||||
|
->paginate(Base::getPaginate(100, 20));
|
||||||
|
return Base::retSuccess('success', $data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/project/task/files 26. 获取任务文件列表
|
* @api {get} api/project/task/files 26. 获取任务文件列表
|
||||||
*
|
*
|
||||||
|
|||||||
@ -393,7 +393,7 @@ class ProjectTask extends AbstractModel
|
|||||||
$p_color = $data['p_color'];
|
$p_color = $data['p_color'];
|
||||||
$top = intval($data['top']);
|
$top = intval($data['top']);
|
||||||
$userid = User::userid();
|
$userid = User::userid();
|
||||||
$visibility = isset($data['visibility_appoint']) ? $data['visibility_appoint'] : $data['visibility'];
|
$visibility = $data['visibility_appoint'] ?? $data['visibility'];
|
||||||
$visibility_userids = $data['visibility_appointor'] ?: [];
|
$visibility_userids = $data['visibility_appointor'] ?: [];
|
||||||
//
|
//
|
||||||
if (ProjectTask::whereProjectId($project_id)
|
if (ProjectTask::whereProjectId($project_id)
|
||||||
@ -527,6 +527,8 @@ class ProjectTask extends AbstractModel
|
|||||||
ProjectTaskContent::createInstance([
|
ProjectTaskContent::createInstance([
|
||||||
'project_id' => $task->project_id,
|
'project_id' => $task->project_id,
|
||||||
'task_id' => $task->id,
|
'task_id' => $task->id,
|
||||||
|
'userid' => $task->userid,
|
||||||
|
'desc' => $task->desc,
|
||||||
'content' => [
|
'content' => [
|
||||||
'url' => ProjectTaskContent::saveContent($task->id, $content)
|
'url' => ProjectTaskContent::saveContent($task->id, $content)
|
||||||
],
|
],
|
||||||
@ -913,15 +915,25 @@ class ProjectTask extends AbstractModel
|
|||||||
}
|
}
|
||||||
// 内容
|
// 内容
|
||||||
if (Arr::exists($data, 'content')) {
|
if (Arr::exists($data, 'content')) {
|
||||||
|
$logRecord = [];
|
||||||
|
$logContent = ProjectTaskContent::whereTaskId($this->id)->orderByDesc('id')->first();
|
||||||
|
if ($logContent) {
|
||||||
|
$logRecord['link'] = [
|
||||||
|
'title' => '查看历史',
|
||||||
|
'url' => 'single/task/content/' . $this->id . '?history_id=' . $logContent->id,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$this->desc = self::generateDesc($data['content']);
|
||||||
ProjectTaskContent::createInstance([
|
ProjectTaskContent::createInstance([
|
||||||
'project_id' => $this->project_id,
|
'project_id' => $this->project_id,
|
||||||
'task_id' => $this->id,
|
'task_id' => $this->id,
|
||||||
|
'userid' => User::userid(),
|
||||||
|
'desc' => $this->desc,
|
||||||
'content' => [
|
'content' => [
|
||||||
'url' => ProjectTaskContent::saveContent($this->id, $data['content'])
|
'url' => ProjectTaskContent::saveContent($this->id, $data['content'])
|
||||||
],
|
],
|
||||||
])->save();
|
])->save();
|
||||||
$this->desc = self::generateDesc($data['content']);
|
$this->addLog("修改{任务}详细描述", $logRecord);
|
||||||
$this->addLog("修改{任务}详细描述");
|
|
||||||
$updateMarking['is_update_content'] = true;
|
$updateMarking['is_update_content'] = true;
|
||||||
}
|
}
|
||||||
// 优先级
|
// 优先级
|
||||||
|
|||||||
@ -34,7 +34,6 @@ use App\Exceptions\ApiException;
|
|||||||
class ProjectTaskContent extends AbstractModel
|
class ProjectTaskContent extends AbstractModel
|
||||||
{
|
{
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'created_at',
|
|
||||||
'updated_at',
|
'updated_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddProjectTaskContentsUserid extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Schema::table('project_task_contents', function (Blueprint $table) {
|
||||||
|
if (!Schema::hasColumn('project_task_contents', 'userid')) {
|
||||||
|
$table->string('desc', 500)->nullable()->default('')->after('task_id')->comment('内容描述');
|
||||||
|
$table->bigInteger('userid')->nullable()->default(0)->after('task_id')->comment('用户ID');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Schema::table('project_task_contents', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("desc");
|
||||||
|
$table->dropColumn("userid");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -354,6 +354,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.ui.registry.addMenuItem('imagePreview', {
|
editor.ui.registry.addMenuItem('imagePreview', {
|
||||||
|
icon: 'preview',
|
||||||
text: this.$L('预览图片'),
|
text: this.$L('预览图片'),
|
||||||
onAction: () => {
|
onAction: () => {
|
||||||
this.operateImg = null
|
this.operateImg = null
|
||||||
@ -394,6 +395,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.ui.registry.addMenuItem('screenload', {
|
editor.ui.registry.addMenuItem('screenload', {
|
||||||
|
icon: 'fullscreen',
|
||||||
text: this.$L('退出全屏'),
|
text: this.$L('退出全屏'),
|
||||||
onAction: () => {
|
onAction: () => {
|
||||||
this.closeFull();
|
this.closeFull();
|
||||||
@ -418,6 +420,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.ui.registry.addMenuItem('screenload', {
|
editor.ui.registry.addMenuItem('screenload', {
|
||||||
|
icon: 'fullscreen',
|
||||||
text: this.$L('全屏'),
|
text: this.$L('全屏'),
|
||||||
onAction: () => {
|
onAction: () => {
|
||||||
this.onFull();
|
this.onFull();
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
<div :style="{userSelect:operateVisible ? 'none' : 'auto', height: operateStyles.height}"></div>
|
<div :style="{userSelect:operateVisible ? 'none' : 'auto', height: operateStyles.height}"></div>
|
||||||
<DropdownMenu slot="list">
|
<DropdownMenu slot="list">
|
||||||
<DropdownItem @click.native="onEditing">{{ $L('编辑描述') }}</DropdownItem>
|
<DropdownItem @click.native="onEditing">{{ $L('编辑描述') }}</DropdownItem>
|
||||||
|
<DropdownItem @click.native="onHistory">{{ $L('历史记录') }}</DropdownItem>
|
||||||
<DropdownItem v-if="operateLink" @click.native="onLinkPreview">{{ $L('打开链接') }}</DropdownItem>
|
<DropdownItem v-if="operateLink" @click.native="onLinkPreview">{{ $L('打开链接') }}</DropdownItem>
|
||||||
<DropdownItem v-if="operateImg" @click.native="onImagePreview">{{ $L('查看图片') }}</DropdownItem>
|
<DropdownItem v-if="operateImg" @click.native="onImagePreview">{{ $L('查看图片') }}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@ -81,7 +82,7 @@ export default {
|
|||||||
autoresize_bottom_margin: 2,
|
autoresize_bottom_margin: 2,
|
||||||
min_height: 200,
|
min_height: 200,
|
||||||
max_height: 380,
|
max_height: 380,
|
||||||
contextmenu: 'checklist | bold italic underline forecolor backcolor | link | uploadImages imagePreview | screenload',
|
contextmenu: 'checklist | bold italic underline forecolor backcolor | link | uploadImages imagePreview | history screenload',
|
||||||
valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
|
valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
|
||||||
extended_valid_elements: 'a[href|title|target=_blank]',
|
extended_valid_elements: 'a[href|title|target=_blank]',
|
||||||
toolbar: false
|
toolbar: false
|
||||||
@ -89,9 +90,13 @@ export default {
|
|||||||
optionFull: {
|
optionFull: {
|
||||||
menubar: 'file edit view',
|
menubar: 'file edit view',
|
||||||
removed_menuitems: 'preview,print',
|
removed_menuitems: 'preview,print',
|
||||||
|
contextmenu: 'checklist | bold italic underline forecolor backcolor | link | uploadImages imagePreview | screenload',
|
||||||
valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
|
valid_elements: 'a[href|title|target=_blank],em,strong/b,div[align],span[style],a,br,p,img[src|alt|witdh|height],pre[class],code,ol[class],ul[class],li[class]',
|
||||||
extended_valid_elements: 'a[href|title|target=_blank]',
|
extended_valid_elements: 'a[href|title|target=_blank]',
|
||||||
toolbar: 'uploadImages | checklist | bold italic underline | forecolor backcolor'
|
toolbar: 'uploadImages | checklist | bold italic underline | forecolor backcolor',
|
||||||
|
mobile: {
|
||||||
|
menubar: 'file edit view',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
operateStyles: {},
|
operateStyles: {},
|
||||||
@ -147,12 +152,17 @@ export default {
|
|||||||
this.$refs.desc.onFull()
|
this.$refs.desc.onFull()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onHistory() {
|
||||||
|
this.$emit('on-history');
|
||||||
|
},
|
||||||
|
|
||||||
onBlur() {
|
onBlur() {
|
||||||
this.$emit('on-blur');
|
this.$emit('on-blur');
|
||||||
},
|
},
|
||||||
|
|
||||||
onEditorInit(editor) {
|
onEditorInit(editor) {
|
||||||
this.updateTouchContent();
|
this.updateTouchContent();
|
||||||
|
this.updateHistoryContent(editor);
|
||||||
this.$emit('on-editor-init', editor);
|
this.$emit('on-editor-init', editor);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -237,6 +247,16 @@ export default {
|
|||||||
}, timeout)
|
}, timeout)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateHistoryContent(editor) {
|
||||||
|
editor.ui.registry.addMenuItem('history', {
|
||||||
|
icon: 'insert-time',
|
||||||
|
text: this.$L('历史记录'),
|
||||||
|
onAction: () => {
|
||||||
|
this.onHistory();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onLinkPreview() {
|
onLinkPreview() {
|
||||||
if (this.operateLink) {
|
if (this.operateLink) {
|
||||||
window.open(this.operateLink);
|
window.open(this.operateLink);
|
||||||
|
|||||||
@ -180,6 +180,16 @@ export default {
|
|||||||
vNode.push(h('span', {class:'change-value'}, now || '-'))
|
vNode.push(h('span', {class:'change-value'}, now || '-'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($A.isJson(record.link)) {
|
||||||
|
let {title, url} = record.link
|
||||||
|
vNode.push(h('span', ': '))
|
||||||
|
vNode.push(h('a', {
|
||||||
|
attrs: {
|
||||||
|
href: $A.baseUrl(url),
|
||||||
|
target: '_blank'
|
||||||
|
}
|
||||||
|
}, this.$L(title)))
|
||||||
|
}
|
||||||
if (record.userid) {
|
if (record.userid) {
|
||||||
let userids = $A.isArray(record.userid) ? record.userid : [record.userid]
|
let userids = $A.isArray(record.userid) ? record.userid : [record.userid]
|
||||||
let userNode = [];
|
let userNode = [];
|
||||||
|
|||||||
@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div class="task-content-history">
|
||||||
|
<Table
|
||||||
|
:max-height="windowHeight - 180"
|
||||||
|
:columns="columns"
|
||||||
|
:data="list"
|
||||||
|
:loading="loadIng > 0"
|
||||||
|
:no-data-text="$L(noText)"
|
||||||
|
highlight-row
|
||||||
|
stripe/>
|
||||||
|
<Page
|
||||||
|
v-if="total > pageSize"
|
||||||
|
:total="total"
|
||||||
|
:current="page"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:disabled="loadIng > 0"
|
||||||
|
:simple="true"
|
||||||
|
@on-change="setPage"
|
||||||
|
@on-page-size-change="setPageSize"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.task-content-history {
|
||||||
|
.ivu-page {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TaskContentHistory",
|
||||||
|
props: {
|
||||||
|
taskId: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
taskName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loadIng: 0,
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: this.$L('日期'),
|
||||||
|
key: 'created_at',
|
||||||
|
width: 168,
|
||||||
|
}, {
|
||||||
|
title: this.$L('描述'),
|
||||||
|
key: 'desc',
|
||||||
|
ellipsis: true,
|
||||||
|
minWidth: 150,
|
||||||
|
render: (h, {row}) => {
|
||||||
|
return h('span', row.desc || '-');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
title: this.$L('创建人'),
|
||||||
|
width: 120,
|
||||||
|
render: (h, {row}) => {
|
||||||
|
if (!row.userid) {
|
||||||
|
return h('div', '-');
|
||||||
|
}
|
||||||
|
return h('UserAvatar', {
|
||||||
|
props: {
|
||||||
|
showName: true,
|
||||||
|
size: 22,
|
||||||
|
userid: row.userid,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
title: this.$L('操作'),
|
||||||
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
|
render: (h, {index, row, column}) => {
|
||||||
|
if (index === 0 && this.page === 1) {
|
||||||
|
return h('div', '-');
|
||||||
|
}
|
||||||
|
return h('TableAction', {
|
||||||
|
props: {
|
||||||
|
column: column,
|
||||||
|
menu: [
|
||||||
|
{
|
||||||
|
label: this.$L('查看'),
|
||||||
|
action: "preview",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
action: (name) => {
|
||||||
|
this.onAction(name, row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
list: [],
|
||||||
|
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
noText: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
taskId: {
|
||||||
|
handler(val) {
|
||||||
|
if (val) {
|
||||||
|
this.setPage(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getLists() {
|
||||||
|
if (this.taskId === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loadIng++;
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'project/task/content_history',
|
||||||
|
data: {
|
||||||
|
task_id: this.taskId,
|
||||||
|
page: Math.max(this.page, 1),
|
||||||
|
pagesize: Math.max($A.runNum(this.pageSize), 10),
|
||||||
|
},
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.page = data.current_page;
|
||||||
|
this.total = data.total;
|
||||||
|
this.list = data.data;
|
||||||
|
this.noText = '没有相关的数据';
|
||||||
|
}).catch(() => {
|
||||||
|
this.noText = '数据加载失败';
|
||||||
|
}).finally(_ => {
|
||||||
|
this.loadIng--;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
setPage(page) {
|
||||||
|
this.page = page;
|
||||||
|
this.getLists();
|
||||||
|
},
|
||||||
|
|
||||||
|
setPageSize(pageSize) {
|
||||||
|
this.page = 1;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.getLists();
|
||||||
|
},
|
||||||
|
|
||||||
|
onAction(name, row) {
|
||||||
|
switch (name) {
|
||||||
|
case 'preview':
|
||||||
|
const title = (this.taskName || `ID: ${this.taskId}`) + ` [${row.created_at}]`;
|
||||||
|
const path = `/single/task/content/${this.taskId}?history_id=${row.id}&history_title=${title}`;
|
||||||
|
if (this.$isEEUiApp) {
|
||||||
|
this.$store.dispatch('openAppChildPage', {
|
||||||
|
pageType: 'app',
|
||||||
|
pageTitle: title,
|
||||||
|
url: 'web.js',
|
||||||
|
params: {
|
||||||
|
titleFixed: true,
|
||||||
|
allowAccess: true,
|
||||||
|
url: $A.rightDelete(window.location.href, window.location.hash) + `#${path}`
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
window.open($A.apiUrl(`..${path}`))
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -140,6 +140,7 @@
|
|||||||
class="desc"
|
class="desc"
|
||||||
:value="taskContent"
|
:value="taskContent"
|
||||||
:placeholder="$L('详细描述...')"
|
:placeholder="$L('详细描述...')"
|
||||||
|
@on-history="onHistory"
|
||||||
@on-blur="updateBlur('content')"/>
|
@on-blur="updateBlur('content')"/>
|
||||||
<Form class="items" label-position="left" label-width="auto" @submit.native.prevent>
|
<Form class="items" label-position="left" label-width="auto" @submit.native.prevent>
|
||||||
<FormItem v-if="taskDetail.p_name">
|
<FormItem v-if="taskDetail.p_name">
|
||||||
@ -496,6 +497,20 @@
|
|||||||
<Button type="primary" @click="onDelay" :loading="delayTaskLoading">{{$L('确定')}}</Button>
|
<Button type="primary" @click="onDelay" :loading="delayTaskLoading">{{$L('确定')}}</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<!--任务描述历史记录-->
|
||||||
|
<Modal
|
||||||
|
v-model="historyShow"
|
||||||
|
:title="$L('任务描述历史记录')"
|
||||||
|
:mask-closable="false"
|
||||||
|
:styles="{
|
||||||
|
width: '90%',
|
||||||
|
maxWidth: '700px'
|
||||||
|
}">
|
||||||
|
<TaskContentHistory v-if="historyShow" :task-id="taskDetail.id" :task-name="taskDetail.name"/>
|
||||||
|
<div slot="footer">
|
||||||
|
<Button @click="historyShow=false">{{$L('关闭')}}</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -511,10 +526,12 @@ import ChatInput from "./ChatInput";
|
|||||||
import UserSelect from "../../../components/UserSelect.vue";
|
import UserSelect from "../../../components/UserSelect.vue";
|
||||||
import TaskExistTips from "./TaskExistTips.vue";
|
import TaskExistTips from "./TaskExistTips.vue";
|
||||||
import TEditorTask from "../../../components/TEditorTask.vue";
|
import TEditorTask from "../../../components/TEditorTask.vue";
|
||||||
|
import TaskContentHistory from "./TaskContentHistory.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TaskDetail",
|
name: "TaskDetail",
|
||||||
components: {
|
components: {
|
||||||
|
TaskContentHistory,
|
||||||
TEditorTask,
|
TEditorTask,
|
||||||
UserSelect,
|
UserSelect,
|
||||||
TaskExistTips,
|
TaskExistTips,
|
||||||
@ -621,7 +638,9 @@ export default {
|
|||||||
remark: [
|
remark: [
|
||||||
{ required: true, message: this.$L('请输入备注'), trigger: 'blur' },
|
{ required: true, message: this.$L('请输入备注'), trigger: 'blur' },
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
|
|
||||||
|
historyShow: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -993,6 +1012,10 @@ export default {
|
|||||||
return isModify;
|
return isModify;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onHistory() {
|
||||||
|
this.historyShow = true;
|
||||||
|
},
|
||||||
|
|
||||||
updateBlur(action, params) {
|
updateBlur(action, params) {
|
||||||
if (this.canUpdateBlur) {
|
if (this.canUpdateBlur) {
|
||||||
this.updateData(action, params)
|
this.updateData(action, params)
|
||||||
|
|||||||
87
resources/assets/js/pages/single/taskContent.vue
Normal file
87
resources/assets/js/pages/single/taskContent.vue
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-preview">
|
||||||
|
<PageTitle :title="pageName"/>
|
||||||
|
<Loading v-if="loadIng > 0"/>
|
||||||
|
<div v-else-if="info" class="file-preview">
|
||||||
|
<div class="edit-header">
|
||||||
|
<div class="header-title">
|
||||||
|
<div class="title-name">{{pageName}}</div>
|
||||||
|
<Tag color="default">{{$L('只读')}}</Tag>
|
||||||
|
<div class="refresh">
|
||||||
|
<Icon type="ios-refresh" @click="getInfo" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-body">
|
||||||
|
<TEditor :value="info.content" height="100%" readOnly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TEditor from "../../components/TEditor.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {TEditor},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loadIng: 0,
|
||||||
|
info: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
taskId() {
|
||||||
|
return this.$route.params ? $A.runNum(this.$route.params.taskId) : 0;
|
||||||
|
},
|
||||||
|
historyId() {
|
||||||
|
return this.$route.query ? $A.runNum(this.$route.query.history_id) : 0;
|
||||||
|
},
|
||||||
|
pageName() {
|
||||||
|
if (this.$route.query && this.$route.query.history_title) {
|
||||||
|
return this.$route.query.history_title
|
||||||
|
}
|
||||||
|
if (this.info) {
|
||||||
|
return `${this.info.name} [${this.info.created_at}]`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$route': {
|
||||||
|
handler() {
|
||||||
|
this.getInfo();
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
setTimeout(_ => {
|
||||||
|
this.loadIng++;
|
||||||
|
}, 600)
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'project/task/content',
|
||||||
|
data: {
|
||||||
|
task_id: this.taskId,
|
||||||
|
history_id: this.historyId,
|
||||||
|
},
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.info = data;
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError({
|
||||||
|
content: msg,
|
||||||
|
onOk: () => {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).finally(_ => {
|
||||||
|
this.loadIng--;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
11
resources/assets/js/routes.js
vendored
11
resources/assets/js/routes.js
vendored
@ -143,6 +143,11 @@ export default [
|
|||||||
path: '/single/file/:codeOrFileId',
|
path: '/single/file/:codeOrFileId',
|
||||||
component: () => import('./pages/single/file.vue'),
|
component: () => import('./pages/single/file.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'single-task-content',
|
||||||
|
path: '/single/task/content/:taskId',
|
||||||
|
component: () => import('./pages/single/taskContent.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'single-task',
|
name: 'single-task',
|
||||||
path: '/single/task/:taskId',
|
path: '/single/task/:taskId',
|
||||||
@ -154,17 +159,17 @@ export default [
|
|||||||
component: () => import('./pages/single/apps.vue')
|
component: () => import('./pages/single/apps.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'valid-email',
|
name: 'single-valid-email',
|
||||||
path: '/single/valid/email',
|
path: '/single/valid/email',
|
||||||
component: () => import('./pages/single/validEmail.vue')
|
component: () => import('./pages/single/validEmail.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'report-edit',
|
name: 'single-report-edit',
|
||||||
path: '/single/report/edit/:reportEditId',
|
path: '/single/report/edit/:reportEditId',
|
||||||
component: () => import('./pages/single/reportEdit.vue')
|
component: () => import('./pages/single/reportEdit.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'report-detail',
|
name: 'single-report-detail',
|
||||||
path: '/single/report/detail/:reportDetailId',
|
path: '/single/report/detail/:reportDetailId',
|
||||||
component: () => import('./pages/single/reportDetail.vue')
|
component: () => import('./pages/single/reportDetail.vue')
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user