|
@@ -18,6 +18,7 @@ use App\Model\ItemNodeMission;
|
|
|
use App\Model\ItemNodeMissionContent;
|
|
use App\Model\ItemNodeMissionContent;
|
|
|
use App\Model\ItemNodeMissionDetails;
|
|
use App\Model\ItemNodeMissionDetails;
|
|
|
use App\Model\ItemNodeMissionEmployee;
|
|
use App\Model\ItemNodeMissionEmployee;
|
|
|
|
|
+use App\Model\ItemNodeMissionShare;
|
|
|
use App\Model\SysOssTasks;
|
|
use App\Model\SysOssTasks;
|
|
|
use App\Model\Tag;
|
|
use App\Model\Tag;
|
|
|
use App\Model\SysMenu;
|
|
use App\Model\SysMenu;
|
|
@@ -2088,102 +2089,6 @@ class ItemService extends Service
|
|
|
return [true, $list];
|
|
return [true, $list];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function itemNodeRule1(&$data, $user, $is_add = true){
|
|
|
|
|
- $data['top_depart_id'] = $user['top_depart_id'];
|
|
|
|
|
- if(empty($data['item_id'])) return [false, '项目ID不能为空'];
|
|
|
|
|
- $item = Item::where('id', $data['item_id'])->where('del_time',0)->first();
|
|
|
|
|
- if(empty($item)) return [false, '项目不存在或已被删除'];
|
|
|
|
|
- $item = $item->toArray();
|
|
|
|
|
- if($item['state'] == Item::TYPE_THREE) return [false, '项目已完结,操作失败'];
|
|
|
|
|
- if(empty($data['title'])) return [false, '节点名称不能为空'];
|
|
|
|
|
- if(! isset($data['node_weight'])) return [false, '节点权重不存在'];
|
|
|
|
|
- list($status, $res) = $this->checkWeight($data['node_weight'], '节点权重');
|
|
|
|
|
- if(! $status) return [false, $res];
|
|
|
|
|
- if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
|
|
|
|
|
- if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
|
|
|
|
|
- if(! empty($data['start_time']) && ! empty($data['end_time']) && $data['start_time'] > $data['end_time']) return [false, '开始时间不能大于结束时间'];
|
|
|
|
|
-
|
|
|
|
|
- $itemStartTime = $item['start_time'];
|
|
|
|
|
- $itemEndTime = $item['end_time'];
|
|
|
|
|
- if (!empty($data['start_time'])) {
|
|
|
|
|
- $inputStartTime = $data['start_time'];
|
|
|
|
|
-
|
|
|
|
|
- if ($itemStartTime > 0 && $inputStartTime < $itemStartTime) {
|
|
|
|
|
- return [false, '节点开始时间不能早于项目开始时间:' . date('Y-m-d', $itemStartTime)];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!empty($data['end_time'])) {
|
|
|
|
|
- $inputEndTime = $data['end_time'];
|
|
|
|
|
- if ($itemEndTime > 0 && $inputEndTime > $itemEndTime) {
|
|
|
|
|
- return [false, '节点结束时间不能晚于项目结束时间:' . date('Y-m-d', $itemEndTime)];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(! empty($data['man_list'])) {
|
|
|
|
|
- foreach ($data['man_list'] as $key => $value){
|
|
|
|
|
- if(empty($value['type'])) return [false, '类型不能为空'];
|
|
|
|
|
- if(empty($value['data_id'])) return [false, '人员不能为空'];
|
|
|
|
|
- $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
|
|
|
|
|
- }
|
|
|
|
|
- list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
|
|
|
|
|
- if(! $status) return [false, $msg];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(! empty($data['device_list'])) {
|
|
|
|
|
- foreach ($data['device_list'] as $key => $value){
|
|
|
|
|
- if(empty($value['type'])) return [false, '类型不能为空'];
|
|
|
|
|
- if(empty($value['data_id'])) return [false, '设备ID不能为空'];
|
|
|
|
|
- $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
|
|
|
|
|
- }
|
|
|
|
|
- list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
|
|
|
|
|
- if(! $status) return [false, $msg];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if($is_add){
|
|
|
|
|
- $bool = ItemNode::where('item_id',$data['item_id'])
|
|
|
|
|
- ->where('top_depart_id', $data['top_depart_id'])
|
|
|
|
|
- ->where('title', $data['title'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- }else{
|
|
|
|
|
- if(empty($data['id'])) return [false,'ID不能为空'];
|
|
|
|
|
- $item = ItemNode::where('id', $data['id'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->first();
|
|
|
|
|
- if(empty($item)) return [false, '项目节点不存在或已被删除'];
|
|
|
|
|
- if($item->approval_state == ItemNode::TYPE_MINUS_ONE) return [false, '节点审核中,操作失败'];
|
|
|
|
|
-
|
|
|
|
|
- if($data['state'] == ItemNode::TYPE_THREE) {
|
|
|
|
|
- $bool = ItemNodeMission::where('del_time',0)
|
|
|
|
|
- ->where('item_node_id', $data['id'])
|
|
|
|
|
- ->where('state', '<>',ItemNodeMission::TYPE_THREE)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- if($bool) return [false, '节点下存在任务未完结'];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $bool = ItemNode::where('title', $data['title'])
|
|
|
|
|
- ->where('item_id',$data['item_id'])
|
|
|
|
|
- ->where('top_depart_id', $data['top_depart_id'])
|
|
|
|
|
- ->where('id','<>',$data['id'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- }
|
|
|
|
|
- if($bool) return [false, '该项目下节点名称已存在'];
|
|
|
|
|
-
|
|
|
|
|
- //判断是否编辑 然后需要审核的 需要后 就更新状态 记录草稿
|
|
|
|
|
- if(! $is_add){
|
|
|
|
|
- $return = $this->checkItemNodeIsChanged($data, $user);
|
|
|
|
|
- if(is_array($return)) {
|
|
|
|
|
- list($status, $msg) = $return;
|
|
|
|
|
- return [$status, $msg];
|
|
|
|
|
- }else{
|
|
|
|
|
- if($return) $data['draft'] = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return [true, ''];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
public function itemNodeRule(&$data, $user, $is_add = true)
|
|
public function itemNodeRule(&$data, $user, $is_add = true)
|
|
|
{
|
|
{
|
|
|
$data['top_depart_id'] = $user['top_depart_id'];
|
|
$data['top_depart_id'] = $user['top_depart_id'];
|
|
@@ -2826,8 +2731,13 @@ class ItemService extends Service
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public function itemMissionProgressBoard($data,$user){
|
|
public function itemMissionProgressBoard($data,$user){
|
|
|
|
|
+ $is_my = $data['is_my'] ?? 0;
|
|
|
|
|
+ $my = $user['id'] ?? 0;
|
|
|
$list = ItemNodeMissionContent::where('del_time',0)
|
|
$list = ItemNodeMissionContent::where('del_time',0)
|
|
|
->where('item_node_mission_id', $data['id'])
|
|
->where('item_node_mission_id', $data['id'])
|
|
|
|
|
+ ->when(! empty($is_my),function ($query) use($my){
|
|
|
|
|
+ return $query->where('crt_id', $my);
|
|
|
|
|
+ })
|
|
|
->select('*')
|
|
->select('*')
|
|
|
->get()->toArray();
|
|
->get()->toArray();
|
|
|
|
|
|
|
@@ -2990,104 +2900,6 @@ class ItemService extends Service
|
|
|
return [true, $model];
|
|
return [true, $model];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function itemNodeMissionRule1(&$data, $user, $is_add = true){
|
|
|
|
|
- $data['top_depart_id'] = $user['top_depart_id'];
|
|
|
|
|
- if(empty($data['item_node_id']) && empty($data['parent_item_node_mission_id'])) return [false, '节点与父级任务不能同时为空'];
|
|
|
|
|
- if(empty($data['item_node_id'])) return [false, '项目节点ID不能为空'];
|
|
|
|
|
- $item = ItemNode::where('id', $data['item_node_id'])->where('del_time',0)->first();
|
|
|
|
|
- if(empty($item)) return [false, '项目节点不存在或已被删除'];
|
|
|
|
|
- $item = $item->toArray();
|
|
|
|
|
- if($item['state'] == ItemNode::TYPE_THREE) return [false, '节点已完结,操作失败'];
|
|
|
|
|
- $data['item_id'] = $item['item_id'];
|
|
|
|
|
- if(! empty($data['parent_item_node_mission_id'])) {
|
|
|
|
|
- $bool = ItemNodeMission::where('id', $data['parent_item_node_mission_id'])->where('del_time',0)->exists();
|
|
|
|
|
- if(! $bool) return [false, '父任务不存在或已被删除'];
|
|
|
|
|
- }
|
|
|
|
|
- if(empty($data['title'])) return [false, '任务名称不能为空'];
|
|
|
|
|
- if(! isset($data['mission_weight'])) return [false, '任务权重不存在'];
|
|
|
|
|
- list($status, $res) = $this->checkWeight($data['mission_weight'], '任务权重');
|
|
|
|
|
- if(! $status) return [false, $res];
|
|
|
|
|
- if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
|
|
|
|
|
- if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
|
|
|
|
|
- if(! empty($data['start_time']) && ! empty($data['end_time']) && $data['start_time'] > $data['end_time']) return [false, '开始时间不能大于结束时间'];
|
|
|
|
|
-
|
|
|
|
|
- $itemStartTime = $item['start_time'];
|
|
|
|
|
- $itemEndTime = $item['end_time'];
|
|
|
|
|
- if (!empty($data['start_time'])) {
|
|
|
|
|
- $inputStartTime = $data['start_time'];
|
|
|
|
|
- if ($itemStartTime > 0 && $inputStartTime < $itemStartTime) {
|
|
|
|
|
- return [false, '任务开始时间不能早于项目节点开始时间:' . date('Y-m-d', $itemStartTime)];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!empty($data['end_time'])) {
|
|
|
|
|
- $inputEndTime = $data['end_time'];
|
|
|
|
|
- if ($itemEndTime > 0 && $inputEndTime > $itemEndTime) {
|
|
|
|
|
- return [false, '任务结束时间不能晚于项目节点结束时间:' . date('Y-m-d', $itemEndTime)];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if(! empty($data['man_list'])) {
|
|
|
|
|
- foreach ($data['man_list'] as $key => $value){
|
|
|
|
|
- if(empty($value['type'])) return [false, '类型不能为空'];
|
|
|
|
|
- if(empty($value['data_id'])) return [false, '人员不能为空'];
|
|
|
|
|
- $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
|
|
|
|
|
- }
|
|
|
|
|
- list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
|
|
|
|
|
- if(! $status) return [false, $msg];
|
|
|
|
|
- }
|
|
|
|
|
- if(! empty($data['device_list'])) {
|
|
|
|
|
- foreach ($data['device_list'] as $key => $value){
|
|
|
|
|
- if(empty($value['type'])) return [false, '类型不能为空'];
|
|
|
|
|
- if(empty($value['data_id'])) return [false, '设备ID不能为空'];
|
|
|
|
|
- $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
|
|
|
|
|
- }
|
|
|
|
|
- list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
|
|
|
|
|
- if(! $status) return [false, $msg];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if($is_add){
|
|
|
|
|
- $bool = ItemNodeMission::where('item_node_id',$data['item_node_id'])
|
|
|
|
|
- ->where('top_depart_id', $data['top_depart_id'])
|
|
|
|
|
- ->where('title', $data['title'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- }else{
|
|
|
|
|
- if(empty($data['id'])) return [false,'ID不能为空'];
|
|
|
|
|
- $item = ItemNodeMission::where('id', $data['id'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->first();
|
|
|
|
|
- if(empty($item)) return [false, '项目节点下任务不存在或已被删除'];
|
|
|
|
|
- if($item->approval_state == ItemNodeMission::TYPE_MINUS_ONE) return [false, '任务审核中,操作失败'];
|
|
|
|
|
- if($data['state'] == ItemNodeMission::TYPE_THREE) {
|
|
|
|
|
- $bool = ItemNodeMission::where('del_time',0)
|
|
|
|
|
- ->where('parent_item_node_mission_id', $data['id'])
|
|
|
|
|
- ->where('state', '<>',ItemNodeMission::TYPE_THREE)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- if($bool) return [false, '任务下存在子任务未完结'];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $bool = ItemNodeMission::where('title', $data['title'])
|
|
|
|
|
- ->where('item_node_id',$data['item_node_id'])
|
|
|
|
|
- ->where('top_depart_id', $data['top_depart_id'])
|
|
|
|
|
- ->where('id','<>',$data['id'])
|
|
|
|
|
- ->where('del_time',0)
|
|
|
|
|
- ->exists();
|
|
|
|
|
- }
|
|
|
|
|
- if($bool) return [false, '该项目节点下任务名称已存在'];
|
|
|
|
|
-
|
|
|
|
|
- //判断是否编辑 然后需要审核的 需要后 就更新状态 记录草稿
|
|
|
|
|
- if(! $is_add){
|
|
|
|
|
- $return = $this->checkItemNodeMissionIsChanged($data, $user);
|
|
|
|
|
- if(is_array($return)) {
|
|
|
|
|
- list($status, $msg) = $return;
|
|
|
|
|
- return [$status, $msg];
|
|
|
|
|
- }else{
|
|
|
|
|
- if($return) $data['draft'] = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return [true, ''];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
public function itemNodeMissionRule(&$data, $user, $is_add = true)
|
|
public function itemNodeMissionRule(&$data, $user, $is_add = true)
|
|
|
{
|
|
{
|
|
|
$data['top_depart_id'] = $user['top_depart_id'];
|
|
$data['top_depart_id'] = $user['top_depart_id'];
|
|
@@ -3295,6 +3107,17 @@ class ItemService extends Service
|
|
|
->toArray();
|
|
->toArray();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function getItemNodeMissionMap($ids){
|
|
|
|
|
+ $ids = array_filter((array)$ids);
|
|
|
|
|
+ if (empty($ids)) return [];
|
|
|
|
|
+
|
|
|
|
|
+ return ItemNodeMission::whereIn('id', $ids)
|
|
|
|
|
+ ->select('id', 'title', 'code')
|
|
|
|
|
+ ->get()
|
|
|
|
|
+ ->keyBy('id')
|
|
|
|
|
+ ->toArray();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function checkIsDelivery($data, $tableName){
|
|
public function checkIsDelivery($data, $tableName){
|
|
|
//是否需要交付物完结
|
|
//是否需要交付物完结
|
|
|
if($data['is_review_required']){
|
|
if($data['is_review_required']){
|
|
@@ -3363,4 +3186,400 @@ class ItemService extends Service
|
|
|
list($status, $msg) = (new WorkFlowService())->triggerWorkflow($oldData['review_id'],$oldData['id'],$tableName,$user);
|
|
list($status, $msg) = (new WorkFlowService())->triggerWorkflow($oldData['review_id'],$oldData['id'],$tableName,$user);
|
|
|
if(! $status) throw new \Exception($msg);
|
|
if(! $status) throw new \Exception($msg);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 创建链接分享
|
|
|
|
|
+ public function shareAdd($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 执行校验
|
|
|
|
|
+ list($status, $msg) = $this->shareRule($data, $user);
|
|
|
|
|
+ if (!$status) return [$status, $msg];
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ $mission = $data['mission_data'];
|
|
|
|
|
+
|
|
|
|
|
+ // 生成唯一的随机 Token (32位字符串)
|
|
|
|
|
+ $shareToken = bin2hex(random_bytes(16));
|
|
|
|
|
+
|
|
|
|
|
+ $model = new ItemNodeMissionShare();
|
|
|
|
|
+ $model->item_id = $mission->item_id;
|
|
|
|
|
+ $model->item_node_id = $mission->item_node_id;
|
|
|
|
|
+ $model->item_node_mission_id = $mission->id;
|
|
|
|
|
+ $model->share_token = $shareToken;
|
|
|
|
|
+ $model->expire_time = $data['expire_time'];
|
|
|
|
|
+ $model->remark = $data['remark'] ?? '';
|
|
|
|
|
+ $model->crt_id = $user['id'];
|
|
|
|
|
+ $model->top_depart_id = $data['top_depart_id'];
|
|
|
|
|
+ $model->save();
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $exception) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ return [false, $exception->getMessage()];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareEdit($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 执行校验
|
|
|
|
|
+ list($status, $msg) = $this->shareRule($data, $user, false);
|
|
|
|
|
+ if (!$status) return [$status, $msg];
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ $model = $data['share_model'];
|
|
|
|
|
+ $model->expire_time = $data['expire_time'];
|
|
|
|
|
+ $model->remark = $data['remark'] ?? '';
|
|
|
|
|
+ $model->type = $data['type'] ?? 0;
|
|
|
|
|
+ $model->save();
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $exception) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ return [false, $exception->getMessage()];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareRule(&$data, $user, $is_add = true)
|
|
|
|
|
+ {
|
|
|
|
|
+ $data['top_depart_id'] = $user['top_depart_id'];
|
|
|
|
|
+ $currentTime = time();
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 基础参数校验
|
|
|
|
|
+ if (empty($data['item_node_mission_id'])) return [false, '请选择任务'];
|
|
|
|
|
+ if (empty($data['expire_time'])) return [false, '请选择链接过期时间'];
|
|
|
|
|
+ if (! isset($data['type']) || ! isset(ItemNodeMissionShare::QX_Type[$data['type']])) return [false, '链接权限不能为空或错误'];
|
|
|
|
|
+
|
|
|
|
|
+ $mission = DB::table('item_node_mission')
|
|
|
|
|
+ ->where('id', $data['item_node_mission_id'])
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if (empty($mission)) return [false, '任务不存在或已被删除'];
|
|
|
|
|
+ if ($mission->approval_state == -1) return [false, '任务正在审核中,无法生成/编辑分享链接'];
|
|
|
|
|
+ $data['item_node_mission_title'] = $mission->title;
|
|
|
|
|
+ $data['item_node_title'] = ItemNode::where('id', $mission->item_node_id)->value('title') ?? '';
|
|
|
|
|
+ $data['item_title'] = Item::where('id', $mission->item_id)->value('title') ?? '';
|
|
|
|
|
+
|
|
|
|
|
+ // 时间校验与转换
|
|
|
|
|
+ $data['expire_time'] = $this->changeDateToDate($data['expire_time'], true);
|
|
|
|
|
+ if ($data['expire_time'] < $currentTime) {
|
|
|
|
|
+ return [false, '过期时间不能小于当前时间'];
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($mission->end_time > 0 && $data['expire_time'] > $mission->end_time) {
|
|
|
|
|
+ return [false, '链接过期时间不能超过任务的结束时间'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 新增 编辑 的差异化校验
|
|
|
|
|
+ if ($is_add) {
|
|
|
|
|
+ // 【新增场景】同一个任务下的同一个人,只允许存在一个有效的分享链接
|
|
|
|
|
+ // 健壮性设计:状态是0 并且 事实上还没过期的链接,都算有效链接
|
|
|
|
|
+ $existsValidShare = ItemNodeMissionShare::where('item_node_mission_id', $data['item_node_mission_id'])
|
|
|
|
|
+ ->where('status', ItemNodeMissionShare::TYPE_ZERO) // 0-已生效
|
|
|
|
|
+ ->where('type', $data['type'])
|
|
|
|
|
+ ->where('expire_time', '>', $currentTime) // 必须也没过期
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->exists();
|
|
|
|
|
+
|
|
|
|
|
+ $qx = ItemNodeMissionShare::QX_Type[$data['type']] ?? '';
|
|
|
|
|
+ if ($existsValidShare) return [false, '该任务下已存在一个生效中的分享链接(权限:' . $qx . ')'];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (empty($data['id'])) return [false, 'ID不能为空'];
|
|
|
|
|
+
|
|
|
|
|
+ $share = ItemNodeMissionShare::where('id', $data['id'])
|
|
|
|
|
+ ->where('top_depart_id', $data['top_depart_id'])
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if (empty($share)) return [false, '链接不存在或已被删除'];
|
|
|
|
|
+
|
|
|
|
|
+ // 核心拦截:已过期(1) 或 已作废(2) 或者是时间戳层面的实际过期,均不允许编辑
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_ONE || $share->expire_time <= $currentTime) {
|
|
|
|
|
+ return [false, '该分享链接已过期,不允许操作'];
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_TWO) {
|
|
|
|
|
+ return [false, '该分享链接已作废,不允许操作'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 编辑时查重:排除自身 ID
|
|
|
|
|
+ $existsOtherValidShare = ItemNodeMissionShare::where('item_node_mission_id', $data['item_node_mission_id'])
|
|
|
|
|
+ ->where('id', '<>', $data['id']) // 排除自己
|
|
|
|
|
+ ->where('status', ItemNodeMissionShare::TYPE_ZERO)
|
|
|
|
|
+ ->where('type', $share->type)
|
|
|
|
|
+ ->where('expire_time', '>', $currentTime)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->exists();
|
|
|
|
|
+
|
|
|
|
|
+ $qx = ItemNodeMissionShare::QX_Type[$share->type] ?? '';
|
|
|
|
|
+ if ($existsOtherValidShare) {
|
|
|
|
|
+ return [false, '该任务下已存在一个生效中的分享链接(权限:' . $qx . ')'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $data['share_model'] = $share;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $data['mission_data'] = $mission;
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareCommon($data,$user, $field = []){
|
|
|
|
|
+ if(empty($field)) $field = ItemNodeMissionShare::$field;
|
|
|
|
|
+
|
|
|
|
|
+ $model = ItemNodeMissionShare::Clear($user,$data);
|
|
|
|
|
+ $model = $model->where('del_time',0)
|
|
|
|
|
+ ->select($field)
|
|
|
|
|
+ ->orderby('id', 'desc');
|
|
|
|
|
+
|
|
|
|
|
+ if(! empty($data['item_title'])) $model->where('item_title', 'LIKE', '%'.$data['item_title'].'%');
|
|
|
|
|
+ if(! empty($data['item_node_title'])) $model->where('item_node_title', 'LIKE', '%'.$data['item_node_title'].'%');
|
|
|
|
|
+ if(! empty($data['item_node_mission_title'])) $model->where('item_node_mission_title', 'LIKE', '%'.$data['item_node_mission_title'].'%');
|
|
|
|
|
+ if(! empty($data['id'])) $model->whereIn('id', $data['id']);
|
|
|
|
|
+ if(isset($data['status'])) $model->where('status', $data['status']);
|
|
|
|
|
+ if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
|
|
|
|
|
+ $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
|
|
|
|
|
+ $model->where('crt_time','>=',$return[0]);
|
|
|
|
|
+ $model->where('crt_time','<=',$return[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $model;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareList($data,$user){
|
|
|
|
|
+ $model = $this->shareCommon($data, $user);
|
|
|
|
|
+ $list = $this->limit($model,'',$data);
|
|
|
|
|
+ $list = $this->fillShareData($list);
|
|
|
|
|
+
|
|
|
|
|
+ return [true, $list];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function fillShareData($data){
|
|
|
|
|
+ if(empty($data['data'])) return $data;
|
|
|
|
|
+
|
|
|
|
|
+ $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_column($data['data'],'crt_id')));
|
|
|
|
|
+ foreach ($data['data'] as $key => $value){
|
|
|
|
|
+ $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
|
|
|
|
|
+ $data['data'][$key]['expire_time'] = $value['expire_time'] ? date('Y-m-d',$value['expire_time']) : '';
|
|
|
|
|
+ $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
|
|
|
|
|
+ $data['data'][$key]['status_title'] = ItemNodeMissionShare::State_Type[$value['status']] ?? '';
|
|
|
|
|
+ $data['data'][$key]['type_title'] = ItemNodeMissionShare::QX_Type[$value['type']] ?? '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareDetail($data, $user){
|
|
|
|
|
+ if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
|
|
|
|
|
+ $customer = ItemNodeMissionShare::where('del_time',0)
|
|
|
|
|
+ ->where('id',$data['id'])
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if(empty($customer)) return [false,'分享链接不存在或已被删除'];
|
|
|
|
|
+ $customer = $customer->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ $customer['expire_time'] = ! empty($customer['expire_time']) ? date("Y-m-d", $customer['expire_time']) : "";
|
|
|
|
|
+ $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
|
|
|
|
|
+ $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
|
|
|
|
|
+ $customer['status_title'] = ItemNodeMissionShare::State_Type[$customer['status']] ?? '';
|
|
|
|
|
+ $customer['type_title'] = ItemNodeMissionShare::QX_Type[$customer['type']] ?? '';
|
|
|
|
|
+
|
|
|
|
|
+ return [true, $customer];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareCancel($data, $user){
|
|
|
|
|
+ if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
|
|
|
|
|
+
|
|
|
|
|
+ $share = ItemNodeMissionShare::where('id', $data['id'])
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if (empty($share)) return [false, '分享链接不存在或已被删除'];
|
|
|
|
|
+
|
|
|
|
|
+ $time = time();
|
|
|
|
|
+
|
|
|
|
|
+ // 核心拦截:已过期(1) 或 已作废(2) 或者是时间戳层面的实际过期,均不允许编辑
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_ONE || $share->expire_time <= $time) {
|
|
|
|
|
+ return [false, '该分享链接已过期,不允许操作'];
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_TWO) {
|
|
|
|
|
+ return [false, '该分享链接已作废,不允许操作'];
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ $share->status = ItemNodeMissionShare::TYPE_TWO;
|
|
|
|
|
+ $share->save();
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+ }catch (\Exception $exception){
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ return [false,$exception->getMessage()];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function shareOutSideHTML($data){
|
|
|
|
|
+ if(empty($data['share_token'])) return [false, '分享链接不能为空'];
|
|
|
|
|
+
|
|
|
|
|
+ $share = ItemNodeMissionShare::where('share_token', $data['share_token'])
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if (empty($share)) return [false, '分享链接不存在或已被删除'];
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_ONE || $share->expire_time <= time()) {
|
|
|
|
|
+ return [false, '该分享链接已过期'];
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($share->status == ItemNodeMissionShare::TYPE_TWO) {
|
|
|
|
|
+ return [false, '该分享链接已作废'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $share_array = $share->toArray();
|
|
|
|
|
+ $emp = (new EmployeeService())->getEmployeeMap([$share_array['user_id']]);
|
|
|
|
|
+ $share_array['user_title'] = $emp[$share_array['user_id']] ?? "";
|
|
|
|
|
+ list($status, $msg) = $this->itemNodeMissionDetail(['id' => $share_array['item_node_mission_id']], ['top_depart_id' => $share_array['top_depart_id']]);
|
|
|
|
|
+ if(! $status) return [false, $msg];
|
|
|
|
|
+ $share_array['item_node_mission_data'] = $msg;
|
|
|
|
|
+
|
|
|
|
|
+ return [true, $share_array];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 外部人员更新任务进展(单条模式)
|
|
|
|
|
+ */
|
|
|
|
|
+ public function itemNodeMissionUpdateProgressContentOutSide($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ list($status, $msg) = $this->progressOutsideRule($data, $user);
|
|
|
|
|
+ if (!$status) return [$status, $msg];
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
|
+
|
|
|
|
|
+ $insertData = $data['processed_data'];
|
|
|
|
|
+ ItemNodeMissionContent::insert($insertData);
|
|
|
|
|
+
|
|
|
|
|
+ DB::commit();
|
|
|
|
|
+ } catch (\Exception $exception) {
|
|
|
|
|
+ DB::rollBack();
|
|
|
|
|
+ return [false, $exception->getMessage()];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 进展提交校验逻辑
|
|
|
|
|
+ */
|
|
|
|
|
+ public function progressOutsideRule(&$data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 1. 基础校验
|
|
|
|
|
+ if (empty($data['id'])) return [false, '任务ID不能为空'];
|
|
|
|
|
+
|
|
|
|
|
+ $customer = ItemNodeMission::where('del_time', 0)
|
|
|
|
|
+ ->where('id', $data['id'])
|
|
|
|
|
+ ->first();
|
|
|
|
|
+ if (empty($customer)) return [false, '项目节点任务不存在或已被删除'];
|
|
|
|
|
+ $customer = $customer->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($data['data']) || !is_array($data['data'])) return [false, '任务进展明细不能为空'];
|
|
|
|
|
+
|
|
|
|
|
+ // 强制获取第一条数据(确保单条限制)
|
|
|
|
|
+ $value = reset($data['data']);
|
|
|
|
|
+ $empId = $user['id'] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 日期校验
|
|
|
|
|
+ if (empty($value['order_time'])) return [false, '提交日期不能为空'];
|
|
|
|
|
+ $order_time = $this->changeDateToDate($value['order_time']);
|
|
|
|
|
+ if ($order_time > $customer['end_time'] || $order_time < $customer['start_time']) {
|
|
|
|
|
+ return [false, "提交日期必须在任务周期内"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 数字与合法性校验
|
|
|
|
|
+ $res = $this->checkNumber($value['start_time_hour'], 0, 'non-negative');
|
|
|
|
|
+ if (!$res['valid']) return [false, "开始点:" . $res['error']];
|
|
|
|
|
+ if ($value['start_time_hour'] > 23) return [false, "开始点不合法"];
|
|
|
|
|
+
|
|
|
|
|
+ $res = $this->checkNumber($value['start_time_min'], 0, 'non-negative');
|
|
|
|
|
+ if (!$res['valid']) return [false, "开始分:" . $res['error']];
|
|
|
|
|
+ if ($value['start_time_min'] > 59) return [false, "开始分不合法"];
|
|
|
|
|
+
|
|
|
|
|
+ $res = $this->checkNumber($value['end_time_hour'], 0, 'non-negative');
|
|
|
|
|
+ if (!$res['valid']) return [false, "结束点:" . $res['error']];
|
|
|
|
|
+ if ($value['end_time_hour'] > 24) return [false, "结束点不合法"];
|
|
|
|
|
+
|
|
|
|
|
+ $res = $this->checkNumber($value['end_time_min'], 0, 'non-negative');
|
|
|
|
|
+ if (!$res['valid']) return [false, "结束分:" . $res['error']];
|
|
|
|
|
+ if ($value['end_time_min'] > 59) return [false, "结束分不合法"];
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 计算当前提交的时间段(分钟数)
|
|
|
|
|
+ $currentStart = $value['start_time_hour'] * 60 + $value['start_time_min'];
|
|
|
|
|
+ $currentEnd = $value['end_time_hour'] * 60 + $value['end_time_min'];
|
|
|
|
|
+
|
|
|
|
|
+ if ($currentStart >= $currentEnd) {
|
|
|
|
|
+ return [false, "开始时间必须早于结束时间"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $calculatedTotal = $currentEnd - $currentStart;
|
|
|
|
|
+ if (!isset($value['total_work_min']) || intval($value['total_work_min']) !== $calculatedTotal) {
|
|
|
|
|
+ return [false, "工时计算有误,应为 {$calculatedTotal} 分钟"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $hasDbOverlap = ItemNodeMissionContent::where('del_time', 0)
|
|
|
|
|
+ ->where('crt_id', $empId)
|
|
|
|
|
+ ->where('order_time', $order_time)
|
|
|
|
|
+ ->where('item_node_mission_id', '<>', $customer['id'])
|
|
|
|
|
+ ->where(function ($query) use ($value) {
|
|
|
|
|
+
|
|
|
|
|
+ // 【条件一】:数据库开始时间 < 前端结束时间
|
|
|
|
|
+ $query->where(function ($q) use ($value) {
|
|
|
|
|
+ $q->where('start_time_hour', '<', $value['end_time_hour'])
|
|
|
|
|
+ ->orWhere(function ($sub) use ($value) {
|
|
|
|
|
+ $sub->where('start_time_hour', '=', $value['end_time_hour'])
|
|
|
|
|
+ ->where('start_time_min', '<', $value['end_time_min']);
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 【条件二】:前端开始时间 < 数据库结束时间
|
|
|
|
|
+ ->where(function ($q) use ($value) {
|
|
|
|
|
+ $q->where('end_time_hour', '>', $value['start_time_hour'])
|
|
|
|
|
+ ->orWhere(function ($sub) use ($value) {
|
|
|
|
|
+ $sub->where('end_time_hour', '=', $value['start_time_hour'])
|
|
|
|
|
+ ->where('end_time_min', '>', $value['start_time_min']);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ })
|
|
|
|
|
+ ->exists();
|
|
|
|
|
+
|
|
|
|
|
+ if ($hasDbOverlap) {
|
|
|
|
|
+ return [false, "您在该日期(" . date('Y-m-d', $order_time) . ")下已提交过冲突的工时阶段"];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 拼装标准的单条入库数据结构(包在数组里以适配单次批量 insert)
|
|
|
|
|
+ $processedData = [
|
|
|
|
|
+ [
|
|
|
|
|
+ 'item_id' => $customer['item_id'],
|
|
|
|
|
+ 'item_node_id' => $customer['item_node_id'],
|
|
|
|
|
+ 'item_node_mission_id' => $customer['id'],
|
|
|
|
|
+ 'top_depart_id' => $user['top_depart_id'],
|
|
|
|
|
+ 'crt_id' => $empId,
|
|
|
|
|
+ 'order_time' => $order_time,
|
|
|
|
|
+ 'start_time_hour' => $value['start_time_hour'],
|
|
|
|
|
+ 'start_time_min' => $value['start_time_min'],
|
|
|
|
|
+ 'end_time_hour' => $value['end_time_hour'],
|
|
|
|
|
+ 'end_time_min' => $value['end_time_min'],
|
|
|
|
|
+ 'total_work_min' => $calculatedTotal,
|
|
|
|
|
+ 'mark' => $value['mark'] ?? '',
|
|
|
|
|
+ 'crt_time' => time(),
|
|
|
|
|
+ 'upd_time' => time(),
|
|
|
|
|
+ ]
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $data['processed_data'] = $processedData;
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ''];
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|