ItemService.php 35 KB

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