ItemService.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <?php
  2. namespace App\Service;
  3. use App\Model\Device;
  4. use App\Model\Employee;
  5. use App\Model\Item;
  6. use App\Model\ItemDetails;
  7. use App\Model\ItemNode;
  8. use App\Model\ItemNodeDetails;
  9. use App\Model\Tag;
  10. use App\Model\SysMenu;
  11. use Illuminate\Support\Facades\DB;
  12. class ItemService extends Service
  13. {
  14. public function itemEdit($data,$user){
  15. list($status,$msg) = $this->itemRule($data, $user, false);
  16. if(!$status) return [$status,$msg];
  17. try {
  18. DB::beginTransaction();
  19. $model = Item::where('id', $data['id'])->first();
  20. $tableName = $model->getTable();
  21. $model->code = $data['code'] ?? '';
  22. $model->title = $data['title'] ?? '';
  23. $model->mark = $data['mark'] ?? "";
  24. $model->start_time = $data['start_time'] ?? 0;
  25. $model->end_time = $data['end_time'] ?? 0;
  26. $model->state = $data['state'] ?? 0;
  27. $model->budget = $data['budget'] ?? 0;
  28. $model->charge_id = $data['charge_id'] ?? 0;
  29. $model->field = $data['field'] ?? "";
  30. $model->item_attribute = $data['item_attribute'] ?? 0;
  31. //项目管理的字段
  32. if($user['select_tree_type'] == SysMenu::tree_type_one){
  33. $model->is_review_required = $data['is_review_required'] ?? 0;
  34. $model->review_id = $data['review_id'] ?? 0;
  35. $model->priority_id = $data['priority_id'] ?? 0;
  36. }
  37. $model->save();
  38. $time = time();
  39. ItemDetails::where('del_time',0)
  40. ->where('item_id', $model->id)
  41. ->update(['del_time' => $time]);
  42. $this->saveDetail($model->id, $time, $data);
  43. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  44. if (! $status) {
  45. DB::rollBack();
  46. return [false, $msg];
  47. }
  48. DB::commit();
  49. }catch (\Exception $exception){
  50. DB::rollBack();
  51. return [false,$exception->getMessage()];
  52. }
  53. return [true, ''];
  54. }
  55. public function itemAdd($data,$user){
  56. list($status,$msg) = $this->itemRule($data, $user);
  57. if(!$status) return [$status,$msg];
  58. try {
  59. DB::beginTransaction();
  60. $model = new Item();
  61. $tableName = $model->getTable();
  62. $model->code = $data['code'] ?? '';
  63. $model->title = $data['title'] ?? '';
  64. $model->mark = $data['mark'] ?? "";
  65. $model->start_time = $data['start_time'] ?? 0;
  66. $model->end_time = $data['end_time'] ?? 0;
  67. $model->state = $data['state'] ?? 0;
  68. $model->budget = $data['budget'] ?? 0;
  69. $model->charge_id = $data['charge_id'] ?? 0;
  70. $model->field = $data['field'] ?? "";
  71. $model->item_attribute = $data['item_attribute'] ?? 0;
  72. $model->is_review_required = $data['is_review_required'] ?? 0;
  73. $model->review_id = $data['review_id'] ?? 0;
  74. $model->priority_id = $data['priority_id'] ?? 0;
  75. $model->crt_id = $user['id'];
  76. $model->top_depart_id = $data['top_depart_id'];
  77. $model->save();
  78. $this->saveDetail($model->id, time(), $data);
  79. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  80. if (!$status) {
  81. DB::rollBack();
  82. return [false, $msg];
  83. }
  84. DB::commit();
  85. }catch (\Exception $exception){
  86. DB::rollBack();
  87. return [false,$exception->getMessage()];
  88. }
  89. return [true, ''];
  90. }
  91. private function saveDetail($id, $time, $data){
  92. if(! empty($data['man_list'])){
  93. $unit = [];
  94. foreach ($data['man_list'] as $value){
  95. $unit[] = [
  96. 'item_id' => $id,
  97. 'type' => $value['type'],
  98. 'data_id' => $value['data_id'],
  99. 'crt_time' => $time,
  100. 'top_depart_id' => $value['top_depart_id'],
  101. ];
  102. }
  103. if(! empty($unit)) ItemDetails::insert($unit);
  104. }
  105. if(! empty($data['device_list'])){
  106. $receipt = [];
  107. foreach ($data['device_list'] as $value){
  108. $receipt[] = [
  109. 'item_id' => $id,
  110. 'type' => $value['type'],
  111. 'data_id' => $value['data_id'],
  112. 'crt_time' => $time,
  113. 'top_depart_id' => $value['top_depart_id'],
  114. ];
  115. }
  116. if(! empty($receipt)) ItemDetails::insert($receipt);
  117. }
  118. }
  119. private function getDetail($id){
  120. $data = ItemDetails::where('del_time',0)
  121. ->where('item_id', $id)
  122. ->get()->toArray();
  123. $id = $id2 = [];
  124. foreach ($data as $value){
  125. if($value['type'] == ItemDetails::type_one) {
  126. $id[] = $value['data_id'];
  127. }else{
  128. $id2[] = $value['data_id'];
  129. }
  130. }
  131. $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
  132. $map = array_column($map,null,'id');
  133. $map2 = Device::whereIn('id', $id2)->select('code','id','title')->get()->toArray();
  134. $map2 = array_column($map2,null,'id');
  135. $unit = $receipt = [];
  136. foreach ($data as $value){
  137. if($value['type'] == ItemDetails::type_one) {
  138. $tmp = $map[$value['data_id']] ?? [];
  139. $unit[] = [
  140. 'type' => $value['type'],
  141. 'data_id' => $value['data_id'],
  142. 'data_title' => $tmp['title'],
  143. 'data_code' => $tmp['number'],
  144. ];
  145. }else{
  146. $tmp = $map2[$value['data_id']] ?? [];
  147. $receipt[] = [
  148. 'type' => $value['type'],
  149. 'data_id' => $value['data_id'],
  150. 'data_title' => $tmp['title'] ?? "",
  151. 'data_code' => $tmp['code'] ?? "",
  152. ];
  153. }
  154. }
  155. return [
  156. 'man_list' => $unit,
  157. 'device_list' => $receipt,
  158. ];
  159. }
  160. public function getItemMap($ids){
  161. $ids = array_filter((array)$ids);
  162. if (empty($ids)) return [];
  163. return Item::whereIn('id', $ids)
  164. ->select('id', 'title', 'code')
  165. ->get()
  166. ->keyBy('id')
  167. ->toArray();
  168. }
  169. public function itemDel($data){
  170. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  171. try {
  172. DB::beginTransaction();
  173. $time = time();
  174. Item::where('del_time',0)
  175. ->whereIn('id',$data['id'])
  176. ->update(['del_time' => $time]);
  177. ItemDetails::where('del_time',0)
  178. ->whereIn('item_id', $data['id'])
  179. ->update(['del_time' => $time]);
  180. DB::commit();
  181. }catch (\Exception $exception){
  182. DB::rollBack();
  183. return [false,$exception->getMessage()];
  184. }
  185. return [true, ''];
  186. }
  187. public function itemDetail($data, $user){
  188. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  189. $customer = Item::where('del_time',0)
  190. ->withCustomData($user)
  191. ->where('id',$data['id'])
  192. ->first();
  193. if(empty($customer)) return [false,'项目不存在或已被删除'];
  194. $customer->getFormattedCustomFields();// 自定义数据附件处理
  195. $customer = $customer->toArray();
  196. $customer['start_time'] = ! empty($customer['start_time']) ? date("Y-m-d", $customer['start_time']) : "";
  197. $customer['end_time'] = ! empty($customer['end_time']) ? date("Y-m-d", $customer['end_time']) : "";
  198. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
  199. $customer['charge_name'] = Employee::where('id',$customer['charge_id'])->value('title');
  200. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  201. $customer['state_title'] = Item::State_Type[$customer['state']] ?? '';
  202. $customer['priority_title'] = Tag::where('id', $customer['priority_id'])->value('title') ?? "";
  203. $details = $this->getDetail($data['id']);
  204. $customer = array_merge($customer, $details);
  205. return [true, $customer];
  206. }
  207. public function itemCommon($data,$user, $field = []){
  208. if(empty($field)) $field = Item::$field;
  209. $model = Item::TopClear($user,$data);
  210. $model = $model->where('del_time',0)
  211. // ->withCustomData($user)
  212. ->select($field)
  213. ->orderby('id', 'desc');
  214. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  215. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  216. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  217. if(! empty($data['state'])) $model->where('state', $data['state']);
  218. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  219. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  220. $model->where('crt_time','>=',$return[0]);
  221. $model->where('crt_time','<=',$return[1]);
  222. }
  223. return $model;
  224. }
  225. public function itemList($data,$user){
  226. $model = $this->itemCommon($data, $user);
  227. $list = $this->limit($model,'',$data);
  228. $list = $this->fillData($list);
  229. return [true, $list];
  230. }
  231. public function itemRule(&$data, $user, $is_add = true){
  232. $data['top_depart_id'] = $user['top_depart_id'];
  233. if(empty($data['code'])) return [false, '项目编码不能为空'];
  234. if(empty($data['title'])) return [false, '项目名称不能为空'];
  235. if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
  236. if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
  237. $isMonthEnd = date('j', $data['end_time']) == date('t', $data['end_time']);
  238. if(! $isMonthEnd) return [false, '项目结束日期必须是当月最后一天'];
  239. if(empty($data['state'])) return [false, '项目状态不能为空'];
  240. if(! isset(Item::State_Type[$data['state']])) return [false, '项目状态不存在'];
  241. if(empty($data['man_list'])) return [false, '人员不能为空'];
  242. foreach ($data['man_list'] as $key => $value){
  243. if(empty($value['type'])) return [false, '类型不能为空'];
  244. if(empty($value['data_id'])) return [false, '人员不能为空'];
  245. $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  246. }
  247. list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
  248. if(! $status) return [false, $msg];
  249. if(empty($data['device_list'])) return [false, '设备不能为空'];
  250. if(isset($data['device_list'])){
  251. foreach ($data['device_list'] as $key => $value){
  252. if(empty($value['type'])) return [false, '类型不能为空'];
  253. if(empty($value['data_id'])) return [false, '设备ID不能为空'];
  254. $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  255. }
  256. }
  257. list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
  258. if(! $status) return [false, $msg];
  259. if(isset($data['budget'])){
  260. $res = $this->checkNumber($data['budget'],2,'non-negative');
  261. if(! $res['valid']) return [false,'预算:' . $res['error']];
  262. }
  263. if(! empty($data['item_attribute']) && ! isset(Item::Item_Attribute[$data['item_attribute']])) return [false, '项目属性不存在'];
  264. if($is_add){
  265. $bool = Item::where('code',$data['code'])
  266. ->where('top_depart_id', $data['top_depart_id'])
  267. ->where('del_time',0)
  268. ->exists();
  269. }else{
  270. if(empty($data['id'])) return [false,'ID不能为空'];
  271. $bool = Item::where('code',$data['code'])
  272. ->where('top_depart_id', $data['top_depart_id'])
  273. ->where('id','<>',$data['id'])
  274. ->where('del_time',0)
  275. ->exists();
  276. }
  277. if($bool) return [false, '项目编码已存在'];
  278. return [true, ''];
  279. }
  280. public function fillData($data){
  281. if(empty($data['data'])) return $data;
  282. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($data['data'],'charge_id'), array_column($data['data'],'crt_id'))));
  283. foreach ($data['data'] as $key => $value){
  284. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  285. $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  286. $data['data'][$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  287. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  288. $data['data'][$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  289. $data['data'][$key]['state_title'] = Item::State_Type[$value['state']] ?? "";
  290. }
  291. return $data;
  292. }
  293. /**
  294. * 填充项目导出数据(主表与明细平铺)
  295. */
  296. public function fillDataForExport($data, $column, $user, &$return)
  297. {
  298. if (empty($data)) return;
  299. $dataArray = is_array($data) ? $data : $data->toArray();
  300. $mainIds = array_column($dataArray, 'id');
  301. // 1. 获取详情映射 [item_id => [ [type_title=>..., code_2=>..., title=>...], ... ]]
  302. $detailsMap = $this->getDetailsMap($mainIds, $user);
  303. // 2. 获取主表状态映射
  304. $stateMap = \App\Model\Item::State_Type;
  305. $attrMap = \App\Model\Item::Item_Attribute;
  306. $empMap = Employee::whereIn('id', array_unique(array_column($dataArray,'charge_id')))->get()->keyBy('id');
  307. foreach ($dataArray as $main) {
  308. $itemId = $main['id'];
  309. $details = $detailsMap[$itemId] ?? [];
  310. // 3. 提取并格式化主表信息
  311. $mainInfo = $main;
  312. $mainInfo['state_title'] = $stateMap[$main['state'] ?? ''] ?? '';
  313. $mainInfo['item_attribute_title'] = $attrMap[$main['item_attribute'] ?? ''] ?? '';
  314. $tmpEmp = $empMap[$main['charge_id']] ?? null;
  315. $mainInfo['charge_number'] = $tmpEmp ? $tmpEmp->number : '';
  316. $mainInfo['charge_name'] = $tmpEmp ? $tmpEmp->title : '';
  317. // 日期格式化
  318. $mainInfo['start_time'] = !empty($main['start_time']) ? date('Y-m-d', $main['start_time']) : '';
  319. $mainInfo['end_time'] = !empty($main['end_time']) ? date('Y-m-d', $main['end_time']) : '';
  320. if (empty($details)) {
  321. // 如果单据没有明细,保底出一行
  322. $tempRow = [];
  323. foreach ($column as $col) {
  324. $tempRow[] = $mainInfo[$col] ?? '';
  325. }
  326. $return[] = $tempRow;
  327. } else {
  328. // 4. 核心平铺逻辑:每一行明细都带上主表信息
  329. foreach ($details as $sub) {
  330. // 合并主表数据和详情数据(sub 中包含 type_title, code_2, title 等)
  331. $fullRowData = array_merge($mainInfo, $sub);
  332. $tempRow = [];
  333. foreach ($column as $col) {
  334. $tempRow[] = $fullRowData[$col] ?? '';
  335. }
  336. $return[] = $tempRow;
  337. }
  338. }
  339. }
  340. }
  341. /**
  342. * 获取明细聚合映射表
  343. */
  344. public function getDetailsMap($mainIds, $user)
  345. {
  346. $details = ItemDetails::where('del_time', 0)
  347. ->whereIn('item_id', $mainIds)
  348. ->where('top_depart_id', $user['top_depart_id'])
  349. ->get();
  350. if ($details->isEmpty()) return [];
  351. // 1. 批量提取关联 ID
  352. $empIds = $details->where('type', ItemDetails::type_one)->pluck('data_id')->unique();
  353. $devIds = $details->where('type', ItemDetails::type_two)->pluck('data_id')->unique();
  354. // 2. 批量获取档案 Map
  355. $empMap = Employee::whereIn('id', $empIds)->get()->keyBy('id');
  356. $devMap = Device::whereIn('id', $devIds)->get()->keyBy('id');
  357. $typeNames = ItemDetails::$type_name;
  358. $res = [];
  359. foreach ($details as $item) {
  360. $detailRow = [];
  361. $detailRow['type_title'] = $typeNames[$item->type] ?? '';
  362. // 根据类型处理影子列 code_2 和 名称 title
  363. if ($item->type == ItemDetails::type_one) {
  364. $emp = $empMap[$item->data_id] ?? null;
  365. $detailRow['code_2'] = $emp ? $emp->number : '';
  366. $detailRow['title_2'] = $emp ? $emp->title : '';
  367. } else {
  368. $dev = $devMap[$item->data_id] ?? null;
  369. $detailRow['code_2'] = $dev ? $dev->code : '';
  370. $detailRow['title_2'] = $dev ? $dev->title : '';
  371. }
  372. // 归档到对应的主表 ID 下
  373. $res[$item->item_id][] = $detailRow;
  374. }
  375. return $res;
  376. }
  377. //项目节点
  378. public function itemNodeEdit($data,$user){
  379. list($status,$msg) = $this->itemNodeRule($data, $user, false);
  380. if(!$status) return [$status,$msg];
  381. try {
  382. DB::beginTransaction();
  383. $model = ItemNode::where('id', $data['id'])->first();
  384. $tableName = $model->getTable();
  385. $model->title = $data['title'] ?? '';
  386. $model->mark = $data['mark'] ?? "";
  387. $model->start_time = $data['start_time'] ?? 0;
  388. $model->end_time = $data['end_time'] ?? 0;
  389. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  390. $model->entrust_type = $data['entrust_type'] ?? 0;
  391. $model->charge_id = $data['charge_id'] ?? 0;
  392. $model->node_id = $data['node_id'] ?? 0;
  393. $model->node_weight = $data['node_weight'] ?? 0;
  394. $model->is_review_required = $data['is_review_required'] ?? 0;
  395. $model->review_id = $data['review_id'] ?? 0;
  396. $model->priority_id = $data['priority_id'] ?? 0;
  397. $model->save();
  398. $time = time();
  399. ItemNodeDetails::where('del_time',0)
  400. ->where('item_node_id', $model->id)
  401. ->update(['del_time' => $time]);
  402. $this->saveNodeDetail($model->id, $time, $data);
  403. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  404. if (! $status) {
  405. DB::rollBack();
  406. return [false, $msg];
  407. }
  408. DB::commit();
  409. }catch (\Exception $exception){
  410. DB::rollBack();
  411. return [false,$exception->getMessage()];
  412. }
  413. return [true, ''];
  414. }
  415. public function itemNodeAdd($data,$user){
  416. list($status,$msg) = $this->itemNodeRule($data, $user);
  417. if(!$status) return [$status,$msg];
  418. try {
  419. DB::beginTransaction();
  420. $model = new ItemNode();
  421. $model->item_id = $data['item_id'] ?? 0;
  422. $tableName = $model->getTable();
  423. $model->code = $this->generateBillNo([
  424. 'top_depart_id' => $user['top_depart_id'],
  425. 'type' => ItemNode::Order_type,
  426. 'period' => date("Ym", time())
  427. ]);
  428. $model->title = $data['title'] ?? '';
  429. $model->mark = $data['mark'] ?? "";
  430. $model->start_time = $data['start_time'] ?? 0;
  431. $model->end_time = $data['end_time'] ?? 0;
  432. $model->is_delivery_required = $data['is_delivery_required'] ?? 0;
  433. $model->entrust_type = $data['entrust_type'] ?? 0;
  434. $model->charge_id = $data['charge_id'] ?? 0;
  435. $model->node_id = $data['node_id'] ?? 0;
  436. $model->node_weight = $data['node_weight'] ?? 0;
  437. $model->is_review_required = $data['is_review_required'] ?? 0;
  438. $model->review_id = $data['review_id'] ?? 0;
  439. $model->priority_id = $data['priority_id'] ?? 0;
  440. $model->crt_id = $user['id'];
  441. $model->top_depart_id = $data['top_depart_id'];
  442. $model->save();
  443. $this->saveNodeDetail($model->id, time(), $data);
  444. list($status, $msg) = CustomFieldSettingService::syncCustomFieldData($model->id, $tableName, $data, $user);
  445. if (!$status) {
  446. DB::rollBack();
  447. return [false, $msg];
  448. }
  449. DB::commit();
  450. }catch (\Exception $exception){
  451. DB::rollBack();
  452. return [false,$exception->getMessage()];
  453. }
  454. return [true, ''];
  455. }
  456. private function saveNodeDetail($id, $time, $data){
  457. if(! empty($data['man_list'])){
  458. $unit = [];
  459. foreach ($data['man_list'] as $value){
  460. $unit[] = [
  461. 'item_id' => $data['item_id'],
  462. 'item_node_id' => $id,
  463. 'type' => $value['type'],
  464. 'data_id' => $value['data_id'],
  465. 'crt_time' => $time,
  466. 'top_depart_id' => $value['top_depart_id'],
  467. ];
  468. }
  469. if(! empty($unit)) ItemNodeDetails::insert($unit);
  470. }
  471. if(! empty($data['device_list'])){
  472. $receipt = [];
  473. foreach ($data['device_list'] as $value){
  474. $receipt[] = [
  475. 'item_id' => $data['item_id'],
  476. 'item_node_id' => $id,
  477. 'type' => $value['type'],
  478. 'data_id' => $value['data_id'],
  479. 'crt_time' => $time,
  480. 'top_depart_id' => $value['top_depart_id'],
  481. ];
  482. }
  483. if(! empty($receipt)) ItemNodeDetails::insert($receipt);
  484. }
  485. }
  486. private function getNodeDetail($id){
  487. $data = ItemNodeDetails::where('del_time',0)
  488. ->where('item_node_id', $id)
  489. ->get()->toArray();
  490. $id = $id2 = [];
  491. foreach ($data as $value){
  492. if($value['type'] == ItemNodeDetails::type_one) {
  493. $id[] = $value['data_id'];
  494. }else{
  495. $id2[] = $value['data_id'];
  496. }
  497. }
  498. $map = Employee::whereIn('id', $id)->select('title','id','number')->get()->toArray();
  499. $map = array_column($map,null,'id');
  500. $map2 = Device::whereIn('id', $id2)->select('code','id','title')->get()->toArray();
  501. $map2 = array_column($map2,null,'id');
  502. $unit = $receipt = [];
  503. foreach ($data as $value){
  504. if($value['type'] == ItemNodeDetails::type_one) {
  505. $tmp = $map[$value['data_id']] ?? [];
  506. $unit[] = [
  507. 'type' => $value['type'],
  508. 'data_id' => $value['data_id'],
  509. 'data_title' => $tmp['title'],
  510. 'data_code' => $tmp['number'],
  511. ];
  512. }else{
  513. $tmp = $map2[$value['data_id']] ?? [];
  514. $receipt[] = [
  515. 'type' => $value['type'],
  516. 'data_id' => $value['data_id'],
  517. 'data_title' => $tmp['title'] ?? "",
  518. 'data_code' => $tmp['code'] ?? "",
  519. ];
  520. }
  521. }
  522. return [
  523. 'man_list' => $unit,
  524. 'device_list' => $receipt,
  525. ];
  526. }
  527. public function itemNodeDel($data){
  528. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  529. try {
  530. DB::beginTransaction();
  531. $time = time();
  532. ItemNode::where('del_time',0)
  533. ->whereIn('id',$data['id'])
  534. ->update(['del_time' => $time]);
  535. ItemNodeDetails::where('del_time',0)
  536. ->whereIn('item_node_id', $data['id'])
  537. ->update(['del_time' => $time]);
  538. DB::commit();
  539. }catch (\Exception $exception){
  540. DB::rollBack();
  541. return [false,$exception->getMessage()];
  542. }
  543. return [true, ''];
  544. }
  545. public function itemNodeDetail($data, $user){
  546. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  547. $customer = ItemNode::where('del_time',0)
  548. ->withCustomData($user)
  549. ->where('id',$data['id'])
  550. ->first();
  551. if(empty($customer)) return [false,'项目节点不存在或已被删除'];
  552. $customer->getFormattedCustomFields();// 自定义数据附件处理
  553. $customer = $customer->toArray();
  554. $customer['start_time'] = ! empty($customer['start_time']) ? date("Y-m-d", $customer['start_time']) : "";
  555. $customer['end_time'] = ! empty($customer['end_time']) ? date("Y-m-d", $customer['end_time']) : "";
  556. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('title');
  557. $customer['charge_name'] = Employee::where('id',$customer['charge_id'])->value('title');
  558. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  559. $customer['state_title'] = ItemNode::State_Type[$customer['state']] ?? '';
  560. $customer['priority_title'] = Tag::where('id', $customer['priority_id'])->value('title') ?? "";
  561. $customer['node_title'] = Tag::where('id', $customer['node_id'])->value('title') ?? "";
  562. $tag = (new TagService())->getTagMap(array_unique([$customer['priority_id'], $customer['node_id'] ]));
  563. $priority_tmp = $tag[$customer['priority_id']] ?? [];
  564. $customer['priority_title'] = $priority_tmp['title'] ?? '';
  565. $customer['priority_code'] = $priority_tmp['code'] ?? '';
  566. $node_tmp = $tag[$customer['node_id']] ?? [];
  567. $customer['node_title'] = $node_tmp['title'] ?? '';
  568. $customer['node_code'] = $node_tmp['code'] ?? '';
  569. $details = $this->getNodeDetail($data['id']);
  570. $customer = array_merge($customer, $details);
  571. return [true, $customer];
  572. }
  573. public function itemNodeCommon($data,$user, $field = []){
  574. if(empty($field)) $field = ItemNode::$field;
  575. $model = ItemNode::TopClear($user,$data);
  576. $model = $model->where('del_time',0)
  577. ->select($field)
  578. ->orderby('id', 'desc');
  579. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  580. if(! empty($data['code'])) $model->where('code', 'LIKE', '%'.$data['code'].'%');
  581. if(! empty($data['id'])) $model->whereIn('id', $data['id']);
  582. if(isset($data['state'])) $model->where('state', $data['state']);
  583. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  584. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  585. $model->where('crt_time','>=',$return[0]);
  586. $model->where('crt_time','<=',$return[1]);
  587. }
  588. return $model;
  589. }
  590. public function itemNodeList($data,$user){
  591. $model = $this->itemNodeCommon($data, $user);
  592. $list = $this->limit($model,'',$data);
  593. $list = $this->fillNodeData($list);
  594. return [true, $list];
  595. }
  596. public function itemNodeRule(&$data, $user, $is_add = true){
  597. $data['top_depart_id'] = $user['top_depart_id'];
  598. if(empty($data['item_id'])) return [false, '项目ID不能为空'];
  599. $item = Item::where('item_id', $data['item_id'])->where('del_time',0)->first();
  600. if(empty($item)) return [false, '项目不存在或已被删除'];
  601. $item = $item->toArray();
  602. if(empty($data['title'])) return [false, '节点名称不能为空'];
  603. if(! empty($data['start_time'])) $data['start_time'] = $this->changeDateToDate($data['start_time']);
  604. if(! empty($data['end_time'])) $data['end_time'] = $this->changeDateToDate($data['end_time'],true);
  605. $itemStartTime = $item['start_time'];
  606. $itemEndTime = $item['end_time'];
  607. if (!empty($data['start_time'])) {
  608. $inputStartTime = $data['start_time'];
  609. if ($itemStartTime > 0 && $inputStartTime < $itemStartTime) {
  610. return [false, '节点开始时间不能早于项目开始时间:' . date('Y-m-d', $itemStartTime)];
  611. }
  612. }
  613. if (!empty($data['end_time'])) {
  614. $inputEndTime = $data['end_time'];
  615. if ($itemEndTime > 0 && $inputEndTime > $itemEndTime) {
  616. return [false, '节点结束时间不能晚于项目结束时间:' . date('Y-m-d', $itemEndTime)];
  617. }
  618. }
  619. if(! empty($data['man_list'])) {
  620. foreach ($data['man_list'] as $key => $value){
  621. if(empty($value['type'])) return [false, '类型不能为空'];
  622. if(empty($value['data_id'])) return [false, '人员不能为空'];
  623. $data['man_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  624. }
  625. list($status, $msg) = $this->checkArrayRepeat($data['man_list'],'data_id','人员');
  626. if(! $status) return [false, $msg];
  627. }
  628. if(! empty($data['device_list'])) {
  629. foreach ($data['device_list'] as $key => $value){
  630. if(empty($value['type'])) return [false, '类型不能为空'];
  631. if(empty($value['data_id'])) return [false, '设备ID不能为空'];
  632. $data['device_list'][$key]['top_depart_id'] = $data['top_depart_id'];
  633. }
  634. list($status, $msg) = $this->checkArrayRepeat($data['device_list'],'data_id','设备');
  635. if(! $status) return [false, $msg];
  636. }
  637. if($is_add){
  638. $bool = ItemNode::where('item_id',$data['item_id'])
  639. ->where('top_depart_id', $data['top_depart_id'])
  640. ->where('title', $data['title'])
  641. ->where('del_time',0)
  642. ->exists();
  643. }else{
  644. if(empty($data['id'])) return [false,'ID不能为空'];
  645. $bool = ItemNode::where('title', $data['title'])
  646. ->where('item_id',$data['item_id'])
  647. ->where('top_depart_id', $data['top_depart_id'])
  648. ->where('id','<>',$data['id'])
  649. ->where('del_time',0)
  650. ->exists();
  651. }
  652. if($bool) return [false, '该项目下节点名称已存在'];
  653. return [true, ''];
  654. }
  655. public function fillNodeData($data){
  656. if(empty($data['data'])) return $data;
  657. $emp = (new EmployeeService())->getEmployeeMap(array_unique(array_merge_recursive(array_column($data['data'],'charge_id'), array_column($data['data'],'crt_id'))));
  658. $tag = (new TagService())->getTagMap(array_unique(array_merge_recursive(array_column($data['data'],'priority_id'),array_column($data['data'],'node_id'))));
  659. foreach ($data['data'] as $key => $value){
  660. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  661. $data['data'][$key]['start_time'] = $value['start_time'] ? date('Y-m-d',$value['start_time']) : '';
  662. $data['data'][$key]['end_time'] = $value['end_time'] ? date('Y-m-d',$value['end_time']) : '';
  663. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  664. $data['data'][$key]['charge_name'] = $emp[$value['charge_id']] ?? '';
  665. $data['data'][$key]['state_title'] = ItemNode::State_Type[$value['state']] ?? "";
  666. $priority_tmp = $tag[$value['priority_id']] ?? [];
  667. $data['data'][$key]['priority_title'] = $priority_tmp['title'] ?? '';
  668. $data['data'][$key]['priority_code'] = $priority_tmp['code'] ?? '';
  669. $node_tmp = $tag[$value['node_id']] ?? [];
  670. $data['data'][$key]['node_title'] = $node_tmp['title'] ?? '';
  671. $data['data'][$key]['node_code'] = $node_tmp['code'] ?? '';
  672. }
  673. return $data;
  674. }
  675. }