no message
This commit is contained in:
parent
9d24f51845
commit
a6bdf9e7ad
144
app/Http/Controllers/Api/ProjectController.php
Executable file
144
app/Http/Controllers/Api/ProjectController.php
Executable file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\AbstractModel;
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectColumn;
|
||||
use App\Models\ProjectLog;
|
||||
use App\Models\ProjectUser;
|
||||
use App\Models\User;
|
||||
use App\Module\Base;
|
||||
use Request;
|
||||
|
||||
/**
|
||||
* @apiDefine project
|
||||
*
|
||||
* 项目
|
||||
*/
|
||||
class ProjectController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* 项目列表
|
||||
*
|
||||
* @apiParam {Number} [page] 当前页,默认:1
|
||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:100,最大:200
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
$user = User::authE();
|
||||
if (Base::isError($user)) {
|
||||
return $user;
|
||||
} else {
|
||||
$user = User::IDE($user['data']);
|
||||
}
|
||||
//
|
||||
$list = Project::join('project_users', 'projects.id', '=', 'project_users.project_id')
|
||||
->where('project_users.userid', $user->userid)
|
||||
->orderByDesc('projects.id')
|
||||
->paginate(Base::getPaginate(200, 100));
|
||||
//
|
||||
return Base::retSuccess('success', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目详情
|
||||
*
|
||||
* @apiParam {Number} project_id 项目ID
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$user = User::authE();
|
||||
if (Base::isError($user)) {
|
||||
return $user;
|
||||
} else {
|
||||
$user = User::IDE($user['data']);
|
||||
}
|
||||
//
|
||||
$project_id = intval(Request::input('project_id'));
|
||||
//
|
||||
$project = Project::with(['projectColumn' => function($query) {
|
||||
$query->with(['projectTask' => function($taskQuery) {
|
||||
$taskQuery->where('parent_id', 0);
|
||||
}]);
|
||||
}, 'projectUser'])
|
||||
->join('project_users', 'projects.id', '=', 'project_users.project_id')
|
||||
->where('projects.id', $project_id)
|
||||
->where('project_users.userid', $user->userid)
|
||||
->first();
|
||||
//
|
||||
return Base::retSuccess('success', $project);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加项目
|
||||
*
|
||||
* @apiParam {String} name 项目名称
|
||||
* @apiParam {String} [desc] 项目描述
|
||||
* @apiParam {Array} [columns] 流程,格式[流程1, 流程2]
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$user = User::authE();
|
||||
if (Base::isError($user)) {
|
||||
return $user;
|
||||
} else {
|
||||
$user = User::IDE($user['data']);
|
||||
}
|
||||
//项目名称
|
||||
$name = trim(Request::input('name', ''));
|
||||
$desc = trim(Request::input('desc', ''));
|
||||
if (mb_strlen($name) < 2) {
|
||||
return Base::retError('项目名称不可以少于2个字!');
|
||||
} elseif (mb_strlen($name) > 32) {
|
||||
return Base::retError('项目名称最多只能设置32个字!');
|
||||
}
|
||||
//流程
|
||||
$columns = Request::input('columns');
|
||||
if (!is_array($columns)) $columns = [];
|
||||
$insertColumns = [];
|
||||
$inorder = 0;
|
||||
foreach ($columns AS $column) {
|
||||
$column = trim($column);
|
||||
if ($column) {
|
||||
$insertColumns[] = [
|
||||
'name' => $column,
|
||||
'inorder' => $inorder++,
|
||||
];
|
||||
}
|
||||
}
|
||||
if (empty($insertColumns)) {
|
||||
$insertColumns[] = [
|
||||
'name' => 'Default',
|
||||
'inorder' => 0,
|
||||
];
|
||||
}
|
||||
if (count($insertColumns) > 30) {
|
||||
return Base::retError('项目流程最多不能超过30个!');
|
||||
}
|
||||
//开始创建
|
||||
$project = Project::createInstance([
|
||||
'name' => $name,
|
||||
'desc' => $desc,
|
||||
'userid' => $user->userid,
|
||||
]);
|
||||
return AbstractModel::transaction(function() use ($user, $insertColumns, $project) {
|
||||
$project->save();
|
||||
ProjectUser::createInstance([
|
||||
'project_id' => $project->id,
|
||||
'userid' => $user->userid,
|
||||
'owner' => 1,
|
||||
])->save();
|
||||
ProjectLog::createInstance([
|
||||
'project_id' => $project->id,
|
||||
'userid' => $user->userid,
|
||||
'detail' => '创建项目',
|
||||
])->save();
|
||||
foreach ($insertColumns AS $column) {
|
||||
$column['project_id'] = $project->id;
|
||||
ProjectColumn::createInstance($column)->save();
|
||||
}
|
||||
return Base::retSuccess('添加成功!');
|
||||
});
|
||||
}
|
||||
}
|
@ -311,7 +311,7 @@ class UsersController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/users/searchinfo 08. 搜索会员列表
|
||||
* @api {get} api/users/search 08. 搜索会员列表
|
||||
*
|
||||
* @apiDescription 搜索会员列表
|
||||
* @apiVersion 1.0.0
|
||||
@ -319,65 +319,29 @@ class UsersController extends AbstractController
|
||||
* @apiName searchinfo
|
||||
*
|
||||
* @apiParam {Object} where 搜索条件
|
||||
* - where.email
|
||||
* - where.noemail
|
||||
* - where.username
|
||||
* - where.nousername
|
||||
* - where.usernameequal
|
||||
* - where.noidentity
|
||||
* - where.identity
|
||||
* - where.key 昵称、邮箱、用户名
|
||||
* @apiParam {Number} [take] 获取数量,10-100
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function searchinfo()
|
||||
public function search()
|
||||
{
|
||||
$builder = User::select(['userid', 'email', 'username', 'nickname', 'userimg']);
|
||||
//
|
||||
$keys = Request::input('where');
|
||||
$whereArr = [];
|
||||
$whereRaw = null;
|
||||
if ($keys['email']) $whereArr[] = ['email', '=', $keys['email']];
|
||||
if ($keys['usernameequal']) $whereArr[] = ['username', '=', $keys['usernameequal']];
|
||||
if ($keys['identity']) $whereArr[] = ['identity', 'like', '%,' . $keys['identity'] . ',%'];
|
||||
if ($keys['noidentity']) $whereArr[] = ['identity', 'not like', '%,' . $keys['noidentity'] . ',%'];
|
||||
if ($keys['username']) {
|
||||
$whereRaw.= $whereRaw ? ' AND ' : '';
|
||||
$whereRaw.= "(`username` LIKE '%" . $keys['username'] . "%' OR `nickname` LIKE '%" . $keys['username'] . "%')";
|
||||
}
|
||||
if ($keys['nousername']) {
|
||||
$nousername = [];
|
||||
foreach (explode(",", $keys['nousername']) AS $name) {
|
||||
$name = trim($name);
|
||||
if ($name && !in_array($name, $nousername)) {
|
||||
$nousername[] = $name;
|
||||
}
|
||||
}
|
||||
if ($nousername) {
|
||||
$whereRaw.= $whereRaw ? ' AND ' : '';
|
||||
$whereRaw.= "(`username` NOT IN ('" . implode("','", $nousername) . "'))";
|
||||
}
|
||||
}
|
||||
if ($keys['noemail']) {
|
||||
$noemail = [];
|
||||
foreach (explode(",", $keys['noemail']) AS $email) {
|
||||
$email = trim($email);
|
||||
if ($email && !in_array($email, $noemail)) {
|
||||
$noemail[] = $email;
|
||||
}
|
||||
}
|
||||
if ($noemail) {
|
||||
$whereRaw.= $whereRaw ? ' AND ' : '';
|
||||
$whereRaw.= "(`email` NOT IN ('" . implode("','", $noemail) . "'))";
|
||||
if (is_array($keys)) {
|
||||
if ($keys['key']) {
|
||||
$builder->where(function($query) use ($keys) {
|
||||
$query->where('email', 'like', '%,' . $keys['key'] . ',%')
|
||||
->orWhere('username', 'like', '%,' . $keys['key'] . ',%')
|
||||
->orWhere('nickname', 'like', '%,' . $keys['key'] . ',%');
|
||||
});
|
||||
}
|
||||
}
|
||||
//
|
||||
$list = User::select(['userid', 'email', 'username', 'nickname', 'userimg'])
|
||||
->where($whereArr)
|
||||
->whereRaw($whereRaw)
|
||||
->orderBy('userid')
|
||||
->take(Base::getPaginate(100, 10, 'take'))
|
||||
->get();
|
||||
$list = $builder->orderBy('userid')->take(Base::getPaginate(100, 10, 'take'))->get();
|
||||
return Base::retSuccess('success', $list);
|
||||
}
|
||||
|
||||
@ -389,7 +353,7 @@ class UsersController extends AbstractController
|
||||
* @apiGroup users
|
||||
* @apiName basic
|
||||
*
|
||||
* @apiParam {String} email 会员用户名(多个格式:jsonArray,一次最多30个)
|
||||
* @apiParam {Number} userid 会员ID(多个格式:jsonArray,一次最多30个)
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
@ -397,17 +361,17 @@ class UsersController extends AbstractController
|
||||
*/
|
||||
public function basic()
|
||||
{
|
||||
$email = trim(Request::input('email'));
|
||||
$array = Base::json2array($email);
|
||||
$userid = Request::input('userid');
|
||||
$array = Base::json2array($userid);
|
||||
if (empty($array)) {
|
||||
$array[] = $email;
|
||||
$array[] = $userid;
|
||||
}
|
||||
if (count($array) > 50) {
|
||||
return Base::retError(['一次最多只能获取%条数据!', 50]);
|
||||
}
|
||||
$retArray = [];
|
||||
foreach ($array AS $name) {
|
||||
$basic = User::email2basic($name);
|
||||
foreach ($array AS $id) {
|
||||
$basic = User::userid2basic($id);
|
||||
if ($basic) {
|
||||
$retArray[] = $basic;
|
||||
}
|
||||
|
66
app/Models/Project.php
Normal file
66
app/Models/Project.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class Project
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property string|null $name 名称
|
||||
* @property string|null $desc 描述、备注
|
||||
* @property int|null $userid 创建人
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
||||
* @property-read int|null $project_column_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
||||
* @property-read int|null $project_log_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
||||
* @property-read int|null $project_user_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|Project onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereDesc($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|Project withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|Project withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Project extends AbstractModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function projectColumn(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(projectColumn::class, 'project_id', 'id')->orderByDesc('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function projectLog(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(projectLog::class, 'project_id', 'id')->orderByDesc('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function projectUser(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(projectUser::class, 'project_id', 'id')->orderByDesc('id');
|
||||
}
|
||||
}
|
37
app/Models/ProjectColumn.php
Normal file
37
app/Models/ProjectColumn.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectColumn
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property string|null $name 列表名称
|
||||
* @property int|null $inorder 排序(ASC)
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTask[] $projectTask
|
||||
* @property-read int|null $project_task_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereInorder($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectColumn extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function projectTask(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(projectTask::class, 'column_id', 'id')->orderByDesc('id');
|
||||
}
|
||||
}
|
31
app/Models/ProjectLog.php
Normal file
31
app/Models/ProjectLog.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectLog
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property int|null $task_id 项目ID
|
||||
* @property int|null $userid 会员ID
|
||||
* @property string|null $detail 详细信息
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereDetail($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereTaskId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUserid($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectLog extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
45
app/Models/ProjectTask.php
Normal file
45
app/Models/ProjectTask.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectTask
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $parent_id 父级任务ID
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property int|null $column_id 列表ID
|
||||
* @property string|null $name 标题
|
||||
* @property string|null $desc 描述
|
||||
* @property string|null $start_at 计划开始时间
|
||||
* @property string|null $end_at 计划结束时间
|
||||
* @property string|null $archived_at 归档时间
|
||||
* @property string|null $complete_at 完成时间
|
||||
* @property int|null $userid 创建人
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereArchivedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereColumnId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCompleteAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDesc($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereEndAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereParentId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereStartAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUserid($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTask extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
29
app/Models/ProjectTaskContent.php
Normal file
29
app/Models/ProjectTaskContent.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectTaskContent
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property int|null $task_id 任务ID
|
||||
* @property string|null $content 内容
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereContent($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereTaskId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskContent whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTaskContent extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
31
app/Models/ProjectTaskUser.php
Normal file
31
app/Models/ProjectTaskUser.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectTaskUser
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property int|null $task_id 任务ID
|
||||
* @property int|null $userid 成员ID
|
||||
* @property int|null $owner 是否任务负责人
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereOwner($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereTaskId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskUser whereUserid($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTaskUser extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
29
app/Models/ProjectUser.php
Normal file
29
app/Models/ProjectUser.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* Class ProjectUser
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $project_id 项目ID
|
||||
* @property int|null $userid 成员ID
|
||||
* @property int|null $owner 是否负责人
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereOwner($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUserid($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectUser extends AbstractModel
|
||||
{
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ namespace App\Models;
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property string|null $title
|
||||
* @property string|null $name
|
||||
* @property string|null $desc 参数描述、备注
|
||||
* @property string|null $setting
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
@ -18,8 +18,8 @@ namespace App\Models;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereDesc($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereSetting($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereTitle($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereUpdatedAt($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@ namespace App\Models;
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property string|null $title
|
||||
* @property string|null $name
|
||||
* @property string|null $value
|
||||
* @property string|null $content
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
@ -18,7 +18,7 @@ namespace App\Models;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereContent($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereTitle($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Tmp whereValue($value)
|
||||
* @mixin \Eloquent
|
||||
|
@ -65,16 +65,6 @@ class User extends AbstractModel
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
public function getUsernameAttribute($value)
|
||||
{
|
||||
return $value ?: $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
* @param $value
|
||||
@ -88,7 +78,7 @@ class User extends AbstractModel
|
||||
if ($this->username) {
|
||||
return $this->username;
|
||||
}
|
||||
return Base::getMiddle($this->email, null, "@");
|
||||
return Base::cardFormat($this->email);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -367,12 +357,13 @@ class User extends AbstractModel
|
||||
* @param int $userid 会员ID
|
||||
* @return self
|
||||
*/
|
||||
public static function userid2basic(int $userid)
|
||||
public static function userid2basic($userid)
|
||||
{
|
||||
global $_A;
|
||||
if (empty($userid)) {
|
||||
return null;
|
||||
}
|
||||
$userid = intval($userid);
|
||||
if (isset($_A["__static_userid2basic_" . $userid])) {
|
||||
return $_A["__static_userid2basic_" . $userid];
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class Base
|
||||
$log = self::array2json($log, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
Tmp::createInstance([
|
||||
'title' => 'log_' . ($title ?: date("Y-m-d H:i:s", time())),
|
||||
'name' => 'log_' . ($title ?: date("Y-m-d H:i:s", time())),
|
||||
'value' => date("Y-m-d H:i:s", time()),
|
||||
'content' => $log,
|
||||
])->save();
|
||||
@ -1139,11 +1139,11 @@ class Base
|
||||
return $_A["__static_setting_" . $setname];
|
||||
}
|
||||
$setting = [];
|
||||
$row = Setting::whereTitle($setname)->first();
|
||||
$row = Setting::whereName($setname)->first();
|
||||
if (!empty($row)) {
|
||||
$setting = Base::string2array($row->setting);
|
||||
} else {
|
||||
$row = Setting::createInstance(['title' => $setname]);
|
||||
$row = Setting::createInstance(['name' => $setname]);
|
||||
$row->save();
|
||||
}
|
||||
if ($array !== false) {
|
||||
@ -2629,19 +2629,19 @@ class Base
|
||||
|
||||
/**
|
||||
* 缓存数据
|
||||
* @param $title
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function cacheData($title, $value = null)
|
||||
public static function cacheData($name, $value = null)
|
||||
{
|
||||
$title = "cacheData::" . $title;
|
||||
$tmp = Tmp::where('title', $title)->select('value')->first();
|
||||
$name = "cacheData::" . $name;
|
||||
$tmp = Tmp::whereName($name)->select('value')->first();
|
||||
if ($value !== null) {
|
||||
if (empty($tmp)) {
|
||||
Tmp::insert(['title' => $title, 'value' => $value]);
|
||||
Tmp::createInstance(['name' => $name, 'value' => $value])->save();
|
||||
} else {
|
||||
Tmp::where('title', $title)->update(['value' => $value]);
|
||||
Tmp::whereName($name)->update(['value' => $value]);
|
||||
}
|
||||
return $value;
|
||||
} else {
|
||||
|
@ -34,7 +34,7 @@
|
||||
"dependencies": {
|
||||
"echarts": "^5.1.1",
|
||||
"tinymce": "^5.8.1",
|
||||
"view-design-hi": "^4.5.0-4",
|
||||
"view-design-hi": "^4.5.0-10",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-emoji-picker": "^1.0.1",
|
||||
"vue-kityminder-gg": "^1.3.6",
|
||||
|
@ -191,7 +191,13 @@
|
||||
type: String,
|
||||
default: ' undo redo | styleselect | uploadImages | uploadFiles | bold italic underline forecolor backcolor | alignleft aligncenter alignright | bullist numlist outdent indent | link image emoticons media codesample | preview screenload',
|
||||
},
|
||||
other_options: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
optionFull: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
@ -262,23 +268,31 @@
|
||||
methods: {
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
tinymce.init(this.concatAssciativeArrays(this.options(false), this.other_options));
|
||||
tinymce.init(this.concatAssciativeArrays(this.option(false), this.options));
|
||||
});
|
||||
},
|
||||
|
||||
initTransfer() {
|
||||
this.$nextTick(() => {
|
||||
tinymce.init(this.concatAssciativeArrays(this.options(true), this.other_options));
|
||||
tinymce.init(this.concatAssciativeArrays(this.option(true), this.optionFull));
|
||||
});
|
||||
},
|
||||
|
||||
options(isFull) {
|
||||
plugin(isFull) {
|
||||
if (isFull) {
|
||||
return this.plugins.filter((val) => val != 'autoresize');
|
||||
} else {
|
||||
return this.plugins;
|
||||
}
|
||||
},
|
||||
|
||||
option(isFull) {
|
||||
return {
|
||||
selector: (isFull ? '#T_' : '#') + this.id,
|
||||
base_url: $A.serverUrl('js/build'),
|
||||
base_url: $A.serverUrl('js/tinymce'),
|
||||
language: "zh_CN",
|
||||
toolbar: this.toolbar,
|
||||
plugins: this.plugins,
|
||||
plugins: this.plugin(isFull),
|
||||
save_onsavecallback: (e) => {
|
||||
this.$emit('editorSave', e);
|
||||
},
|
||||
|
138
resources/assets/js/components/UserInput.vue
Executable file
138
resources/assets/js/components/UserInput.vue
Executable file
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div v-if="ready" class="common-user">
|
||||
<Select
|
||||
v-model="values"
|
||||
:transfer="transfer"
|
||||
:remote-method="searchUser"
|
||||
:placeholder="placeholder"
|
||||
:loading="loading"
|
||||
:loading-text="$L('加载中...')"
|
||||
:default-label="value"
|
||||
:default-event-object="true"
|
||||
:multipleMax="multipleMax"
|
||||
multiple
|
||||
filterable
|
||||
transfer-class-name="common-user-transfer"
|
||||
@on-set-default-options="setDefaultOptions">
|
||||
<div v-if="multipleMax" slot="drop-prepend" class="user-drop-prepend">{{$L('最多只能选择' + multipleMax + '个')}}</div>
|
||||
<Option v-for="(item, key) in lists" :value="item.userid" :key="key" :label="item.nickname" :avatar="item.userimg">
|
||||
<div class="user-input-option">
|
||||
<div class="user-input-avatar"><Avatar :src="item.userimg"/></div>
|
||||
<div class="user-input-nickname">{{ item.nickname }}</div>
|
||||
<div class="user-input-userid">ID: {{ item.userid }}</div>
|
||||
</div>
|
||||
</Option>
|
||||
</Select>
|
||||
<div v-if="!initialized" class="common-user-loading"><Loading/></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UserInput',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Array],
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
default: ''
|
||||
},
|
||||
transfer: {
|
||||
type: Boolean,
|
||||
default () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
multipleMax: {
|
||||
type: Number,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ready: false,
|
||||
initialized: false,
|
||||
loading: false,
|
||||
values: [],
|
||||
lists: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (!$A.isArray(this.value)) {
|
||||
this.$emit('input', [this.value]);
|
||||
} else {
|
||||
this.values = $A.cloneJSON(this.value);
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.ready = true;
|
||||
});
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.values = val;
|
||||
},
|
||||
values(val) {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setDefaultOptions(options) {
|
||||
const userids = [];
|
||||
options.forEach(({value, label}) => {
|
||||
this.lists.push({
|
||||
userid: value,
|
||||
nickname: label,
|
||||
});
|
||||
userids.push(value);
|
||||
});
|
||||
//
|
||||
this.$store.commit('getUserBasic', {
|
||||
userid: userids,
|
||||
complete: () => {
|
||||
this.initialized = true;
|
||||
},
|
||||
success: (user) => {
|
||||
let option = options.find(({value}) => value == user.userid);
|
||||
if (option) {
|
||||
this.$set(option, 'label', user.nickname)
|
||||
this.$set(option, 'avatar', user.userimg)
|
||||
}
|
||||
this.lists.some((item, index) => {
|
||||
if (item.userid == user.userid) {
|
||||
this.$set(this.lists, index, Object.assign(item, user));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
searchUser(query) {
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
$A.apiAjax({
|
||||
url: 'users/search',
|
||||
data: {
|
||||
keys: {
|
||||
key: query
|
||||
},
|
||||
take: 30
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
},
|
||||
success: ({ret, data, msg}) => {
|
||||
if (ret === 1) {
|
||||
this.lists = data;
|
||||
} else {
|
||||
this.lists = [];
|
||||
$A.messageWarning(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.lists = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -21,17 +21,13 @@
|
||||
<li class="menu-project">
|
||||
<ul>
|
||||
<li v-for="(item, key) in projectLists" :key="key" @click="toggleRoute('project/' + item.id)" :class="classNameRoute('project/' + item.id)">{{item.name}}</li>
|
||||
<li @click="toggleRoute('project/1')" :class="classNameRoute('project/1')">✔️ Daily Task</li>
|
||||
<li @click="toggleRoute('project/2')" :class="classNameRoute('project/2')">✈️ Meetings Summary</li>
|
||||
<li @click="toggleRoute('project/3')" :class="classNameRoute('project/3')">🛰 Resources</li>
|
||||
<li @click="toggleRoute('project/4')" :class="classNameRoute('project/4')">💺 Availibity</li>
|
||||
<li @click="toggleRoute('project/5')" :class="classNameRoute('project/5')">🍒 Brainstroaming</li>
|
||||
</ul>
|
||||
<Loading v-if="projectLoad > 0"/>
|
||||
</li>
|
||||
</ul>
|
||||
<Button class="manage-box-new" type="primary" icon="md-add" @click="addShow=true">New Project</Button>
|
||||
</div>
|
||||
|
||||
<div class="manage-box-main">
|
||||
<div class="manage-box-body">
|
||||
<div class="manage-box-body-content">
|
||||
@ -46,12 +42,11 @@
|
||||
<Modal
|
||||
v-model="addShow"
|
||||
:title="$L('新建项目')"
|
||||
:closable="false"
|
||||
:mask-closable="false"
|
||||
class-name="simple-modal">
|
||||
<Form ref="addProject" :model="addData" :rules="addRule" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="title" :label="$L('项目名称')">
|
||||
<Input type="text" v-model="addData.title"></Input>
|
||||
<FormItem prop="name" :label="$L('项目名称')">
|
||||
<Input type="text" v-model="addData.name"></Input>
|
||||
</FormItem>
|
||||
<FormItem prop="columns" :label="$L('项目模板')">
|
||||
<Select v-model="addData.template" @on-change="(res) => {$set(addData, 'columns', columns[res].value)}" :placeholder="$L('请选择模板')">
|
||||
@ -78,7 +73,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:global {
|
||||
.manage-box {
|
||||
@ -244,7 +238,7 @@ export default {
|
||||
|
||||
addShow: false,
|
||||
addData: {
|
||||
title: '',
|
||||
name: '',
|
||||
columns: [],
|
||||
template: 0,
|
||||
},
|
||||
@ -267,8 +261,8 @@ export default {
|
||||
...mapState(['userId']),
|
||||
},
|
||||
watch: {
|
||||
'$route' (To) {
|
||||
this.curPath = To.path;
|
||||
'$route' (route) {
|
||||
this.curPath = route.path;
|
||||
},
|
||||
userId(userid) {
|
||||
if (userid > 0) {
|
||||
@ -289,7 +283,7 @@ export default {
|
||||
value: [this.$L('产品计划'), this.$L('正在设计'), this.$L('正在研发'), this.$L('测试'), this.$L('准备发布'), this.$L('发布成功')],
|
||||
}];
|
||||
this.addRule = {
|
||||
title: [
|
||||
name: [
|
||||
{ required: true, message: this.$L('请填写项目名称!'), trigger: 'change' },
|
||||
{ type: 'string', min: 2, message: this.$L('项目名称至少2个字!'), trigger: 'change' }
|
||||
]
|
||||
|
@ -7,23 +7,26 @@
|
||||
</div>
|
||||
<div class="project-icobox">
|
||||
<ul class="project-icons">
|
||||
<li class="project-icon">
|
||||
<Icon type="ios-add" />
|
||||
<li class="project-avatar online">
|
||||
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||
</li>
|
||||
<li class="project-icon" @click="addShow=true">
|
||||
<Icon type="md-add" />
|
||||
</li>
|
||||
<li class="project-icon">
|
||||
<Tooltip theme="light" :always="searchText!=''" transfer>
|
||||
<Icon type="ios-search-outline" />
|
||||
<Icon type="ios-search" />
|
||||
<div slot="content">
|
||||
<Input v-model="searchText" placeholder="Search task..." clearable autofocus/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</li>
|
||||
<li class="project-icon" :class="{'active':$store.state.projectChatShow}" @click="$store.commit('toggleProjectChatShow')">
|
||||
<Icon type="ios-chatbubbles-outline" />
|
||||
<Icon type="ios-chatbubbles" />
|
||||
<Badge :count="999"></Badge>
|
||||
</li>
|
||||
<li class="project-avatar online">
|
||||
<Avatar src="https://i.loli.net/2017/08/21/599a521472424.jpg" />
|
||||
<li class="project-icon">
|
||||
<Icon type="ios-more" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="project-switch">
|
||||
@ -595,6 +598,23 @@
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--新建项目-->
|
||||
<Modal
|
||||
v-model="addShow"
|
||||
:title="$L('添加任务')"
|
||||
:styles="{
|
||||
width: '90%',
|
||||
maxWidth: '640px'
|
||||
}"
|
||||
:mask-closable="false"
|
||||
class-name="simple-modal">
|
||||
<TaskAdd v-model="addData"/>
|
||||
<div slot="footer">
|
||||
<Button type="default" @click="addShow=false">{{$L('取消')}}</Button>
|
||||
<Button type="primary" :loading="taskLoad > 0" @click="">{{$L('添加')}}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -639,8 +659,14 @@
|
||||
justify-content: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-left: 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
box-shadow: 0 0 6px #cccccc;
|
||||
}
|
||||
&.project-icon {
|
||||
border-radius: 50%;
|
||||
background-color: #F2F3F5;
|
||||
@ -945,7 +971,7 @@
|
||||
}
|
||||
.item-icon {
|
||||
font-size: 12px;
|
||||
margin-right: 6px;
|
||||
margin-right: 8px;
|
||||
color: #777777;
|
||||
.ivu-icon,
|
||||
.iconfont {
|
||||
@ -988,12 +1014,22 @@
|
||||
|
||||
<script>
|
||||
import TaskPriority from "./task-priority";
|
||||
import TaskAdd from "./task-add";
|
||||
export default {
|
||||
name: "ProjectList",
|
||||
components: {TaskPriority},
|
||||
components: {TaskAdd, TaskPriority},
|
||||
data() {
|
||||
return {
|
||||
searchText: '',
|
||||
|
||||
addShow: false,
|
||||
addData: {
|
||||
type: 'task',
|
||||
owner: 1,
|
||||
column_id: 5,
|
||||
times: [],
|
||||
},
|
||||
taskLoad: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
181
resources/assets/js/pages/manage/components/task-add.vue
Normal file
181
resources/assets/js/pages/manage/components/task-add.vue
Normal file
@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<div class="task-add">
|
||||
<Form class="task-add-form" label-position="top" @submit.native.prevent>
|
||||
<FormItem :label="$L('任务名称')">
|
||||
<Input type="text" v-model="value.name"></Input>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('任务详情')">
|
||||
<TEditor v-model="value.content" :plugins="taskPlugins" :options="taskOptions" :option-full="taskOptionFull"></TEditor>
|
||||
</FormItem>
|
||||
<Button class="advanced-option" :class="{advanced: advanced}" @click="advanced=!advanced">{{$L('高级选项')}}</Button>
|
||||
</Form>
|
||||
<Form v-if="advanced" class="task-add-advanced" label-width="auto" @submit.native.prevent>
|
||||
<FormItem :label="$L('任务列表')">
|
||||
<Select
|
||||
v-model="value.column_id"
|
||||
:placeholder="$L('选择任务列表')"
|
||||
:multipleMax="1"
|
||||
multiple
|
||||
filterable
|
||||
transfer
|
||||
allowCreate
|
||||
transfer-class-name="task-add-advanced-transfer"
|
||||
@on-create="columnCreate">
|
||||
<div slot="drop-prepend" class="task-drop-prepend">{{$L('最多只能选择1项')}}</div>
|
||||
<Option v-for="(item, key) in columns" :value="item.id" :key="key">{{ item.name }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('计划时间')">
|
||||
<DatePicker
|
||||
v-model="value.times"
|
||||
:options="timeOptions"
|
||||
:editable="false"
|
||||
:placeholder="$L('选择计划范围')"
|
||||
format="yyyy-MM-dd HH:mm"
|
||||
type="datetimerange"
|
||||
@on-change="taskTimeChange"/>
|
||||
</FormItem>
|
||||
<FormItem :label="$L('项目负责人')">
|
||||
<UserInput v-model="value.owner" :multiple-max="1" :placeholder="$L('选择项目负责人')"/>
|
||||
</FormItem>
|
||||
<div class="subtasks">
|
||||
<Input type="text" :placeholder="$L('+ 输入子任务,回车添加子任务')"></Input>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TEditor from "../../../components/TEditor";
|
||||
import {mapState} from "vuex";
|
||||
import UserInput from "../../../components/UserInput";
|
||||
|
||||
export default {
|
||||
name: "TaskAdd",
|
||||
components: {UserInput, TEditor},
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
advanced: false,
|
||||
columns: [],
|
||||
|
||||
taskPlugins: [
|
||||
'advlist autolink lists link image charmap print preview hr anchor pagebreak imagetools',
|
||||
'searchreplace visualblocks visualchars code',
|
||||
'insertdatetime media nonbreaking save table contextmenu directionality',
|
||||
'emoticons paste textcolor colorpicker imagetools codesample',
|
||||
'autoresize'
|
||||
],
|
||||
taskOptions: {
|
||||
statusbar: false,
|
||||
menubar: false,
|
||||
forced_root_block : false,
|
||||
remove_trailing_brs: false,
|
||||
autoresize_bottom_margin: 2,
|
||||
min_height: 200,
|
||||
max_height: 380,
|
||||
valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code',
|
||||
toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload'
|
||||
},
|
||||
taskOptionFull: {
|
||||
menubar: 'file edit view',
|
||||
forced_root_block : false,
|
||||
remove_trailing_brs: false,
|
||||
valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code',
|
||||
toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload'
|
||||
},
|
||||
|
||||
timeOptions: {
|
||||
shortcuts: []
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(['projectDetail']),
|
||||
},
|
||||
watch: {
|
||||
projectDetail(detail) {
|
||||
this.columns = detail.project_column;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initLanguage() {
|
||||
const lastSecond = (e) => {
|
||||
return new Date($A.formatDate("Y-m-d 23:59:29", Math.round(e / 1000)))
|
||||
};
|
||||
this.timeOptions = {
|
||||
shortcuts: [{
|
||||
text: this.$L('今天'),
|
||||
value() {
|
||||
return [new Date(), lastSecond(new Date().getTime())];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('明天'),
|
||||
value() {
|
||||
let e = new Date();
|
||||
e.setDate(e.getDate() + 1);
|
||||
return [new Date(), lastSecond(e.getTime())];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('本周'),
|
||||
value() {
|
||||
return [$A.getData('今天', true), lastSecond($A.getData('本周结束2', true))];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('本月'),
|
||||
value() {
|
||||
return [$A.getData('今天', true), lastSecond($A.getData('本月结束', true))];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('3天'),
|
||||
value() {
|
||||
let e = new Date();
|
||||
e.setDate(e.getDate() + 3);
|
||||
return [new Date(), lastSecond(e.getTime())];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('5天'),
|
||||
value() {
|
||||
let e = new Date();
|
||||
e.setDate(e.getDate() + 5);
|
||||
return [new Date(), lastSecond(e.getTime())];
|
||||
}
|
||||
}, {
|
||||
text: this.$L('7天'),
|
||||
value() {
|
||||
let e = new Date();
|
||||
e.setDate(e.getDate() + 7);
|
||||
return [new Date(), lastSecond(e.getTime())];
|
||||
}
|
||||
}]
|
||||
};
|
||||
},
|
||||
columnCreate(val) {
|
||||
if (!this.columns.find(({id}) => id == val)) {
|
||||
this.columns.push({
|
||||
id: val,
|
||||
name: val
|
||||
});
|
||||
}
|
||||
},
|
||||
taskTimeChange() {
|
||||
let tempc = $A.date2string(this.value.times, "Y-m-d H:i");
|
||||
if (tempc[0] && tempc[1]) {
|
||||
if ($A.rightExists(tempc[0], '00:00') && $A.rightExists(tempc[1], '00:00')) {
|
||||
this.$set(this.value.times, 1, tempc[1].replace("00:00", "23:59"));
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
@ -44,11 +44,19 @@ export default {
|
||||
components: {ProjectMessage, ProjectList},
|
||||
data() {
|
||||
return {
|
||||
|
||||
project_id: 0,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.project_id = this.$route.params.id;
|
||||
},
|
||||
watch: {
|
||||
'$route' (route) {
|
||||
this.project_id = route.params.id;
|
||||
},
|
||||
project_id(id) {
|
||||
this.$store.commit('getProjectDetail', id);
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
81
resources/assets/js/store/mutations.js
vendored
81
resources/assets/js/store/mutations.js
vendored
@ -1,14 +1,27 @@
|
||||
export default {
|
||||
/**
|
||||
* 切换项目聊天显隐
|
||||
* @param state
|
||||
*/
|
||||
toggleProjectChatShow(state) {
|
||||
state.projectChatShow = !state.projectChatShow
|
||||
state.setStorage('projectChatShow', state.projectChatShow);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换项目面板显示类型
|
||||
* @param state
|
||||
*/
|
||||
toggleProjectListPanel(state) {
|
||||
state.projectListPanel = !state.projectListPanel
|
||||
state.setStorage('projectListPanel', state.projectListPanel);
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新会员信息
|
||||
* @param state
|
||||
* @param info
|
||||
*/
|
||||
setUserInfo(state, info) {
|
||||
const userInfo = state._cloneJSON(info);
|
||||
userInfo.userid = state._runNum(userInfo.userid);
|
||||
@ -17,5 +30,73 @@ export default {
|
||||
state.userId = userInfo.userid;
|
||||
state.userToken = userInfo.token;
|
||||
state.setStorage('userInfo', state.userInfo);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取项目信息
|
||||
* @param state
|
||||
* @param project_id
|
||||
*/
|
||||
getProjectDetail(state, project_id) {
|
||||
if (state._isJson(state.cacheProject[project_id])) {
|
||||
state.projectDetail = state.cacheProject[project_id];
|
||||
}
|
||||
state.projectLoad++;
|
||||
$A.apiAjax({
|
||||
url: 'project/detail',
|
||||
data: {
|
||||
project_id: project_id,
|
||||
},
|
||||
complete: () => {
|
||||
state.projectLoad--;
|
||||
},
|
||||
success: ({ret, data, msg}) => {
|
||||
if (ret === 1) {
|
||||
state.projectDetail = state.cacheProject[project_id] = data;
|
||||
} else {
|
||||
$A.modalError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取用户基本信息
|
||||
* @param state
|
||||
* @param params {userid, success, complete}
|
||||
*/
|
||||
getUserBasic(state, params) {
|
||||
if (!state._isJson(params)) {
|
||||
return;
|
||||
}
|
||||
const {userid, success, complete} = params;
|
||||
if (typeof success === "function") {
|
||||
if (state._isArray(userid)) {
|
||||
userid.forEach((uid) => {
|
||||
state.cacheUserBasic[uid] && success(state.cacheUserBasic[uid], false)
|
||||
});
|
||||
} else {
|
||||
state.cacheUserBasic[userid] && success(state.cacheUserBasic[userid], false)
|
||||
}
|
||||
}
|
||||
$A.apiAjax({
|
||||
url: 'users/basic',
|
||||
data: {
|
||||
userid: userid
|
||||
},
|
||||
complete: () => {
|
||||
typeof complete === "function" && complete()
|
||||
},
|
||||
success: ({ret, data, msg}) => {
|
||||
if (ret === 1) {
|
||||
data.forEach((item) => {
|
||||
state.cacheUserBasic[item.userid] = item;
|
||||
typeof success === "function" && success(item, true)
|
||||
});
|
||||
} else {
|
||||
$A.modalError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
6
resources/assets/js/store/state.js
vendored
6
resources/assets/js/store/state.js
vendored
@ -172,4 +172,10 @@ export default Object.assign(stateCommon, {
|
||||
userId,
|
||||
userInfo,
|
||||
userToken,
|
||||
|
||||
projectLoad: 0,
|
||||
projectDetail: {},
|
||||
|
||||
cacheProject: {},
|
||||
cacheUserBasic: {},
|
||||
})
|
||||
|
180
resources/assets/sass/main.scss
vendored
180
resources/assets/sass/main.scss
vendored
@ -24,10 +24,47 @@
|
||||
top: 35px;
|
||||
padding-bottom: 35px;
|
||||
}
|
||||
}
|
||||
.ivu-modal-header,
|
||||
.ivu-modal-footer {
|
||||
border-color: transparent;
|
||||
&.ivu-modal-fullscreen {
|
||||
top: 0;
|
||||
}
|
||||
.ivu-modal-header,
|
||||
.ivu-modal-footer {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.ivu-modal-header {
|
||||
padding: 22px 24px 20px;
|
||||
.ivu-modal-header-inner {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
.ivu-modal-body {
|
||||
padding: 16px 32px 2px;
|
||||
}
|
||||
.ivu-modal-footer {
|
||||
padding: 20px 30px 22px;
|
||||
.ivu-btn {
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
padding: 0 32px;
|
||||
}
|
||||
}
|
||||
.ivu-modal-content {
|
||||
border-radius: 18px;
|
||||
.ivu-modal-close {
|
||||
.ivu-icon-ios-close {
|
||||
font-size: 38px;
|
||||
top: 3px;
|
||||
right: 2px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
&:hover {
|
||||
.ivu-icon-ios-close {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-network-add-tabs {
|
||||
@ -283,3 +320,138 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.task-add {
|
||||
.task-add-form,
|
||||
.task-add-advanced {
|
||||
margin: 0 0 -18px;
|
||||
.ivu-form-item-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.ivu-input,
|
||||
.ivu-select-selection {
|
||||
border-color: #e8e8e8;
|
||||
}
|
||||
.teditor-box {
|
||||
.tox-tinymce {
|
||||
border-color: #e8e8e8;
|
||||
}
|
||||
.tox .tox-statusbar,
|
||||
.tox .tox-menubar+.tox-toolbar,
|
||||
.tox .tox-menubar+.tox-toolbar-overlord .tox-toolbar__primary,
|
||||
.tox:not([dir=rtl]) .tox-toolbar__group:not(:last-of-type) {
|
||||
border-color: #e8e8e8;
|
||||
}
|
||||
.tox .tox-toolbar,
|
||||
.tox .tox-toolbar__overflow,
|
||||
.tox .tox-toolbar__primary {
|
||||
background-image: none;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
}
|
||||
.advanced-option {
|
||||
margin-top: -6px;
|
||||
transition: margin 0.2s;
|
||||
z-index: 1;
|
||||
&.advanced {
|
||||
margin-left: 22px;
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.task-add-advanced {
|
||||
margin: 0;
|
||||
padding: 34px 32px 6px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e8e8e8;
|
||||
.subtasks {
|
||||
margin-bottom: 24px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 6px;
|
||||
background-color: #f8f8f8;
|
||||
.ivu-input {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
&:hover,
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ivu-date-picker {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.task-add-advanced-transfer {
|
||||
.task-drop-prepend {
|
||||
text-align: center;
|
||||
color: #c5c8ce;
|
||||
line-height: 20px;
|
||||
padding-bottom: 5px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.common-user {
|
||||
position: relative;
|
||||
.common-user-loading {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
bottom: 0;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.common-loading {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.common-user-transfer {
|
||||
.user-input-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.user-input-avatar {
|
||||
.ivu-avatar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
}
|
||||
.user-input-nickname {
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
.user-input-userid {
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
color: #cccccc;
|
||||
transition: margin 0.1s;
|
||||
}
|
||||
}
|
||||
.ivu-select-item {
|
||||
&.ivu-select-item-selected {
|
||||
&:after {
|
||||
top: 8px;
|
||||
}
|
||||
.user-input-option {
|
||||
.user-input-userid {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-drop-prepend {
|
||||
text-align: center;
|
||||
color: #c5c8ce;
|
||||
line-height: 20px;
|
||||
padding-bottom: 5px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Api\ProjectController;
|
||||
use App\Http\Controllers\Api\UsersController;
|
||||
use App\Http\Controllers\IndexController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
@ -16,7 +17,6 @@ use Illuminate\Support\Facades\Route;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 接口
|
||||
*/
|
||||
@ -24,6 +24,9 @@ Route::prefix('api')->middleware(['webapi'])->group(function () {
|
||||
// 会员
|
||||
Route::any('users/{method}', UsersController::class);
|
||||
Route::any('users/{method}/{action}', UsersController::class);
|
||||
//项目
|
||||
Route::any('project/{method}', ProjectController::class);
|
||||
Route::any('project/{method}/{action}', ProjectController::class);
|
||||
});
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user