ProductService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <?php
  2. namespace App\Service;
  3. use App\Model\Employee;
  4. use App\Model\Product;
  5. use Illuminate\Support\Facades\DB;
  6. /**
  7. * 产品管理
  8. */
  9. class ProductService extends Service
  10. {
  11. /**
  12. * 产品分类编辑
  13. * @param $data
  14. * @param $user
  15. * @return array
  16. */
  17. public function productCategoryEdit($data,$user){
  18. list($status,$msg) = $this->productCategoryRule($data,$user,false);
  19. if(!$status) return [$status,$msg];
  20. $update = $msg['data'][0];
  21. $model = new ProductCategory();
  22. $model->where('id',$data['id'])->update($update);
  23. return [true,''];
  24. }
  25. /**
  26. * 产品分类新增
  27. * @param $data
  28. * @param $user
  29. * @return array
  30. */
  31. public function productCategoryAdd($data,$user){
  32. list($status,$msg) = $this->productCategoryRule($data,$user);
  33. if(!$status) return [$status,$msg];
  34. ProductCategory::insert($msg['data']);
  35. return [true,''];
  36. }
  37. /**
  38. * 产品分类删除
  39. * @param $data
  40. * @return array
  41. */
  42. public function productCategoryDel($data){
  43. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  44. $bool = Product::where('del_time',0)
  45. ->where('product_category_id',$data['id'])
  46. ->exists();
  47. if($bool) return [false,'产品分类下已添加产品,操作失败'];
  48. try {
  49. DB::beginTransaction();
  50. ProductCategory::where('id',$data['id'])->update([
  51. 'del_time' => time()
  52. ]);
  53. DB::commit();
  54. }catch (\Exception $exception){
  55. DB::rollBack();
  56. return [false,$exception->getMessage()];
  57. }
  58. return [true,''];
  59. }
  60. /**
  61. * 产品分类列表
  62. * @param $data
  63. * @param $user
  64. * @return array
  65. */
  66. public function productCategoryList($data,$user){
  67. $model = ProductCategory::leftJoin('product_category_orderby as a', function ($join) {
  68. $join->on('product_category.id', '=', 'a.category_id')
  69. ->where('a.del_time',0);
  70. })
  71. ->where('product_category.del_time',0)
  72. ->select('product_category.title','product_category.id','product_category.parent_id','product_category.is_edit_unit_price')
  73. ->orderByRaw('IF(a.sort IS NULL, product_category.id, a.sort) ASC'); // 排序逻辑:优先按 a.sort 排序,没有关联时按主表 id 排序
  74. if(! empty($data['title'])) $model->where('title', 'LIKE', '%'.$data['title'].'%');
  75. if(isset($data['is_edit_unit_price'])) $model->where('is_edit_unit_price', $data['is_edit_unit_price']);
  76. $list = $model->get()->toArray();
  77. foreach ($list as $key => $value){
  78. $list[$key]['is_edit_unit_price_title'] = ProductCategory::$is_edit_unit_price[$value['is_edit_unit_price']] ?? "";
  79. }
  80. $list_tree = $list;
  81. if(! empty($list_tree)) {
  82. $list_tree = $this->makeTree(0,$list_tree);
  83. $list_tree = $this->set_sort_circle($list_tree);
  84. }
  85. return [200, ['data' => $list,'tree' => $list_tree]];
  86. }
  87. /**
  88. * 产品分类参数规则
  89. * @param $data
  90. * @param $is_add
  91. * @return array
  92. */
  93. public function productCategoryRule($data,$user, $is_add = true){
  94. if($this->isEmpty($data,'data')) return [false,'数据不能为空!'];
  95. $title = array_column($data['data'],'title');
  96. $title = array_map(function($val) {
  97. return $val !== null ? $val : 0;
  98. }, $title);
  99. $title_count = array_count_values($title);
  100. foreach ($title as $value){
  101. if(empty($value)) return [false,'名称不能为空!'];
  102. if($title_count[$value] > 1) return [false,'名称不能重复'];
  103. }
  104. foreach ($data['data'] as $key => $value){
  105. $data['data'][$key]['upd_time'] = time();
  106. if($is_add){
  107. $parent_id = 0;
  108. if(! empty($value['parent_id'])) {
  109. $bool = Product::where('del_time',0)
  110. ->where('product_category_id',$value['parent_id'])
  111. ->exists();
  112. if($bool) {
  113. $title = ProductCategory::where('id',$value['parent_id'])->select('title')->value('title');
  114. return [false,'产品分类:'. $title .'下已添加产品,不允许添加子分类'];
  115. }
  116. $parent_id = $value['parent_id'];
  117. }
  118. $data['data'][$key]['parent_id'] = $parent_id;
  119. $data['data'][$key]['crt_time'] = time();
  120. $data['data'][$key]['depart_id'] = $data['depart_id'];
  121. $data['data'][$key]['top_depart_id'] = $data['top_depart_id'];
  122. $bool = ProductCategory::where('title',$value['title'])
  123. ->where('top_depart_id',$data['top_depart_id'])
  124. ->where('del_time',0)
  125. ->exists();
  126. }else{
  127. if($this->isEmpty($data,'id')) return [false,'id不能为空!'];
  128. $top_depart_id = ProductCategory::where('id',$data['id'])->value('top_depart_id');
  129. $bool = ProductCategory::where('title',$value['title'])
  130. ->where('id','<>',$data['id'])
  131. ->where('del_time',0)
  132. ->exists();
  133. }
  134. if($bool) return [false,'分类名称不能重复'];
  135. }
  136. return [true, $data];
  137. }
  138. /**
  139. * 产品编辑
  140. * @param $data
  141. * @param $user
  142. * @return array
  143. */
  144. public function productEdit($data,$user){
  145. list($status,$msg) = $this->productRule($data, $user, false);
  146. if(!$status) return [$status,$msg];
  147. try {
  148. DB::beginTransaction();
  149. $model = Product::where('id',$data['id'])->first();
  150. $model->category = $data['category'] ?? '';
  151. $model->title = $data['title'];
  152. $model->code = $data['code'] ?? '';
  153. $model->size = $data['size'] ?? '';
  154. $model->unit = $data['unit'] ?? 0;
  155. $model->business_cost = $data['business_cost'] ?? 0;
  156. $model->cost = $data['cost'] ?? 0;
  157. $model->write_off_price = $data['write_off_price'] ?? 0;
  158. $model->major_client_settlement_price = $data['major_client_settlement_price'] ?? 0;
  159. $model->return_change_price = $data['return_change_price'] ?? 0;
  160. $model->freight_price = $data['freight_price'] ?? 0;
  161. $model->mark = $data['mark'] ?? '';
  162. $model->save();
  163. DB::commit();
  164. }catch (\Exception $exception){
  165. DB::rollBack();
  166. return [false,$exception->getMessage()];
  167. }
  168. return [true, ''];
  169. }
  170. /**
  171. * 产品新增
  172. * @param $data
  173. * @param $user
  174. * @return array
  175. */
  176. public function productAdd($data,$user){
  177. list($status,$msg) = $this->productRule($data, $user);
  178. if(!$status) return [$status,$msg];
  179. try {
  180. DB::beginTransaction();
  181. $model = new Product();
  182. $model->category = $data['category'] ?? '';
  183. $model->title = $data['title'];
  184. $model->code = $data['code'] ?? '';
  185. $model->size = $data['size'] ?? '';
  186. $model->unit = $data['unit'] ?? 0;
  187. $model->business_cost = $data['business_cost'] ?? 0;
  188. $model->cost = $data['cost'] ?? 0;
  189. $model->write_off_price = $data['write_off_price'] ?? 0;
  190. $model->major_client_settlement_price = $data['major_client_settlement_price'] ?? 0;
  191. $model->return_change_price = $data['return_change_price'] ?? 0;
  192. $model->freight_price = $data['freight_price'] ?? 0;
  193. $model->mark = $data['mark'] ?? '';
  194. $model->crt_id = $user['id'];
  195. $model->save();
  196. DB::commit();
  197. }catch (\Exception $exception){
  198. DB::rollBack();
  199. return [false,$exception->getMessage()];
  200. }
  201. return [true, ''];
  202. }
  203. /**
  204. * 产品删除
  205. * @param $data
  206. * @return array
  207. */
  208. public function productDel($data){
  209. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  210. try {
  211. DB::beginTransaction();
  212. $time = time();
  213. Product::where('del_time',0)->where('id',$data['id'])->update(['del_time' => $time]);
  214. DB::commit();
  215. }catch (\Exception $exception){
  216. DB::rollBack();
  217. return [false,$exception->getMessage()];
  218. }
  219. return [true, ''];
  220. }
  221. /**
  222. * 产品详情
  223. * @param $data
  224. * @param $user
  225. * @return array
  226. */
  227. public function productDetail($data,$user){
  228. if($this->isEmpty($data,'id')) return [false,'请选择数据!'];
  229. $customer = Product::where('del_time',0)
  230. ->where('id',$data['id'])
  231. ->first();
  232. if(empty($customer)) return [false,'产品不存在或已被删除'];
  233. $customer = $customer->toArray();
  234. $customer['crt_name'] = Employee::where('id',$customer['crt_id'])->value('emp_name');
  235. $customer['crt_time'] = $customer['crt_time'] ? date("Y-m-d H:i:s",$customer['crt_time']): '';
  236. return [true, $customer];
  237. }
  238. public function productCommon($data,$user, $field = []){
  239. if(empty($field)) $field = Product::$field;
  240. $model = Product::where('del_time',0)
  241. ->select($field)
  242. ->orderby('code', 'asc');
  243. if(! empty($data['title'])) {
  244. // 清理用户输入,去除前后空白并替换多个连续空格为单个空格
  245. $cleanTitle = preg_replace('/\s+/', ' ', trim($data['title']));
  246. // 构建查询时使用 TRIM 和 REPLACE 来清理数据库字段中的空白字符
  247. $model->whereRaw("TRIM(REPLACE(title, ' ', '')) LIKE ?", ['%' . str_replace(' ', '', $cleanTitle) . '%']);
  248. }
  249. if(! empty($data['product_category_id'])) $model->where('product_category_id', $data['product_category_id']);
  250. if(! empty($data['category'])) $model->where('code', 'LIKE', '%'.$data['category'].'%');
  251. if(! empty($data['size'])) $model->where('size', 'LIKE', '%'.$data['size'].'%');
  252. if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) {
  253. $return = $this->changeDateToTimeStampAboutRange($data['crt_time']);
  254. $model->where('crt_time','>=',$return[0]);
  255. $model->where('crt_time','<=',$return[1]);
  256. }
  257. return $model;
  258. }
  259. /**
  260. * 产品列表
  261. * @param $data
  262. * @param $user
  263. * @return array
  264. */
  265. public function productList($data,$user){
  266. $model = $this->productCommon($data, $user);
  267. $list = $this->limit($model,'',$data);
  268. $list = $this->fillData($list,$user,$data);
  269. return [true, $list];
  270. }
  271. /**
  272. * 产品参数规则
  273. * @param $data
  274. * @param $is_add
  275. * @return array
  276. */
  277. public function productRule(&$data, $user, $is_add = true){
  278. if(empty($data['code'])) return [false,'产品编码不能为空'];
  279. if(empty($data['title'])) return [false,'产品名称不能为空'];
  280. if(! isset($data['cost'])) return [false, '请填写成本'];
  281. if(! isset($data['business_cost'])) return [false, '请填写业务成本'];
  282. $res = $this->checkNumber($data['cost']);
  283. if(! $res) return [false,'成本请输入不超过两位小数并且大于等于0的数值'];
  284. $res = $this->checkNumber($data['business_cost']);
  285. if(! $res) return [false,'业务成本请输入不超过两位小数并且大于等于0的数值'];
  286. if(! empty($data['write_off_price'])){
  287. $res = $this->checkNumber($data['write_off_price']);
  288. if(! $res) return [false,'核销单价请输入不超过两位小数并且大于等于0的数值'];
  289. }
  290. if(! empty($data['major_client_settlement_price'])){
  291. $res = $this->checkNumber($data['major_client_settlement_price']);
  292. if(! $res) return [false,'大客户结算单价请输入不超过两位小数并且大于等于0的数值'];
  293. }
  294. if(! empty($data['return_change_price'])){
  295. $res = $this->checkNumber($data['return_change_price']);
  296. if(! $res) return [false,'退货损耗单价请输入不超过两位小数并且大于等于0的数值'];
  297. }
  298. if(! empty($data['freight_price'])){
  299. $res = $this->checkNumber($data['freight_price']);
  300. if(! $res) return [false,'运费单价请输入不超过两位小数并且大于等于0的数值'];
  301. }
  302. if($is_add){
  303. $bool = Product::where('code', $data['code'])
  304. ->where('del_time',0)
  305. ->exists();
  306. }else{
  307. if(empty($data['id'])) return [false,'ID不能为空'];
  308. $bool = Product::where('code', $data['code'])
  309. ->where('id','<>',$data['id'])
  310. ->where('del_time',0)
  311. ->exists();
  312. }
  313. if($bool) return [false,'产品编码不能重复'];
  314. return [true, $data];
  315. }
  316. /**
  317. * 拼接数据
  318. * @param $data
  319. * @return array
  320. */
  321. public function fillData($data, $user, $search){
  322. if(empty($data['data'])) return $data;
  323. foreach ($data['data'] as $key => $value){
  324. $data['data'][$key]['crt_time'] = $value['crt_time'] ? date('Y-m-d H:i:s',$value['crt_time']) : '';
  325. $data['data'][$key]['crt_name'] = $emp[$value['crt_id']] ?? '';
  326. }
  327. return $data;
  328. }
  329. }