ItemService.php 34 KB

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