no message

This commit is contained in:
kuaifan 2021-06-24 01:10:49 +08:00
parent f5c3604397
commit 7e1e311e68
11 changed files with 135 additions and 58 deletions

View File

@ -724,7 +724,6 @@ class ProjectController extends AbstractController
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(), 'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(),
]; ];
$task->pushMsg('add', $data); $task->pushMsg('add', $data);
$data['task']['owner'] = 1;
return Base::retSuccess('添加成功', $data); return Base::retSuccess('添加成功', $data);
} }
@ -754,7 +753,6 @@ class ProjectController extends AbstractController
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(), 'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(),
]; ];
$task->pushMsg('add', $data); $task->pushMsg('add', $data);
$data['task']['owner'] = 1;
return Base::retSuccess('添加成功', $data); return Base::retSuccess('添加成功', $data);
} }
@ -764,7 +762,7 @@ class ProjectController extends AbstractController
* @apiParam {Number} task_id 任务ID * @apiParam {Number} task_id 任务ID
* @apiParam {String} [name] 任务描述 * @apiParam {String} [name] 任务描述
* @apiParam {Array} [times] 计划时间(格式:开始时间,结束时间2020-01-01 00:00,2020-01-01 23:59 * @apiParam {Array} [times] 计划时间(格式:开始时间,结束时间2020-01-01 00:00,2020-01-01 23:59
* @apiParam {Number} [owner] 修改负责人 * @apiParam {Array} [owner] 修改负责人
* @apiParam {String} [content] 任务详情(子任务不支持) * @apiParam {String} [content] 任务详情(子任务不支持)
* @apiParam {String} [color] 背景色(子任务不支持) * @apiParam {String} [color] 背景色(子任务不支持)
* @apiParam {Array} [assist] 修改协助人员(子任务不支持) * @apiParam {Array} [assist] 修改协助人员(子任务不支持)

View File

@ -327,10 +327,16 @@ class ProjectTask extends AbstractModel
} }
} }
// 负责人 // 负责人
$owner = intval($owner) ?: User::userid(); $owner = is_array($owner) ? $owner : [$owner];
if (!ProjectUser::whereProjectId($project_id)->whereUserid($owner)->exists()) { $tmpArray = [];
throw new ApiException($retPre . '负责人填写错误'); foreach ($owner as $uid) {
if (intval($uid) == 0) continue;
if (!ProjectUser::whereProjectId($project_id)->whereUserid($uid)->exists()) {
throw new ApiException($retPre . '负责人填写错误');
}
$tmpArray[] = $uid;
} }
$owner = $tmpArray;
// 创建人 // 创建人
$task->userid = User::userid(); $task->userid = User::userid();
// 排序位置 // 排序位置
@ -342,12 +348,12 @@ class ProjectTask extends AbstractModel
// //
return AbstractModel::transaction(function() use ($subtasks, $content, $owner, $task) { return AbstractModel::transaction(function() use ($subtasks, $content, $owner, $task) {
$task->save(); $task->save();
if ($owner) { foreach ($owner as $uid) {
ProjectTaskUser::createInstance([ ProjectTaskUser::createInstance([
'project_id' => $task->project_id, 'project_id' => $task->project_id,
'task_id' => $task->id, 'task_id' => $task->id,
'task_pid' => $task->parent_id ?: $task->id, 'task_pid' => $task->parent_id ?: $task->id,
'userid' => $owner, 'userid' => $uid,
'owner' => 1, 'owner' => 1,
])->save(); ])->save();
} }
@ -392,27 +398,37 @@ class ProjectTask extends AbstractModel
} }
// 负责人 // 负责人
if (Arr::exists($data, 'owner')) { if (Arr::exists($data, 'owner')) {
$owner = intval($data['owner']); $count = $this->task_user_count;
$row = ProjectTaskUser::whereTaskId($this->id)->whereUserid($owner)->first(); $array = [];
if (empty($row)) { $owner = is_array($data['owner']) ? $data['owner'] : [$data['owner']];
$row = ProjectTaskUser::createInstance([ foreach ($owner as $uid) {
'project_id' => $this->project_id, if (intval($uid) == 0) continue;
if (!$this->project->useridInTheProject($uid)) continue;
//
ProjectTaskUser::updateInsert([
'task_id' => $this->id, 'task_id' => $this->id,
'userid' => $uid,
], [
'project_id' => $this->project_id,
'task_pid' => $this->parent_id ?: $this->id, 'task_pid' => $this->parent_id ?: $this->id,
'userid' => $owner,
'owner' => 1, 'owner' => 1,
]); ]);
} else { $array[] = $uid;
$row->owner = 1; if ($this->parent_id) {
} break; // 子任务只能是一个负责人
$row->save(); }
if ($this->parent_id) {
ProjectTaskUser::whereTaskId($this->id)->where('id', '!=', $row->id)->delete();
} else {
ProjectTaskUser::whereTaskId($this->id)->where('id', '!=', $row->id)->update([ 'owner' => 0 ]);
} }
ProjectTaskUser::whereTaskId($this->id)->whereOwner(1)->whereNotIn('userid', $array)->delete();
$this->syncDialogUser(); $this->syncDialogUser();
$this->addLog("修改{任务}负责人为会员ID" . $row->userid); if (count($array) == 0) {
$this->addLog("删除{任务}负责人");
} else {
if ($count == 0) {
$this->addLog("认领{任务}");
} else {
$this->addLog("修改{任务}负责人");
}
}
} }
// 计划时间 // 计划时间
if (Arr::exists($data, 'times')) { if (Arr::exists($data, 'times')) {
@ -436,25 +452,29 @@ class ProjectTask extends AbstractModel
$assist = is_array($data['assist']) ? $data['assist'] : [$data['assist']]; $assist = is_array($data['assist']) ? $data['assist'] : [$data['assist']];
foreach ($assist as $uid) { foreach ($assist as $uid) {
if (intval($uid) == 0) continue; if (intval($uid) == 0) continue;
if (!$this->project->useridInTheProject($uid)) continue;
// //
if (empty($this->useridInTheTask($uid))) { ProjectTaskUser::updateInsert([
ProjectTaskUser::createInstance([ 'task_id' => $this->id,
'project_id' => $this->project_id, 'userid' => $uid,
'task_id' => $this->id, ], [
'task_pid' => $this->parent_id ?: $this->id, 'project_id' => $this->project_id,
'userid' => $uid, 'task_pid' => $this->parent_id ?: $this->id,
'owner' => 0, 'owner' => 0,
])->save(); ]);
}
$array[] = $uid; $array[] = $uid;
} }
ProjectTaskUser::whereTaskId($this->id)->where('owner', '!=', 1)->whereNotIn('userid', $array)->delete(); ProjectTaskUser::whereTaskId($this->id)->whereOwner(0)->whereNotIn('userid', $array)->delete();
$this->syncDialogUser(); $this->syncDialogUser();
$this->addLog("修改协助人员"); if (count($array) == 0) {
$this->addLog("删除{任务}协助人员");
} else {
$this->addLog("修改{任务}协助人员");
}
} }
// 背景色 // 背景色
if (Arr::exists($data, 'color') && $this->color != $data['color']) { if (Arr::exists($data, 'color') && $this->color != $data['color']) {
$this->addLog("修改任务背景色:{$this->color} => {$data['color']}"); $this->addLog("修改{任务}背景色:{$this->color} => {$data['color']}");
$this->color = $data['color']; $this->color = $data['color'];
} }
// 内容 // 内容
@ -466,7 +486,7 @@ class ProjectTask extends AbstractModel
'content' => $data['content'], 'content' => $data['content'],
]); ]);
$this->desc = Base::getHtml($data['content']); $this->desc = Base::getHtml($data['content']);
$this->addLog("修改任务详细描述"); $this->addLog("修改{任务}详细描述");
$updateContent = true; $updateContent = true;
} }
// 优先级 // 优先级
@ -484,7 +504,7 @@ class ProjectTask extends AbstractModel
$p = true; $p = true;
} }
if ($p) { if ($p) {
$this->addLog("修改任务优先级"); $this->addLog("修改{任务}优先级");
} }
} }
$this->save(); $this->save();

View File

@ -175,9 +175,12 @@
</div> </div>
<div class="task-users"> <div class="task-users">
<ul> <ul>
<li v-for="(user, keyu) in item.task_user" :key="keyu"> <li v-for="(user, keyu) in ownerUser(item.task_user)" :key="keyu">
<UserAvatar :userid="user.userid" size="32" :borderWitdh="2" :borderColor="item.color"/> <UserAvatar :userid="user.userid" size="32" :borderWitdh="2" :borderColor="item.color"/>
</li> </li>
<li v-if="ownerUser(item.task_user).length === 0" class="no-owner">
<Button type="primary" size="small">{{$L('领取任务')}}</Button>
</li>
</ul> </ul>
<div v-if="item.file_num > 0" class="task-icon">{{item.file_num}}<Icon type="ios-link-outline" /></div> <div v-if="item.file_num > 0" class="task-icon">{{item.file_num}}<Icon type="ios-link-outline" /></div>
<div v-if="item.msg_num > 0" class="task-icon">{{item.msg_num}}<Icon type="ios-chatbubbles-outline" /></div> <div v-if="item.msg_num > 0" class="task-icon">{{item.msg_num}}<Icon type="ios-chatbubbles-outline" /></div>
@ -986,6 +989,12 @@ export default {
return false; return false;
}, },
ownerUser(list) {
return list.filter(({owner}) => owner == 1).sort((a, b) => {
return a.id - b.id;
});
},
formatTime(date) { formatTime(date) {
let time = Math.round(new Date(date).getTime() / 1000), let time = Math.round(new Date(date).getTime() / 1000),
string = ''; string = '';

View File

@ -63,7 +63,11 @@
@on-change="taskTimeChange(addData.times)"/> @on-change="taskTimeChange(addData.times)"/>
</FormItem> </FormItem>
<FormItem :label="$L('任务负责人')"> <FormItem :label="$L('任务负责人')">
<UserInput v-model="addData.owner" :multiple-max="1" :placeholder="$L('选择任务负责人')"/> <UserInput
v-model="addData.owner"
:multiple-max="10"
:placeholder="$L('选择任务负责人')"
:project-id="projectId"/>
</FormItem> </FormItem>
<div class="subtasks"> <div class="subtasks">
<div v-if="addData.subtasks.length > 0" class="sublist"> <div v-if="addData.subtasks.length > 0" class="sublist">
@ -94,7 +98,8 @@
<UserInput <UserInput
v-model="item.owner" v-model="item.owner"
:multiple-max="1" :multiple-max="1"
:placeholder="$L('选择负责人')"/> :placeholder="$L('选择负责人')"
:project-id="projectId"/>
</Col> </Col>
</Row> </Row>
</div> </div>

View File

@ -83,7 +83,9 @@
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button> <Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
</div> </div>
</div> </div>
<UserAvatar v-if="getOwner" :userid="getOwner.userid" :size="20"/> <template v-if="getOwner.length > 0">
<UserAvatar v-for="item in getOwner" :key="item.userid" :userid="item.userid" :size="20" tooltip-disabled/>
</template>
<div v-else>--</div> <div v-else>--</div>
</Poptip> </Poptip>
</li> </li>
@ -98,6 +100,17 @@
<p v-if="columnName">{{columnName}}</p> <p v-if="columnName">{{columnName}}</p>
<p v-if="taskDetail.id">{{taskDetail.id}}</p> <p v-if="taskDetail.id">{{taskDetail.id}}</p>
</div> </div>
<Poptip
v-if="getOwner.length === 0"
confirm
ref="owner"
class="pick"
:title="$L('你确认领取任务吗?')"
placement="bottom"
@on-ok="onOwner(true)"
transfer>
<Button type="primary">{{$L('我要领取任务')}}</Button>
</Poptip>
<EDropdown <EDropdown
trigger="click" trigger="click"
placement="bottom" placement="bottom"
@ -175,7 +188,7 @@
</li> </li>
</ul> </ul>
</FormItem> </FormItem>
<FormItem> <FormItem v-if="getOwner.length > 0">
<div class="item-label" slot="label"> <div class="item-label" slot="label">
<i class="iconfont">&#xe6e4;</i>{{$L('负责人')}} <i class="iconfont">&#xe6e4;</i>{{$L('负责人')}}
</div> </div>
@ -193,17 +206,16 @@
<UserInput <UserInput
v-if="ownerShow" v-if="ownerShow"
v-model="ownerData.owner_userid" v-model="ownerData.owner_userid"
:multiple-max="1" :multiple-max="10"
:project-id="taskDetail.project_id" :project-id="taskDetail.project_id"
:placeholder="$L('选择任务负责人')"/> :placeholder="$L('选择任务负责人')"/>
<div class="task-detail-avatar-buttons"> <div class="task-detail-avatar-buttons">
<Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button> <Button size="small" type="primary" @click="$refs.owner.ok()">{{$L('确定')}}</Button>
</div> </div>
</div> </div>
<div v-if="getOwner" class="user-list"> <div class="user-list">
<UserAvatar :userid="getOwner.userid" :size="28"/> <UserAvatar v-for="item in getOwner" :key="item.userid" :userid="item.userid" :size="28" tooltip-disabled/>
</div> </div>
<div v-else>--</div>
</Poptip> </Poptip>
</FormItem> </FormItem>
<FormItem v-if="getAssist.length > 0 || assistForce"> <FormItem v-if="getAssist.length > 0 || assistForce">
@ -584,9 +596,11 @@ export default {
getOwner() { getOwner() {
const {taskDetail} = this; const {taskDetail} = this;
if (!$A.isArray(taskDetail.task_user)) { if (!$A.isArray(taskDetail.task_user)) {
return null; return [];
} }
return taskDetail.task_user.find(({owner}) => owner === 1); return taskDetail.task_user.filter(({owner}) => owner === 1).sort((a, b) => {
return a.id - b.id;
});
}, },
getAssist() { getAssist() {
@ -594,7 +608,9 @@ export default {
if (!$A.isArray(taskDetail.task_user)) { if (!$A.isArray(taskDetail.task_user)) {
return []; return [];
} }
return taskDetail.task_user.filter(({owner}) => owner !== 1); return taskDetail.task_user.filter(({owner}) => owner !== 1).sort((a, b) => {
return a.id - b.id;
});
}, },
menuList() { menuList() {
@ -856,19 +872,25 @@ export default {
}, },
openOwner() { openOwner() {
this.$set(this.taskDetail, 'owner_userid', [this.getOwner.userid]) const list = this.getOwner.map(({userid}) => userid)
this.$set(this.ownerData, 'owner_userid', [this.getOwner.userid]); this.$set(this.taskDetail, 'owner_userid', list)
this.$set(this.ownerData, 'owner_userid', list)
this.ownerShow = true; this.ownerShow = true;
}, },
onOwner() { onOwner(pick) {
if (pick === true && this.getOwner.length === 0) {
this.ownerData.owner_userid = [this.userId];
}
if ($A.jsonStringify(this.taskDetail.owner_userid) === $A.jsonStringify(this.ownerData.owner_userid)) { if ($A.jsonStringify(this.taskDetail.owner_userid) === $A.jsonStringify(this.ownerData.owner_userid)) {
return; return;
} }
let owner = this.ownerData.owner_userid;
if ($A.count(owner) == 0) owner = '';
this.ownerLoad++; this.ownerLoad++;
this.$store.dispatch("taskUpdate", { this.$store.dispatch("taskUpdate", {
task_id: this.taskDetail.id, task_id: this.taskDetail.id,
owner: this.ownerData.owner_userid owner: owner,
}).then(({msg}) => { }).then(({msg}) => {
$A.messageSuccess(msg); $A.messageSuccess(msg);
this.ownerLoad--; this.ownerLoad--;
@ -885,7 +907,7 @@ export default {
const list = this.getAssist.map(({userid}) => userid) const list = this.getAssist.map(({userid}) => userid)
this.$set(this.taskDetail, 'assist_userid', list) this.$set(this.taskDetail, 'assist_userid', list)
this.$set(this.assistData, 'assist_userid', list); this.$set(this.assistData, 'assist_userid', list);
this.$set(this.assistData, 'disabled', [this.getOwner.userid]); this.$set(this.assistData, 'disabled', this.getOwner.map(({userid}) => userid))
this.assistShow = true; this.assistShow = true;
}, },

View File

@ -67,9 +67,12 @@
</Col> </Col>
<Col span="3" class="row-user"> <Col span="3" class="row-user">
<ul> <ul>
<li v-for="(user, keyu) in item.task_user" :key="keyu" v-if="keyu < 3"> <li v-for="(user, keyu) in ownerUser(item.task_user)" :key="keyu" v-if="keyu < 3">
<UserAvatar :userid="user.userid" size="32" :borderWitdh="2" :borderColor="item.color"/> <UserAvatar :userid="user.userid" size="32" :borderWitdh="2" :borderColor="item.color"/>
</li> </li>
<li v-if="ownerUser(item.task_user).length === 0" class="no-owner">
<Button type="primary" size="small" @click="openTask(item)">{{$L('领取任务')}}</Button>
</li>
</ul> </ul>
</Col> </Col>
<Col span="3" class="row-time"> <Col span="3" class="row-time">
@ -206,6 +209,12 @@ export default {
} }
}, },
ownerUser(list) {
return list.filter(({owner}) => owner == 1).sort((a, b) => {
return a.id - b.id;
});
},
formatTime(date) { formatTime(date) {
let time = Math.round(new Date(date).getTime() / 1000), let time = Math.round(new Date(date).getTime() / 1000),
string = ''; string = '';

View File

@ -72,7 +72,7 @@ export default {
this.$refs.formDatum.validate((valid) => { this.$refs.formDatum.validate((valid) => {
if (valid) { if (valid) {
let data = $A.cloneJSON(this.formDatum); let data = $A.cloneJSON(this.formDatum);
if ($A.runNum(data.userimg) == 0) data.userimg = ""; if ($A.count(data.userimg) == 0) data.userimg = "";
this.loadIng++; this.loadIng++;
this.$store.dispatch("call", { this.$store.dispatch("call", {
url: 'users/editdata', url: 'users/editdata',

View File

@ -861,7 +861,6 @@ export default {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(state.method.date2string(data)); const post = state.method.cloneJSON(state.method.date2string(data));
if (state.method.isArray(post.column_id)) post.column_id = post.column_id.find((val) => val) if (state.method.isArray(post.column_id)) post.column_id = post.column_id.find((val) => val)
if (state.method.isArray(post.owner)) post.owner = post.owner.find((val) => val)
// //
dispatch("call", { dispatch("call", {
url: 'project/task/add', url: 'project/task/add',
@ -926,7 +925,6 @@ export default {
taskUpdate({state, dispatch}, data) { taskUpdate({state, dispatch}, data) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(state.method.date2string(data)); const post = state.method.cloneJSON(state.method.date2string(data));
if (state.method.isArray(post.owner)) post.owner = post.owner.find((id) => id)
// //
dispatch("call", { dispatch("call", {
url: 'project/task/update', url: 'project/task/update',

View File

@ -1,5 +1,6 @@
.common-user { .common-user {
position: relative; position: relative;
white-space: normal;
.common-user-loading { .common-user-loading {
position: absolute; position: absolute;
top: 2px; top: 2px;

View File

@ -388,6 +388,12 @@
&:first-child { &:first-child {
margin-left: 0; margin-left: 0;
} }
&.no-owner {
width: auto;
.ivu-btn-small {
font-size: 12px;
}
}
} }
} }
.task-icon { .task-icon {
@ -671,6 +677,11 @@
&:first-child { &:first-child {
margin-left: 0; margin-left: 0;
} }
&.no-owner {
height: 32px;
display: flex;
align-items: center;
}
} }
} }
} }

View File

@ -52,6 +52,10 @@
} }
} }
} }
.pick {
margin-left: 16px;
margin-right: -16px;
}
.menu { .menu {
font-size: 22px; font-size: 22px;
margin: 0 32px; margin: 0 32px;