ItemService.php 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. <?php
  2. namespace App\Service;
  3. use App\Jobs\ProcessOssTask;
  4. use App\Model\CustomFieldValue;
  5. use App\Model\Device;
  6. use App\Model\Employee;
  7. use App\Model\Item;
  8. use App\Model\ItemDetails;
  9. use App\Model\ItemEmployee;
  10. use App\Model\ItemFile;
  11. use App\Model\ItemNode;
  12. use App\Model\ItemNodeDetails;
  13. use App\Model\ItemNodeEmployee;
  14. use App\Model\ItemNodeMission;
  15. use App\Model\ItemNodeMissionDetails;
  16. use App\Model\ItemNodeMissionEmployee;
  17. use App\Model\SysOssTasks;
  18. use App\Model\Tag;
  19. use App\Model\SysMenu;
  20. use Illuminate\Support\Facades\DB;
  21. class ItemService extends Service
  22. {
  23. public function itemFileUpLoad($data,$user){
  24. // 1. 基础校验
  25. $from = $data['from'] ?? null;
  26. $fromMap = ItemFile::from;
  27. if (empty($from)) return [false, '上传来源类型不能为空'];
  28. if (!isset($fromMap[$from])) return [false, '上传来源类型错误'];
  29. $id = $data['id'] ?? null;
  30. if (empty($id)) return [false, '来源ID不能为空'];
  31. $modelMap = [
  32. ItemFile::from_one => Item::class,
  33. ItemFile::from_two => ItemNode::class,
  34. ItemFile::from_three => ItemNodeMission::class,
  35. ];
  36. $modelClass = $modelMap[$from] ?? "";
  37. $item = $modelClass::where('id', $id)->where('del_time', 0)->first();
  38. if (!$item) return [false, $fromMap[$from] . "不存在或已被删除"];
  39. $itemId = $item->item_id ?? $item->id;
  40. $itemNodeId = $item->item_node_id ?? ($from == ItemFile::from_one ? 0 : $item->id);
  41. $missionId = ($from != ItemFile::from_one && $from != ItemFile::type_two) ? $item->id : 0;
  42. $files = $data['file'] ?? [];
  43. if (empty($files)) return [false, '上传文件不能为空'];
  44. $time = time();
  45. $pendingTasks = [];
  46. foreach ($files as &$file) {
  47. if (empty($file['url']) || empty($file['type']) || empty($file['name'])) {
  48. return [false, '文件信息(URL/类型/名称)不完整'];
  49. }
  50. $file['top_depart_id'] = $user['top_depart_id'];
  51. $file['type'] = $from;
  52. $file['item_id'] = $itemId;
  53. $file['item_node_id'] = $itemNodeId;
  54. $file['item_node_mission_id'] = $missionId;
  55. $file['crt_time'] = $time;
  56. $pendingTasks[] = ['type' => SysOssTasks::type_two, 'url' => $file['url'], 'top_depart_id' => $user['top_depart_id'], 'crt_time' => $time];
  57. }
  58. unset($file);
  59. $data['file'] = $files;
  60. try {
  61. DB::beginTransaction();
  62. ItemFile::insert($data['file']);
  63. //触发 OSS 任务
  64. if (!empty($pendingTasks)) {
  65. SysOssTasks::insert($pendingTasks);
  66. ProcessOssTask::dispatch()->onQueue(SysOssTasks::job);
  67. }
  68. DB::commit();
  69. }catch (\Exception $exception){
  70. DB::rollBack();
  71. return [false,$exception->getMessage()];
  72. }
  73. return [true, ''];
  74. }
  75. public function itemEdit($data,$user){
  76. list($status,$msg) = $this->itemRule($data, $user, false);
  77. if(!$status) return [$status,$msg];
  78. try {
  79. DB::beginTransaction();
  80. $model = Item::where('id', $data['id'])->first();
  81. $old_employee_id = $model->charge_id;
  82. $tableName = $model->getTable();
  83. $model->code = $data['code'] ?? '';
  84. $model->title = $data['title'] ?? '';
  85. $model->mark = $data['mark'] ?? "";
  86. $model->start_time = $data['start_time'] ?? 0;
  87. $model->end_time = $data['end_time'] ?? 0;
  88. $model->state = $data['state'] ?? 0;
  89. $model->budget = $data['budget'] ?? 0;
  90. $model->charge_id = $data['charge_id'] ?? 0;
  91. $model->field = $data['field'] ?? "";
  92. $model->item_attribute = $data['item_attribute'] ?? 0;
  93. //项目管理的字段
  94. if($user['select_tree_type'] == SysMenu::tree_type_one){
  95. $model->is_review_required = $data['is_review_required'] ?? 0;
  96. $model->review_id = $data['review_id'] ?? 0;
  97. $model->priority_id = $data['priority_id'] ?? 0;
  98. }
  99. $model->save();
  100. $time = time();
  101. // 人员项目表
  102. $this->saveEmployee($data['id'], $time, $data, $user, $old_employee_id);
  103. ItemDetails::where('del_time',0)
  104. ->where('item_id', $model->id)
  105. ->update(['del_time' => $time]);
  106. $this->saveDetail($model->id, $time, $data);
  107. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  108. if (! $status) {
  109. DB::rollBack();
  110. return [false, $msg];
  111. }
  112. DB::commit();
  113. }catch (\Exception $exception){
  114. DB::rollBack();
  115. return [false,$exception->getMessage()];
  116. }
  117. return [true, ''];
  118. }
  119. public function itemAdd($data,$user){
  120. list($status,$msg) = $this->itemRule($data, $user);
  121. if(!$status) return [$status,$msg];
  122. try {
  123. DB::beginTransaction();
  124. $model = new Item();
  125. $tableName = $model->getTable();
  126. $model->code = $data['code'] ?? '';
  127. $model->title = $data['title'] ?? '';
  128. $model->mark = $data['mark'] ?? "";
  129. $model->start_time = $data['start_time'] ?? 0;
  130. $model->end_time = $data['end_time'] ?? 0;
  131. $model->state = $data['state'] ?? 0;
  132. $model->budget = $data['budget'] ?? 0;
  133. $model->charge_id = $data['charge_id'] ?? 0;
  134. $model->field = $data['field'] ?? "";
  135. $model->item_attribute = $data['item_attribute'] ?? 0;
  136. $model->is_review_required = $data['is_review_required'] ?? 0;
  137. $model->review_id = $data['review_id'] ?? 0;
  138. $model->priority_id = $data['priority_id'] ?? 0;
  139. $model->crt_id = $user['id'];
  140. $model->top_depart_id = $data['top_depart_id'];
  141. $model->save();
  142. $time = time();
  143. $this->saveDetail($model->id, $time, $data);
  144. // 人员项目表
  145. $this->saveEmployee($model->id, $time, $data, $user);
  146. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  147. if (!$status) {
  148. DB::rollBack();
  149. return [false, $msg];
  150. }
  151. DB::commit();
  152. }catch (\Exception $exception){
  153. DB::rollBack();
  154. return [false,$exception->getMessage()];
  155. }
  156. return [true, ''];
  157. }
  158. private function saveDetail($id, $time, $data){
  159. if(! empty($data['man_list'])){
  160. $unit = [];
  161. foreach ($data['man_list'] as $value){
  162. $unit[] = [
  163. 'item_id' => $id,
  164. 'type' => $value['type'],
  165. 'data_id' => $value['data_id'],
  166. 'crt_time' => $time,
  167. 'top_depart_id' => $value['top_depart_id'],
  168. ];
  169. }
  170. if(! empty($unit)) ItemDetails::insert($unit);
  171. }
  172. if(! empty($data['device_list'])){
  173. $receipt = [];
  174. foreach ($data['device_list'] as $value){
  175. $receipt[] = [
  176. 'item_id' => $id,
  177. 'type' => $value['type'],
  178. 'data_id' => $value['data_id'],
  179. 'crt_time' => $time,
  180. 'top_depart_id' => $value['top_depart_id'],
  181. ];
  182. }
  183. if(! empty($receipt)) ItemDetails::insert($receipt);
  184. }
  185. }
  186. private function saveEmployee($id, $time, $data, $user, $old_employee_id = 0){
  187. if($old_employee_id != $data['charge_id']){
  188. ItemEmployee::where('del_time',0)
  189. ->where('item_id', $id)
  190. ->where('data_id', $old_employee_id)
  191. ->delete();
  192. ItemEmployee::insert([
  193. 'item_id' => $id,
  194. 'data_id' => $data['charge_id'],
  195. 'top_depart_id' => $user['top_depart_id'],
  196. 'crt_time' => $time
  197. ]);
  198. }
  199. }
  200. private function getDetail($id){
  201. $data = ItemDetails::where('del_time',0)
  202. ->where('item_id', $id)
  203. ->get()->toArray();
  204. $id = $id2 = [];
  205. foreach ($data as $value){
  206. if($value['type'] == ItemDetails::type_one) {
  207. $id[] = $value['data_id'];
  208. }else{
  209. $id2[] = $value['data_id'];
  210. }
  211. }
  212. $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
  213. $map = array_column($map,null,'id');
  214. $map2 = Device::whereIn('id', $id2)->select('code','id','title')->get()->toArray();
  215. $map2 = array_column($map2,null,'id');
  216. $unit = $receipt = [];
  217. foreach ($data as $value){
  218. if($value['type'] == ItemDetails::type_one) {
  219. $tmp = $map[$value['data_id']] ?? [];
  220. $unit[] = [
  221. 'type' => $value['type'],
  222. 'data_id' => $value['data_id'],
  223. 'data_title' => $tmp['title'],
  224. 'data_code' => $tmp['number'],
  225. ];
  226. }else{
  227. $tmp = $map2[$value['data_id']] ?? [];
  228. $receipt[] = [
  229. 'type' => $value['type'],
  230. 'data_id' => $value['data_id'],
  231. 'data_title' => $tmp['title'] ?? "",
  232. 'data_code' => $tmp['code'] ?? "",
  233. ];
  234. }
  235. }
  236. return [
  237. 'man_list' => $unit,
  238. 'device_list' => $receipt,
  239. ];
  240. }
  241. public function getItemMap($ids){
  242. $ids = array_filter((array)$ids);
  243. if (empty($ids)) return [];
  244. return Item::whereIn('id', $ids)
  245. ->select('id', 'title', 'code')
  246. ->get()
  247. ->keyBy('id')
  248. ->toArray();
  249. }
  250. public function itemDel($data){
  251. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  252. try {
  253. DB::beginTransaction();
  254. $time = time();
  255. Item::where('del_time',0)
  256. ->whereIn('id',$data['id'])
  257. ->update(['del_time' => $time]);
  258. ItemDetails::where('del_time',0)
  259. ->whereIn('item_id', $data['id'])
  260. ->update(['del_time' => $time]);
  261. DB::commit();
  262. }catch (\Exception $exception){
  263. DB::rollBack();
  264. return [false,$exception->getMessage()];
  265. }
  266. return [true, ''];
  267. }
  268. public function itemDetail($data, $user){
  269. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  270. $customer = Item::where('del_time',0)
  271. ->withCustomData($user)
  272. ->where('id',$data['id'])
  273. ->first();
  274. if(empty($customer)) return [false,'项目不存在或已被删除'];
  275. $customer->getFormattedCustomFields();// 自定义数据附件处理
  276. $customer = $customer->toArray();
  277. $customer['start_time'] = ! empty($customer['start_time']) ? date("Y-m-d", $customer['start_time']) : "";
  278. $customer['end_time'] = ! empty($customer['end_time']) ? date("Y-m-d", $customer['end_time']) : "";
  279. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
  280. $customer['charge_name'] = Employee::where('id',$customer['charge_id'])->value('title');
  281. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  282. $customer['state_title'] = Item::State_Type[$customer['state']] ?? '';
  283. $customer['priority_title'] = Tag::where('id', $customer['priority_id'])->value('title') ?? "";
  284. $details = $this->getDetail($data['id']);
  285. $customer = array_merge($customer, $details);
  286. return [true, $customer];
  287. }
  288. public function itemDetailBoard($data, $user){
  289. list($status, $msg) = $this->itemDetail($data, $user);
  290. if(! $status) return [false, $msg];
  291. $customer = $msg;
  292. //节点信息
  293. $customer['node_list'] = $this->itemDetailBoard($data, $user);
  294. //文件归档
  295. $customer['file_list'] = $this->getNodeFile($data, $user, $customer);
  296. return [true, $customer];
  297. }
  298. public function itemNodeBoard($data,$user){
  299. $model = ItemNode::TopAndEmployeeClear($user,$data);
  300. $list = $model->where('del_time',0)
  301. ->where('item_id', $data['id'])
  302. ->select('*')
  303. ->orderby('update_time', 'desc')
  304. ->orderby('id', 'desc')
  305. ->get()->toArray();
  306. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($list,'charge_id'), array_column($list,'crt_id'))));
  307. $tag = (new TagService())->getTagMap(array_unique(array_merge_recursive(array_column($list,'priority_id'),array_column($list,'node_id'))));
  308. foreach ($list as $key => $value){
  309. $list[$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  310. $list[$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  311. $list[$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  312. $list[$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  313. $list[$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  314. $list[$key]['state_title'] = ItemNode::State_Type[$value['state']] ?? "";
  315. $priority_tmp = $tag[$value['priority_id']] ?? [];
  316. $list[$key]['priority_title'] = $priority_tmp['title'] ?? '';
  317. $list[$key]['priority_code'] = $priority_tmp['code'] ?? '';
  318. $node_tmp = $tag[$value['node_id']] ?? [];
  319. $list[$key]['node_title'] = $node_tmp['title'] ?? '';
  320. $list[$key]['node_code'] = $node_tmp['code'] ?? '';
  321. $list[$key]['progress'] = rand(1, 100); //todo
  322. }
  323. return $list;
  324. }
  325. public function getNodeFile($data,$user, $item){
  326. $return = [];
  327. if(! empty($item['custom_fields'])){
  328. foreach ($item['custom_fields'] as $value){
  329. $return[] = [
  330. 'id' => $value['id'],
  331. 'url' => $value['field_value'],
  332. 'name' => $value['field_name'],
  333. 'show_url' => $value['field_value_show'],
  334. 'type_name' => '项目',
  335. 'type_name_2' => CustomFieldValue::type[CustomFieldValue::type_two],
  336. 'type' => 'custom_fields',
  337. ];
  338. }
  339. }
  340. $file = ItemFile::where('del_time',0)
  341. ->where('item_id', $data['id'])
  342. ->get()->toArray();
  343. if(! empty($file)){
  344. $fileUploadService = new FileUploadService();
  345. foreach ($file as $value){
  346. $return[] = [
  347. 'id' => $value['id'],
  348. 'url' => $value['url'],
  349. 'name' => $value['name'],
  350. 'show_url' => $fileUploadService->getFileShow($value['url']),
  351. 'type_name' => ItemFile::from[$value['from']],
  352. 'type_name_2' => ItemFile::type[$value['type']],
  353. 'type' => 'item_file',
  354. ];
  355. }
  356. }
  357. return $return;
  358. }
  359. public function itemCommon($data,$user, $field = []){
  360. if(empty($field)) $field = Item::$field;
  361. $model = Item::TopClear($user,$data);
  362. $model = $model->where('del_time',0)
  363. ->select($field)
  364. ->orderby('id', 'desc');
  365. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  366. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  367. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  368. if(! empty($data['state'])) $model->where('state', $data['state']);
  369. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  370. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  371. $model->where('crt_time','>=',$return[0]);
  372. $model->where('crt_time','<=',$return[1]);
  373. }
  374. return $model;
  375. }
  376. public function itemCommon1($data,$user, $field = []){
  377. if(empty($field)) $field = Item::$field;
  378. $model = Item::TopAndEmployeeClear($user,$data);
  379. $model = $model->where('del_time',0)
  380. ->select($field)
  381. ->orderby('id', 'desc');
  382. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  383. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  384. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  385. if(! empty($data['state'])) $model->where('state', $data['state']);
  386. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  387. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  388. $model->where('crt_time','>=',$return[0]);
  389. $model->where('crt_time','<=',$return[1]);
  390. }
  391. return $model;
  392. }
  393. public function itemList($data,$user){
  394. $select_tree_type = $user['select_tree_type'];
  395. if(empty($select_tree_type)){
  396. //工时
  397. $model = $this->itemCommon($data, $user);
  398. }else{
  399. //项目管理
  400. $model = $this->itemCommon1($data, $user);
  401. }
  402. $list = $this->limit($model,'',$data);
  403. $list = $this->fillData($list);
  404. return [true, $list];
  405. }
  406. public function itemRule(&$data, $user, $is_add = true){
  407. $data['top_depart_id'] = $user['top_depart_id'];
  408. if(empty($data['code'])) return [false, '项目编码不能为空'];
  409. if(empty($data['title'])) return [false, '项目名称不能为空'];
  410. if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
  411. if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
  412. $isMonthEnd = date('j', $data['end_time']) == date('t', $data['end_time']);
  413. if(! $isMonthEnd) return [false, '项目结束日期必须是当月最后一天'];
  414. if(empty($data['state'])) return [false, '项目状态不能为空'];
  415. if(! isset(Item::State_Type[$data['state']])) return [false, '项目状态不存在'];
  416. if(empty($data['man_list'])) return [false, '人员不能为空'];
  417. foreach ($data['man_list'] as $key => $value){
  418. if(empty($value['type'])) return [false, '类型不能为空'];
  419. if(empty($value['data_id'])) return [false, '人员不能为空'];
  420. $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  421. }
  422. list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
  423. if(! $status) return [false, $msg];
  424. if(empty($data['device_list'])) return [false, '设备不能为空'];
  425. if(isset($data['device_list'])){
  426. foreach ($data['device_list'] as $key => $value){
  427. if(empty($value['type'])) return [false, '类型不能为空'];
  428. if(empty($value['data_id'])) return [false, '设备ID不能为空'];
  429. $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  430. }
  431. }
  432. list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
  433. if(! $status) return [false, $msg];
  434. if(isset($data['budget'])){
  435. $res = $this->checkNumber($data['budget'],2,'non-negative');
  436. if(! $res['valid']) return [false,'预算:' . $res['error']];
  437. }
  438. if(! empty($data['item_attribute']) && ! isset(Item::Item_Attribute[$data['item_attribute']])) return [false, '项目属性不存在'];
  439. if($is_add){
  440. $bool = Item::where('code',$data['code'])
  441. ->where('top_depart_id', $data['top_depart_id'])
  442. ->where('del_time',0)
  443. ->exists();
  444. }else{
  445. if(empty($data['id'])) return [false,'ID不能为空'];
  446. $bool = Item::where('code',$data['code'])
  447. ->where('top_depart_id', $data['top_depart_id'])
  448. ->where('id','<>',$data['id'])
  449. ->where('del_time',0)
  450. ->exists();
  451. }
  452. if($bool) return [false, '项目编码已存在'];
  453. return [true, ''];
  454. }
  455. public function fillData($data){
  456. if(empty($data['data'])) return $data;
  457. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($data['data'],'charge_id'), array_column($data['data'],'crt_id'))));
  458. foreach ($data['data'] as $key => $value){
  459. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  460. $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  461. $data['data'][$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  462. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  463. $data['data'][$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  464. $data['data'][$key]['state_title'] = Item::State_Type[$value['state']] ?? "";
  465. }
  466. return $data;
  467. }
  468. /**
  469. * 填充项目导出数据(主表与明细平铺)
  470. */
  471. public function fillDataForExport($data, $column, $user, &$return)
  472. {
  473. if (empty($data)) return;
  474. $dataArray = is_array($data) ? $data : $data->toArray();
  475. $mainIds = array_column($dataArray, 'id');
  476. // 1. 获取详情映射 [item_id => [ [type_title=>..., code_2=>..., title=>...], ... ]]
  477. $detailsMap = $this->getDetailsMap($mainIds, $user);
  478. // 2. 获取主表状态映射
  479. $stateMap = \App\Model\Item::State_Type;
  480. $attrMap = \App\Model\Item::Item_Attribute;
  481. $empMap = Employee::whereIn('id', array_unique(array_column($dataArray,'charge_id')))->get()->keyBy('id');
  482. foreach ($dataArray as $main) {
  483. $itemId = $main['id'];
  484. $details = $detailsMap[$itemId] ?? [];
  485. // 3. 提取并格式化主表信息
  486. $mainInfo = $main;
  487. $mainInfo['state_title'] = $stateMap[$main['state'] ?? ''] ?? '';
  488. $mainInfo['item_attribute_title'] = $attrMap[$main['item_attribute'] ?? ''] ?? '';
  489. $tmpEmp = $empMap[$main['charge_id']] ?? null;
  490. $mainInfo['charge_number'] = $tmpEmp ? $tmpEmp->number : '';
  491. $mainInfo['charge_name'] = $tmpEmp ? $tmpEmp->title : '';
  492. // 日期格式化
  493. $mainInfo['start_time'] = !empty($main['start_time']) ? date('Y-m-d', $main['start_time']) : '';
  494. $mainInfo['end_time'] = !empty($main['end_time']) ? date('Y-m-d', $main['end_time']) : '';
  495. if (empty($details)) {
  496. // 如果单据没有明细,保底出一行
  497. $tempRow = [];
  498. foreach ($column as $col) {
  499. $tempRow[] = $mainInfo[$col] ?? '';
  500. }
  501. $return[] = $tempRow;
  502. } else {
  503. // 4. 核心平铺逻辑:每一行明细都带上主表信息
  504. foreach ($details as $sub) {
  505. // 合并主表数据和详情数据(sub 中包含 type_title, code_2, title 等)
  506. $fullRowData = array_merge($mainInfo, $sub);
  507. $tempRow = [];
  508. foreach ($column as $col) {
  509. $tempRow[] = $fullRowData[$col] ?? '';
  510. }
  511. $return[] = $tempRow;
  512. }
  513. }
  514. }
  515. }
  516. /**
  517. * 获取明细聚合映射表
  518. */
  519. public function getDetailsMap($mainIds, $user)
  520. {
  521. $details = ItemDetails::where('del_time', 0)
  522. ->whereIn('item_id', $mainIds)
  523. ->where('top_depart_id', $user['top_depart_id'])
  524. ->get();
  525. if ($details->isEmpty()) return [];
  526. // 1. 批量提取关联 ID
  527. $empIds = $details->where('type', ItemDetails::type_one)->pluck('data_id')->unique();
  528. $devIds = $details->where('type', ItemDetails::type_two)->pluck('data_id')->unique();
  529. // 2. 批量获取档案 Map
  530. $empMap = Employee::whereIn('id', $empIds)->get()->keyBy('id');
  531. $devMap = Device::whereIn('id', $devIds)->get()->keyBy('id');
  532. $typeNames = ItemDetails::$type_name;
  533. $res = [];
  534. foreach ($details as $item) {
  535. $detailRow = [];
  536. $detailRow['type_title'] = $typeNames[$item->type] ?? '';
  537. // 根据类型处理影子列 code_2 和 名称 title
  538. if ($item->type == ItemDetails::type_one) {
  539. $emp = $empMap[$item->data_id] ?? null;
  540. $detailRow['code_2'] = $emp ? $emp->number : '';
  541. $detailRow['title_2'] = $emp ? $emp->title : '';
  542. } else {
  543. $dev = $devMap[$item->data_id] ?? null;
  544. $detailRow['code_2'] = $dev ? $dev->code : '';
  545. $detailRow['title_2'] = $dev ? $dev->title : '';
  546. }
  547. // 归档到对应的主表 ID 下
  548. $res[$item->item_id][] = $detailRow;
  549. }
  550. return $res;
  551. }
  552. //项目节点
  553. public function itemNodeEdit($data,$user){
  554. list($status,$msg) = $this->itemNodeRule($data, $user, false);
  555. if(!$status) return [$status,$msg];
  556. try {
  557. DB::beginTransaction();
  558. $model = ItemNode::where('id', $data['id'])->first();
  559. $old_employee_id = $model->charge_id;
  560. $tableName = $model->getTable();
  561. $model->title = $data['title'] ?? '';
  562. $model->mark = $data['mark'] ?? "";
  563. $model->start_time = $data['start_time'] ?? 0;
  564. $model->end_time = $data['end_time'] ?? 0;
  565. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  566. $model->entrust_type = $data['entrust_type'] ?? 0;
  567. $model->charge_id = $data['charge_id'] ?? 0;
  568. $model->node_id = $data['node_id'] ?? 0;
  569. $model->node_weight = $data['node_weight'] ?? 0;
  570. $model->is_review_required = $data['is_review_required'] ?? 0;
  571. $model->review_id = $data['review_id'] ?? 0;
  572. $model->priority_id = $data['priority_id'] ?? 0;
  573. $model->save();
  574. $time = time();
  575. ItemNodeDetails::where('del_time',0)
  576. ->where('item_node_id', $model->id)
  577. ->update(['del_time' => $time]);
  578. $this->saveNodeDetail($model->id, $time, $data);
  579. // 人员项目节点表
  580. $this->saveNodeEmployee($model->id, $time, $data, $user, $old_employee_id);
  581. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  582. if (! $status) {
  583. DB::rollBack();
  584. return [false, $msg];
  585. }
  586. DB::commit();
  587. }catch (\Exception $exception){
  588. DB::rollBack();
  589. return [false,$exception->getMessage()];
  590. }
  591. return [true, ''];
  592. }
  593. public function itemNodeAdd($data,$user){
  594. list($status,$msg) = $this->itemNodeRule($data, $user);
  595. if(!$status) return [$status,$msg];
  596. try {
  597. DB::beginTransaction();
  598. $model = new ItemNode();
  599. $model->item_id = $data['item_id'] ?? 0;
  600. $tableName = $model->getTable();
  601. $model->code = $this->generateBillNo([
  602. 'top_depart_id' => $user['top_depart_id'],
  603. 'type' => ItemNode::Order_type,
  604. 'period' => date("Ym", time())
  605. ]);
  606. $model->title = $data['title'] ?? '';
  607. $model->mark = $data['mark'] ?? "";
  608. $model->start_time = $data['start_time'] ?? 0;
  609. $model->end_time = $data['end_time'] ?? 0;
  610. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  611. $model->entrust_type = $data['entrust_type'] ?? 0;
  612. $model->charge_id = $data['charge_id'] ?? 0;
  613. $model->node_id = $data['node_id'] ?? 0;
  614. $model->node_weight = $data['node_weight'] ?? 0;
  615. $model->is_review_required = $data['is_review_required'] ?? 0;
  616. $model->review_id = $data['review_id'] ?? 0;
  617. $model->priority_id = $data['priority_id'] ?? 0;
  618. $model->crt_id = $user['id'];
  619. $model->top_depart_id = $data['top_depart_id'];
  620. $model->save();
  621. $time = time();
  622. $this->saveNodeDetail($model->id, $time, $data);
  623. // 人员项目节点表
  624. $this->saveNodeEmployee($model->id, $time, $data, $user);
  625. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  626. if (!$status) {
  627. DB::rollBack();
  628. return [false, $msg];
  629. }
  630. DB::commit();
  631. }catch (\Exception $exception){
  632. DB::rollBack();
  633. return [false,$exception->getMessage()];
  634. }
  635. return [true, ''];
  636. }
  637. private function saveNodeEmployee($id, $time, $data, $user, $old_employee_id = 0){
  638. if($old_employee_id != $data['charge_id']){
  639. ItemNodeEmployee::where('del_time',0)
  640. ->where('item_node_id', $id)
  641. ->where('data_id', $old_employee_id)
  642. ->delete();
  643. ItemNodeEmployee::insert([
  644. 'item_node_id' => $id,
  645. 'item_id' => $data['item_id'],
  646. 'data_id' => $data['charge_id'],
  647. 'top_depart_id' => $user['top_depart_id'],
  648. 'crt_time' => $time
  649. ]);
  650. }
  651. }
  652. private function saveNodeDetail($id, $time, $data){
  653. if(! empty($data['man_list'])){
  654. $unit = [];
  655. foreach ($data['man_list'] as $value){
  656. $unit[] = [
  657. 'item_id' => $data['item_id'],
  658. 'item_node_id' => $id,
  659. 'type' => $value['type'],
  660. 'data_id' => $value['data_id'],
  661. 'crt_time' => $time,
  662. 'top_depart_id' => $value['top_depart_id'],
  663. ];
  664. }
  665. if(! empty($unit)) ItemNodeDetails::insert($unit);
  666. }
  667. if(! empty($data['device_list'])){
  668. $receipt = [];
  669. foreach ($data['device_list'] as $value){
  670. $receipt[] = [
  671. 'item_id' => $data['item_id'],
  672. 'item_node_id' => $id,
  673. 'type' => $value['type'],
  674. 'data_id' => $value['data_id'],
  675. 'crt_time' => $time,
  676. 'top_depart_id' => $value['top_depart_id'],
  677. ];
  678. }
  679. if(! empty($receipt)) ItemNodeDetails::insert($receipt);
  680. }
  681. }
  682. private function getNodeDetail($id){
  683. $data = ItemNodeDetails::where('del_time',0)
  684. ->where('item_node_id', $id)
  685. ->get()->toArray();
  686. $id = $id2 = [];
  687. foreach ($data as $value){
  688. if($value['type'] == ItemNodeDetails::type_one) {
  689. $id[] = $value['data_id'];
  690. }else{
  691. $id2[] = $value['data_id'];
  692. }
  693. }
  694. $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
  695. $map = array_column($map,null,'id');
  696. $map2 = Device::whereIn('id', $id2)->select('code','id','title')->get()->toArray();
  697. $map2 = array_column($map2,null,'id');
  698. $unit = $receipt = [];
  699. foreach ($data as $value){
  700. if($value['type'] == ItemNodeDetails::type_one) {
  701. $tmp = $map[$value['data_id']] ?? [];
  702. $unit[] = [
  703. 'type' => $value['type'],
  704. 'data_id' => $value['data_id'],
  705. 'data_title' => $tmp['title'],
  706. 'data_code' => $tmp['number'],
  707. ];
  708. }else{
  709. $tmp = $map2[$value['data_id']] ?? [];
  710. $receipt[] = [
  711. 'type' => $value['type'],
  712. 'data_id' => $value['data_id'],
  713. 'data_title' => $tmp['title'] ?? "",
  714. 'data_code' => $tmp['code'] ?? "",
  715. ];
  716. }
  717. }
  718. return [
  719. 'man_list' => $unit,
  720. 'device_list' => $receipt,
  721. ];
  722. }
  723. public function itemNodeDel($data){
  724. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  725. try {
  726. DB::beginTransaction();
  727. $time = time();
  728. ItemNode::where('del_time',0)
  729. ->whereIn('id',$data['id'])
  730. ->update(['del_time' => $time]);
  731. ItemNodeDetails::where('del_time',0)
  732. ->whereIn('item_node_id', $data['id'])
  733. ->update(['del_time' => $time]);
  734. DB::commit();
  735. }catch (\Exception $exception){
  736. DB::rollBack();
  737. return [false,$exception->getMessage()];
  738. }
  739. return [true, ''];
  740. }
  741. public function itemNodeDetail($data, $user){
  742. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  743. $customer = ItemNode::where('del_time',0)
  744. ->withCustomData($user)
  745. ->where('id',$data['id'])
  746. ->first();
  747. if(empty($customer)) return [false,'项目节点不存在或已被删除'];
  748. $customer->getFormattedCustomFields();// 自定义数据附件处理
  749. $customer = $customer->toArray();
  750. $customer['start_time'] = ! empty($customer['start_time']) ? date("Y-m-d", $customer['start_time']) : "";
  751. $customer['end_time'] = ! empty($customer['end_time']) ? date("Y-m-d", $customer['end_time']) : "";
  752. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
  753. $customer['charge_name'] = Employee::where('id',$customer['charge_id'])->value('title');
  754. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  755. $customer['state_title'] = ItemNode::State_Type[$customer['state']] ?? '';
  756. $tag = (new TagService())->getTagMap(array_unique([$customer['priority_id'], $customer['node_id'] ]));
  757. $priority_tmp = $tag[$customer['priority_id']] ?? [];
  758. $customer['priority_title'] = $priority_tmp['title'] ?? '';
  759. $customer['priority_code'] = $priority_tmp['code'] ?? '';
  760. $node_tmp = $tag[$customer['node_id']] ?? [];
  761. $customer['node_title'] = $node_tmp['title'] ?? '';
  762. $customer['node_code'] = $node_tmp['code'] ?? '';
  763. $details = $this->getNodeDetail($data['id']);
  764. $customer = array_merge($customer, $details);
  765. return [true, $customer];
  766. }
  767. public function itemNodeCommon($data,$user, $field = []){
  768. if(empty($field)) $field = ItemNode::$field;
  769. $model = ItemNode::TopAndEmployeeClear($user,$data);
  770. $model = $model->where('del_time',0)
  771. ->select($field)
  772. ->orderby('id', 'desc');
  773. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  774. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  775. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  776. if(isset($data['state'])) $model->where('state', $data['state']);
  777. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  778. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  779. $model->where('crt_time','>=',$return[0]);
  780. $model->where('crt_time','<=',$return[1]);
  781. }
  782. return $model;
  783. }
  784. public function itemNodeList($data,$user){
  785. $model = $this->itemNodeCommon($data, $user);
  786. $list = $this->limit($model,'',$data);
  787. $list = $this->fillNodeData($list);
  788. return [true, $list];
  789. }
  790. public function itemNodeRule(&$data, $user, $is_add = true){
  791. $data['top_depart_id'] = $user['top_depart_id'];
  792. if(empty($data['item_id'])) return [false, '项目ID不能为空'];
  793. $item = Item::where('id', $data['item_id'])->where('del_time',0)->first();
  794. if(empty($item)) return [false, '项目不存在或已被删除'];
  795. $item = $item->toArray();
  796. if(empty($data['title'])) return [false, '节点名称不能为空'];
  797. if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
  798. if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
  799. $itemStartTime = $item['start_time'];
  800. $itemEndTime = $item['end_time'];
  801. if (!empty($data['start_time'])) {
  802. $inputStartTime = $data['start_time'];
  803. if ($itemStartTime > 0 && $inputStartTime < $itemStartTime) {
  804. return [false, '节点开始时间不能早于项目开始时间:' . date('Y-m-d', $itemStartTime)];
  805. }
  806. }
  807. if (!empty($data['end_time'])) {
  808. $inputEndTime = $data['end_time'];
  809. if ($itemEndTime > 0 && $inputEndTime > $itemEndTime) {
  810. return [false, '节点结束时间不能晚于项目结束时间:' . date('Y-m-d', $itemEndTime)];
  811. }
  812. }
  813. if(! empty($data['man_list'])) {
  814. foreach ($data['man_list'] as $key => $value){
  815. if(empty($value['type'])) return [false, '类型不能为空'];
  816. if(empty($value['data_id'])) return [false, '人员不能为空'];
  817. $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  818. }
  819. list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
  820. if(! $status) return [false, $msg];
  821. }
  822. if(! empty($data['device_list'])) {
  823. foreach ($data['device_list'] as $key => $value){
  824. if(empty($value['type'])) return [false, '类型不能为空'];
  825. if(empty($value['data_id'])) return [false, '设备ID不能为空'];
  826. $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  827. }
  828. list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
  829. if(! $status) return [false, $msg];
  830. }
  831. if($is_add){
  832. $bool = ItemNode::where('item_id',$data['item_id'])
  833. ->where('top_depart_id', $data['top_depart_id'])
  834. ->where('title', $data['title'])
  835. ->where('del_time',0)
  836. ->exists();
  837. }else{
  838. if(empty($data['id'])) return [false,'ID不能为空'];
  839. $bool = ItemNode::where('title', $data['title'])
  840. ->where('item_id',$data['item_id'])
  841. ->where('top_depart_id', $data['top_depart_id'])
  842. ->where('id','<>',$data['id'])
  843. ->where('del_time',0)
  844. ->exists();
  845. }
  846. if($bool) return [false, '该项目下节点名称已存在'];
  847. return [true, ''];
  848. }
  849. public function fillNodeData($data){
  850. if(empty($data['data'])) return $data;
  851. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($data['data'],'charge_id'), array_column($data['data'],'crt_id'))));
  852. $tag = (new TagService())->getTagMap(array_unique(array_merge_recursive(array_column($data['data'],'priority_id'),array_column($data['data'],'node_id'))));
  853. foreach ($data['data'] as $key => $value){
  854. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  855. $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  856. $data['data'][$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  857. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  858. $data['data'][$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  859. $data['data'][$key]['state_title'] = ItemNode::State_Type[$value['state']] ?? "";
  860. $priority_tmp = $tag[$value['priority_id']] ?? [];
  861. $data['data'][$key]['priority_title'] = $priority_tmp['title'] ?? '';
  862. $data['data'][$key]['priority_code'] = $priority_tmp['code'] ?? '';
  863. $node_tmp = $tag[$value['node_id']] ?? [];
  864. $data['data'][$key]['node_title'] = $node_tmp['title'] ?? '';
  865. $data['data'][$key]['node_code'] = $node_tmp['code'] ?? '';
  866. }
  867. return $data;
  868. }
  869. //项目节点任务
  870. public function itemNodeMissionEdit($data,$user){
  871. list($status,$msg) = $this->itemNodeMissionRule($data, $user, false);
  872. if(!$status) return [$status,$msg];
  873. try {
  874. DB::beginTransaction();
  875. $model = ItemNodeMission::where('id', $data['id'])->first();
  876. $old_employee_id = $model->charge_id;
  877. $tableName = $model->getTable();
  878. $model->title = $data['title'] ?? '';
  879. $model->mark = $data['mark'] ?? "";
  880. $model->start_time = $data['start_time'] ?? 0;
  881. $model->end_time = $data['end_time'] ?? 0;
  882. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  883. $model->entrust_type = $data['entrust_type'] ?? 0;
  884. $model->charge_id = $data['charge_id'] ?? 0;
  885. $model->mission_id = $data['mission_id'] ?? 0;
  886. $model->mission_weight = $data['mission_weight'] ?? 0;
  887. $model->is_review_required = $data['is_review_required'] ?? 0;
  888. $model->review_id = $data['review_id'] ?? 0;
  889. $model->priority_id = $data['priority_id'] ?? 0;
  890. $model->save();
  891. $time = time();
  892. ItemNodeMissionDetails::where('del_time',0)
  893. ->where('item_node_mission_id', $model->id)
  894. ->update(['del_time' => $time]);
  895. $this->saveNodeMissionDetail($model->id, $time, $data);
  896. // 人员项目节点任务表
  897. $this->saveNodeMissionEmployee($model->id, $time, $data, $user, $old_employee_id);
  898. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  899. if (! $status) {
  900. DB::rollBack();
  901. return [false, $msg];
  902. }
  903. DB::commit();
  904. }catch (\Exception $exception){
  905. DB::rollBack();
  906. return [false,$exception->getMessage()];
  907. }
  908. return [true, ''];
  909. }
  910. public function itemNodeMissionAdd($data,$user){
  911. list($status,$msg) = $this->itemNodeMissionRule($data, $user);
  912. if(!$status) return [$status,$msg];
  913. try {
  914. DB::beginTransaction();
  915. $model = new ItemNodeMission();
  916. $model->item_id = $data['item_id'] ?? 0;
  917. $tableName = $model->getTable();
  918. $model->code = $this->generateBillNo([
  919. 'top_depart_id' => $user['top_depart_id'],
  920. 'type' => ItemNodeMission::Order_type,
  921. 'period' => date("Ym", time())
  922. ]);
  923. $model->title = $data['title'] ?? '';
  924. $model->mark = $data['mark'] ?? "";
  925. $model->start_time = $data['start_time'] ?? 0;
  926. $model->end_time = $data['end_time'] ?? 0;
  927. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  928. $model->entrust_type = $data['entrust_type'] ?? 0;
  929. $model->charge_id = $data['charge_id'] ?? 0;
  930. $model->mission_id = $data['mission_id'] ?? 0;
  931. $model->mission_weight = $data['mission_weight'] ?? 0;
  932. $model->is_review_required = $data['is_review_required'] ?? 0;
  933. $model->review_id = $data['review_id'] ?? 0;
  934. $model->priority_id = $data['priority_id'] ?? 0;
  935. $model->crt_id = $user['id'];
  936. $model->top_depart_id = $data['top_depart_id'];
  937. $model->save();
  938. $time = time();
  939. $this->saveNodeMissionDetail($model->id, $time, $data);
  940. // 人员项目节点任务表
  941. $this->saveNodeMissionEmployee($model->id, $time, $data, $user);
  942. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  943. if (!$status) {
  944. DB::rollBack();
  945. return [false, $msg];
  946. }
  947. DB::commit();
  948. }catch (\Exception $exception){
  949. DB::rollBack();
  950. return [false,$exception->getMessage()];
  951. }
  952. return [true, ''];
  953. }
  954. private function saveNodeMissionEmployee($id, $time, $data, $user, $old_employee_id = 0){
  955. if($old_employee_id != $data['charge_id']){
  956. ItemNodeMissionEmployee::where('del_time',0)
  957. ->where('item_node_mission_id', $id)
  958. ->where('data_id', $old_employee_id)
  959. ->delete();
  960. ItemNodeMissionEmployee::insert([
  961. 'item_node_mission_id' => $id,
  962. 'item_node_id' => $data['item_node_id'],
  963. 'item_id' => $data['item_id'],
  964. 'data_id' => $data['charge_id'],
  965. 'top_depart_id' => $user['top_depart_id'],
  966. 'crt_time' => $time
  967. ]);
  968. }
  969. }
  970. private function saveNodeMissionDetail($id, $time, $data){
  971. if(! empty($data['man_list'])){
  972. $unit = [];
  973. foreach ($data['man_list'] as $value){
  974. $unit[] = [
  975. 'item_id' => $data['item_id'],
  976. 'item_node_id' => $data['item_node_id'],
  977. 'item_node_mission_id' => $id,
  978. 'type' => $value['type'],
  979. 'data_id' => $value['data_id'],
  980. 'crt_time' => $time,
  981. 'top_depart_id' => $value['top_depart_id'],
  982. ];
  983. }
  984. if(! empty($unit)) ItemNodeMissionDetails::insert($unit);
  985. }
  986. if(! empty($data['device_list'])){
  987. $receipt = [];
  988. foreach ($data['device_list'] as $value){
  989. $receipt[] = [
  990. 'item_id' => $data['item_id'],
  991. 'item_node_id' => $data['item_node_id'],
  992. 'item_node_mission_id' => $id,
  993. 'type' => $value['type'],
  994. 'data_id' => $value['data_id'],
  995. 'crt_time' => $time,
  996. 'top_depart_id' => $value['top_depart_id'],
  997. ];
  998. }
  999. if(! empty($receipt)) ItemNodeMissionDetails::insert($receipt);
  1000. }
  1001. }
  1002. private function getNodeMissionDetail($id){
  1003. $data = ItemNodeMissionDetails::where('del_time',0)
  1004. ->where('item_node_mission_id', $id)
  1005. ->get()->toArray();
  1006. $id = $id2 = [];
  1007. foreach ($data as $value){
  1008. if($value['type'] == ItemNodeMissionDetails::type_one) {
  1009. $id[] = $value['data_id'];
  1010. }else{
  1011. $id2[] = $value['data_id'];
  1012. }
  1013. }
  1014. $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
  1015. $map = array_column($map,null,'id');
  1016. $map2 = Device::whereIn('id', $id2)->select('code','id','title')->get()->toArray();
  1017. $map2 = array_column($map2,null,'id');
  1018. $unit = $receipt = [];
  1019. foreach ($data as $value){
  1020. if($value['type'] == ItemNodeMissionDetails::type_one) {
  1021. $tmp = $map[$value['data_id']] ?? [];
  1022. $unit[] = [
  1023. 'type' => $value['type'],
  1024. 'data_id' => $value['data_id'],
  1025. 'data_title' => $tmp['title'],
  1026. 'data_code' => $tmp['number'],
  1027. ];
  1028. }else{
  1029. $tmp = $map2[$value['data_id']] ?? [];
  1030. $receipt[] = [
  1031. 'type' => $value['type'],
  1032. 'data_id' => $value['data_id'],
  1033. 'data_title' => $tmp['title'] ?? "",
  1034. 'data_code' => $tmp['code'] ?? "",
  1035. ];
  1036. }
  1037. }
  1038. return [
  1039. 'man_list' => $unit,
  1040. 'device_list' => $receipt,
  1041. ];
  1042. }
  1043. public function itemNodeMissionDel($data){
  1044. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  1045. try {
  1046. DB::beginTransaction();
  1047. $time = time();
  1048. ItemNodeMission::where('del_time',0)
  1049. ->whereIn('id',$data['id'])
  1050. ->update(['del_time' => $time]);
  1051. ItemNodeMissionDetails::where('del_time',0)
  1052. ->whereIn('item_node_mission_id', $data['id'])
  1053. ->update(['del_time' => $time]);
  1054. DB::commit();
  1055. }catch (\Exception $exception){
  1056. DB::rollBack();
  1057. return [false,$exception->getMessage()];
  1058. }
  1059. return [true, ''];
  1060. }
  1061. public function itemNodeMissionDetail($data, $user){
  1062. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  1063. $customer = ItemNodeMission::where('del_time',0)
  1064. ->withCustomData($user)
  1065. ->where('id',$data['id'])
  1066. ->first();
  1067. if(empty($customer)) return [false,'项目节点任务不存在或已被删除'];
  1068. $customer->getFormattedCustomFields();// 自定义数据附件处理
  1069. $customer = $customer->toArray();
  1070. $customer['start_time'] = ! empty($customer['start_time']) ? date("Y-m-d", $customer['start_time']) : "";
  1071. $customer['end_time'] = ! empty($customer['end_time']) ? date("Y-m-d", $customer['end_time']) : "";
  1072. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
  1073. $customer['charge_name'] = Employee::where('id',$customer['charge_id'])->value('title');
  1074. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  1075. $customer['state_title'] = ItemNodeMission::State_Type[$customer['state']] ?? '';
  1076. $tag = (new TagService())->getTagMap(array_unique([$customer['priority_id'], $customer['mission_id'] ]));
  1077. $priority_tmp = $tag[$customer['priority_id']] ?? [];
  1078. $customer['priority_title'] = $priority_tmp['title'] ?? '';
  1079. $customer['priority_code'] = $priority_tmp['code'] ?? '';
  1080. $node_tmp = $tag[$customer['mission_id']] ?? [];
  1081. $customer['mission_title'] = $node_tmp['title'] ?? '';
  1082. $customer['mission_code'] = $node_tmp['code'] ?? '';
  1083. $details = $this->getNodeMissionDetail($data['id']);
  1084. $customer = array_merge($customer, $details);
  1085. return [true, $customer];
  1086. }
  1087. public function itemNodeMissionCommon($data,$user, $field = []){
  1088. if(empty($field)) $field = ItemNodeMission::$field;
  1089. $model = ItemNodeMission::TopAndEmployeeClear($user,$data);
  1090. $model = $model->where('del_time',0)
  1091. ->select($field)
  1092. ->orderby('id', 'desc');
  1093. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  1094. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  1095. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  1096. if(isset($data['state'])) $model->where('state', $data['state']);
  1097. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  1098. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  1099. $model->where('crt_time','>=',$return[0]);
  1100. $model->where('crt_time','<=',$return[1]);
  1101. }
  1102. return $model;
  1103. }
  1104. public function itemNodeMissionList($data,$user){
  1105. $model = $this->itemNodeMissionCommon($data, $user);
  1106. $list = $this->limit($model,'',$data);
  1107. $list = $this->fillNodeMissionData($list);
  1108. return [true, $list];
  1109. }
  1110. public function itemNodeMissionRule(&$data, $user, $is_add = true){
  1111. $data['top_depart_id'] = $user['top_depart_id'];
  1112. if(empty($data['item_node_id'])) return [false, '项目节点ID不能为空'];
  1113. $item = ItemNode::where('id', $data['item_node_id'])->where('del_time',0)->first();
  1114. if(empty($item)) return [false, '项目节点不存在或已被删除'];
  1115. $item = $item->toArray();
  1116. $data['item_id'] = $item['item_id'];
  1117. if(empty($data['title'])) return [false, '任务名称不能为空'];
  1118. if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
  1119. if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
  1120. $itemStartTime = $item['start_time'];
  1121. $itemEndTime = $item['end_time'];
  1122. if (!empty($data['start_time'])) {
  1123. $inputStartTime = $data['start_time'];
  1124. if ($itemStartTime > 0 && $inputStartTime < $itemStartTime) {
  1125. return [false, '任务开始时间不能早于项目节点开始时间:' . date('Y-m-d', $itemStartTime)];
  1126. }
  1127. }
  1128. if (!empty($data['end_time'])) {
  1129. $inputEndTime = $data['end_time'];
  1130. if ($itemEndTime > 0 && $inputEndTime > $itemEndTime) {
  1131. return [false, '任务结束时间不能晚于项目节点结束时间:' . date('Y-m-d', $itemEndTime)];
  1132. }
  1133. }
  1134. if(! empty($data['man_list'])) {
  1135. foreach ($data['man_list'] as $key => $value){
  1136. if(empty($value['type'])) return [false, '类型不能为空'];
  1137. if(empty($value['data_id'])) return [false, '人员不能为空'];
  1138. $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  1139. }
  1140. list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
  1141. if(! $status) return [false, $msg];
  1142. }
  1143. if(! empty($data['device_list'])) {
  1144. foreach ($data['device_list'] as $key => $value){
  1145. if(empty($value['type'])) return [false, '类型不能为空'];
  1146. if(empty($value['data_id'])) return [false, '设备ID不能为空'];
  1147. $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  1148. }
  1149. list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
  1150. if(! $status) return [false, $msg];
  1151. }
  1152. if($is_add){
  1153. $bool = ItemNodeMission::where('item_node_id',$data['item_node_id'])
  1154. ->where('top_depart_id', $data['top_depart_id'])
  1155. ->where('title', $data['title'])
  1156. ->where('del_time',0)
  1157. ->exists();
  1158. }else{
  1159. if(empty($data['id'])) return [false,'ID不能为空'];
  1160. $bool = ItemNodeMission::where('title', $data['title'])
  1161. ->where('item_node_id',$data['item_node_id'])
  1162. ->where('top_depart_id', $data['top_depart_id'])
  1163. ->where('id','<>',$data['id'])
  1164. ->where('del_time',0)
  1165. ->exists();
  1166. }
  1167. if($bool) return [false, '该项目节点下任务名称已存在'];
  1168. return [true, ''];
  1169. }
  1170. public function fillNodeMissionData($data){
  1171. if(empty($data['data'])) return $data;
  1172. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($data['data'],'charge_id'), array_column($data['data'],'crt_id'))));
  1173. $tag = (new TagService())->getTagMap(array_unique(array_merge_recursive(array_column($data['data'],'priority_id'),array_column($data['data'],'mission_id'))));
  1174. foreach ($data['data'] as $key => $value){
  1175. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  1176. $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  1177. $data['data'][$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  1178. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  1179. $data['data'][$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  1180. $data['data'][$key]['state_title'] = ItemNode::State_Type[$value['state']] ?? "";
  1181. $priority_tmp = $tag[$value['priority_id']] ?? [];
  1182. $data['data'][$key]['priority_title'] = $priority_tmp['title'] ?? '';
  1183. $data['data'][$key]['priority_code'] = $priority_tmp['code'] ?? '';
  1184. $node_tmp = $tag[$value['mission_id']] ?? [];
  1185. $data['data'][$key]['mission_title'] = $node_tmp['title'] ?? '';
  1186. $data['data'][$key]['mission_code'] = $node_tmp['code'] ?? '';
  1187. }
  1188. return $data;
  1189. }
  1190. }