no message

This commit is contained in:
kuaifan 2021-06-07 20:04:46 +08:00
parent e0ea6e8303
commit fd1ce8b257
6 changed files with 316 additions and 109 deletions

View File

@ -208,6 +208,66 @@ class ProjectController extends AbstractController
return Base::retSuccess('修改成功');
}
/**
* 排序任务
*
* @apiParam {Number} project_id 项目ID
* @apiParam {Object} sort 排序数据
* @apiParam {Number} [only_column] 仅更新列表
*/
public function sort()
{
$user = User::authE();
if (Base::isError($user)) {
return $user;
} else {
$user = User::IDE($user['data']);
}
//
$project_id = intval(Request::input('project_id'));
$sort = Base::json2array(Request::input('sort'));
$only_column = intval(Request::input('only_column'));
//
$project = Project::select($this->projectSelect)
->join('project_users', 'projects.id', '=', 'project_users.project_id')
->where('projects.id', $project_id)
->where('project_users.userid', $user->userid)
->first();
if (empty($project)) {
return Base::retError('项目不存在或不在成员列表内');
}
//
if ($only_column) {
// 排序列表
$index = 0;
foreach ($sort as $item) {
if (!is_array($item)) continue;
if (!intval($item['id'])) continue;
if (!is_array($item['task'])) continue;
ProjectColumn::whereId($item['id'])->whereProjectId($project->id)->update([
'sort' => $index
]);
$index++;
}
} else {
// 排序任务
foreach ($sort as $item) {
if (!is_array($item)) continue;
if (!intval($item['id'])) continue;
if (!is_array($item['task'])) continue;
$index = 0;
foreach ($item['task'] as $task_id) {
ProjectTask::whereId($task_id)->whereProjectId($project->id)->update([
'column_id' => $item['id'],
'sort' => $index
]);
$index++;
}
}
}
return Base::retSuccess('调整成功');
}
/**
* 修改项目成员
*
@ -505,7 +565,10 @@ class ProjectController extends AbstractController
]);
$column->sort = intval(ProjectColumn::whereProjectId($project->id)->orderByDesc('sort')->value('sort')) + 1;
$column->save();
return Base::retSuccess('添加成功', $column);
//
$data = $column->toArray();
$data['project_task'] = [];
return Base::retSuccess('添加成功', $data);
}
}
@ -608,7 +671,7 @@ class ProjectController extends AbstractController
return Base::retError('任务列表不存在或已被删除');
}
//
return ProjectTask::addTask([
$result = ProjectTask::addTask([
'parent_id' => 0,
'project_id' => $project->id,
'column_id' => $column->id,
@ -622,5 +685,9 @@ class ProjectController extends AbstractController
'p_color' => $p_color,
'top' => $top,
]);
if (Base::isSuccess($result)) {
$result['data'] = ProjectTask::with(['taskUser', 'taskTag'])->whereId($result['data']['id'])->first();
}
return $result;
}
}

View File

@ -298,13 +298,15 @@ class ProjectTask extends AbstractModel
$subtask['p_level'] = $task->p_level;
$subtask['p_name'] = $task->p_name;
$subtask['p_color'] = $task->p_color;
$res = self::addTask($subtask);
if (Base::isError($res)) {
return $res;
$result = self::addTask($subtask);
if (Base::isError($result)) {
return $result;
}
}
}
return Base::retSuccess('添加成功');
return Base::retSuccess('添加成功', [
'id' => $task->id
]);
});
}
}

View File

@ -184,6 +184,7 @@
return;
}
if (typeof config === "string") config = {title:config};
let inputId = "modalInput_" + $A.randomString(6);
$A.Modal.confirm({
render: (h) => {
return h('div', [
@ -197,7 +198,8 @@
h('Input', {
props: {
value: config.value,
placeholder: $A.L(config.placeholder)
placeholder: $A.L(config.placeholder),
elementId: inputId,
},
on: {
input: (val) => {
@ -220,6 +222,9 @@
}
},
});
setTimeout(() => {
document.getElementById(inputId) && document.getElementById(inputId).focus();
});
},
modalConfirm(config, millisecond = 0) {

View File

@ -13,7 +13,7 @@
<li>
<UserAvatar :userid="projectDetail.owner_userid" :size="36"/>
</li>
<li class="project-icon" @click="addOpen(0)">
<li class="project-icon" @click="addTaskOpen(0)">
<Icon type="md-add" />
</li>
<li class="project-icon">
@ -53,8 +53,15 @@
</div>
</div>
<div v-if="projectListPanel" class="project-column">
<ul>
<li v-for="column in projectDetail.project_column">
<Draggable
:list="projectDetail.project_column"
:animation="150"
:disabled="sortDisabled"
class="column-list"
tag="ul"
draggable=".column-item"
@sort="sortUpdate(true)">
<li v-for="column in projectDetail.project_column" class="column-item">
<div
:class="['column-head', column.color ? 'custom-color' : '']"
:style="column.color ? {backgroundColor: column.color}:null">
@ -77,20 +84,30 @@
</ul>
</div>
</Poptip>
<Icon type="md-add" @click="addTop(column)" />
<Icon type="md-add" @click="addTopShow(column)" />
</div>
</div>
<ul class="overlay-y" :ref="'column_' + column.id">
<li v-if="column.addTop===true" class="task-add">
<div :ref="'column_' + column.id" class="column-task overlay-y">
<div v-if="column.addTopShow===true" class="task-item">
<TaskAddSimple
:column-id="column.id"
:project-id="projectDetail.id"
:add-top="true"
@on-close="column.addTop=false"
@on-priority="addOpen"
@on-close="column.addTopShow=false"
@on-priority="addTaskOpen"
@on-success="addTaskSuccess"
auto-active/>
</li>
<li v-for="item in panelTask(column.project_task)">
</div>
<Draggable
:list="column.project_task"
:animation="150"
:disabled="sortDisabled"
class="task-list"
draggable=".task-draggable"
group="task"
@sort="sortUpdate"
@remove="sortUpdate">
<div v-for="item in panelTask(column.project_task)" class="task-item task-draggable">
<div :class="['task-head', item.desc ? 'has-desc' : '']">
<div class="task-title"><pre>{{item.name}}</pre></div>
<Icon type="ios-more" />
@ -120,17 +137,33 @@
</Tooltip>
</div>
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
</li>
<li class="task-add">
</div>
<div class="task-item">
<TaskAddSimple
:column-id="column.id"
:project-id="projectDetail.id"
@on-priority="addOpen"/>
@on-priority="addTaskOpen"
@on-success="addTaskSuccess"/>
</div>
</Draggable>
</div>
</li>
</ul>
<li :class="['add-column', addColumnShow ? 'show-input' : '']">
<div class="add-column-text" @click="addColumnOpen">
<Icon type="md-add" />{{$L('添加列表')}}
</div>
<div class="add-column-input">
<Input
ref="addColumnName"
v-model="addColumnName"
@on-blur="addColumnShow=false"
@on-clear="addColumnShow=false"
@on-enter="addColumnSubmit"
:placeholder="$L('列表名称,回车创建')"
clearable/>
</div>
</li>
<li class="add-column" @click="addColumn"><Icon type="md-add" />{{$L('添加列表')}}</li>
</ul>
</Draggable>
</div>
<div v-else class="project-table">
<div class="project-table-head">
@ -188,7 +221,7 @@
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
</Row>
</div>
<div @click="addOpen(0)">
<div @click="addTaskOpen(0)">
<Row class="project-row">
<Col span="12" class="row-add">
<Icon type="ios-add" /> {{$L('添加任务')}}
@ -370,6 +403,7 @@
</template>
<script>
import Draggable from 'vuedraggable'
import TaskPriority from "./TaskPriority";
import TaskAdd from "./TaskAdd";
import {mapState} from "vuex";
@ -377,7 +411,7 @@ import UserInput from "../../../components/UserInput";
import TaskAddSimple from "./TaskAddSimple";
export default {
name: "ProjectList",
components: {TaskAddSimple, UserInput, TaskAdd, TaskPriority},
components: {Draggable, TaskAddSimple, UserInput, TaskAdd, TaskPriority},
data() {
return {
nowTime: Math.round(new Date().getTime() / 1000),
@ -397,6 +431,12 @@ export default {
},
taskLoad: 0,
addColumnShow: false,
addColumnName: '',
sortData: [],
sortDisabled: false,
settingShow: false,
settingData: {},
settingLoad: 0,
@ -538,8 +578,94 @@ export default {
},
},
watch: {
projectDetail() {
this.sortData = this.getSort();
}
},
methods: {
addOpen(column_id) {
getSort() {
const sortData = [];
this.projectDetail.project_column.forEach((column) => {
sortData.push({
id: column.id,
task: column.project_task.map(({id}) => id)
});
});
return sortData;
},
sortUpdate(only_column) {
const oldSort = this.sortData;
const newSort = this.getSort();
if (JSON.stringify(oldSort) === JSON.stringify(newSort)) {
return;
}
this.sortData = newSort;
//
this.sortDisabled = true;
$A.apiAjax({
url: 'project/sort',
data: {
project_id: this.projectDetail.id,
sort: this.sortData,
only_column: only_column === true ? 1 : 0
},
complete: () => {
this.sortDisabled = false;
},
error: () => {
$A.modalAlert('网络繁忙,请稍后再试!');
this.$store.commit('getProjectDetail', this.projectDetail.id);
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
} else {
$A.modalError(msg);
this.$store.commit('getProjectDetail', this.projectDetail.id);
}
}
});
},
onAddTask() {
this.taskLoad++;
$A.apiAjax({
url: 'project/task/add',
data: this.addData,
method: 'post',
complete: () => {
this.taskLoad--;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.addTaskSuccess(data)
this.addShow = false;
this.addData = {
owner: 0,
column_id: 0,
times: [],
subtasks: [],
p_level: 0,
p_name: '',
p_color: '',
};
} else {
$A.modalError(msg);
}
}
});
},
addTopShow(column) {
this.$set(column, 'addTopShow', true);
this.$refs['column_' + column.id][0].scrollTop = 0;
},
addTaskOpen(column_id) {
if ($A.isJson(column_id)) {
this.addData = Object.assign(this.addData, column_id);
} else {
@ -550,25 +676,35 @@ export default {
this.addShow = true;
},
addTop(column) {
this.$set(column, 'addTop', true);
this.$refs['column_' + column.id][0].scrollTop = 0;
addTaskSuccess(data) {
this.projectDetail.project_column.some((item) => {
if (item.id === data.column_id) {
if (data.top) {
item.project_task.unshift(data);
} else {
item.project_task.push(data);
}
}
});
},
addColumn() {
$A.modalInput({
title: "添加列表",
placeholder: "输入列表名称",
onOk: (value, callback) => {
if (!value) return true;
addColumnOpen() {
this.addColumnShow = true;
this.$nextTick(() => {
this.$refs.addColumnName.focus();
})
},
addColumnSubmit() {
let name = this.addColumnName.trim();
if (name === '') {
return;
}
$A.apiAjax({
url: 'project/column/add',
data: {
project_id: this.projectDetail.id,
name: value,
},
complete: () => {
callback();
name: name,
},
error: () => {
$A.modalAlert('网络繁忙,请稍后再试!');
@ -576,14 +712,12 @@ export default {
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.$store.commit('getProjectDetail', this.projectDetail.id);
this.projectDetail.project_column.push(data)
} else {
$A.modalError(msg, 301);
}
}
});
}
})
},
modifyColumn(column) {
@ -650,38 +784,8 @@ export default {
},
success: ({ret, data, msg}) => {
if (ret !== 1) {
this.$set(column, 'name', bakName);
this.$set(column, 'color', bakColor);
}
}
});
},
onAddTask() {
this.taskLoad++;
$A.apiAjax({
url: 'project/task/add',
data: this.addData,
method: 'post',
complete: () => {
this.taskLoad--;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.$store.commit('getProjectDetail', this.addData.project_id);
this.addShow = false;
this.addData = {
owner: 0,
column_id: 0,
times: [],
subtasks: [],
p_level: 0,
p_name: '',
p_color: '',
};
} else {
$A.modalError(msg);
this.$set(column, 'name', data.name);
this.$set(column, 'color', data.color);
}
}
});

View File

@ -161,7 +161,8 @@ export default {
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess(msg);
this.$store.commit('getProjectDetail', this.projectId);
data.top = this.addTop ? 1 : 0;
this.$emit("on-success", data)
this.active = false;
} else {
$A.modalError(msg);

View File

@ -4,7 +4,7 @@
.project-head {
display: flex;
align-items: flex-start;
margin: 32px 32px 18px;
margin: 32px 32px 0;
.project-titbox {
flex: 1;
margin-bottom: 16px;
@ -139,7 +139,9 @@
.project-column {
display: flex;
height: 100%;
padding-top: 18px;
overflow-x: auto;
overflow-y: hidden;
> ul {
display: inline-flex;
justify-content: space-between;
@ -158,22 +160,41 @@
margin-right: 22px;
}
&.add-column {
display: flex;
flex-direction: row;
align-items: center;
height: 36px;
padding: 0 12px;
color: #888888;
cursor: pointer;
background-color: #F2F3F5;
border-radius: 4px;
&:hover {
color: #777777;
}
.add-column-text {
display: flex;
flex-direction: row;
align-items: center;
line-height: 36px;
padding: 0 12px;
> i {
font-size: 16px;
padding-right: 8px;
}
&:hover {
color: #777777;
}
}
.add-column-input {
display: none;
align-items: center;
height: 36px;
.ivu-input {
height: 36px;
}
}
&.show-input {
.add-column-text {
display: none;
}
.add-column-input {
display: flex;
}
}
}
.column-head {
display: flex;
@ -278,18 +299,25 @@
}
}
}
> ul {
.column-task {
flex: 1;
height: 0;
display: flex;
flex-direction: column;
overflow-x: hidden;
overflow-y: auto;
> li {
.task-list {
flex: 1;
height: 0;
display: flex;
flex-direction: column;
}
.task-item {
list-style: none;
margin: 0 10px 16px;
background-color: #ffffff;
border-radius: 12px;
padding: 12px;
transition: all 0.3s;
transition: box-shadow 0.3s;
position: relative;
&:hover {
box-shadow: 0 0 10px #e6ecfa;