U8ServerService.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <?php
  2. namespace App\Service;
  3. use App\Model\BasicType;
  4. use App\Model\Customer;
  5. use App\Model\Depart;
  6. use App\Model\Employee;
  7. use App\Model\Product;
  8. use App\Model\PurchaseOrder;
  9. use App\Model\PurchaseOrderInfo;
  10. use App\Model\SalesOrder;
  11. use App\Model\SalesOrderProductInfo;
  12. use App\Model\Setting;
  13. use App\Model\Supplier;
  14. use App\Model\U8Job;
  15. use Illuminate\Support\Facades\Config;
  16. use Illuminate\Support\Facades\DB;
  17. use Illuminate\Support\Facades\Log;
  18. use Illuminate\Support\Facades\Redis;
  19. class U8ServerService extends Service
  20. {
  21. public $db = null;
  22. public $error = null; // 错误信息
  23. public $u8 = []; //u8 配置连接参数
  24. public $u8_api = ""; //u8接口请求地址
  25. public $post_common = [];//u8接口公用参数
  26. public function __construct($is_need_connect = 0)
  27. {
  28. //u8 配置连接参数 u8_api设置
  29. list($status,$msg) = $this->settingConnection();
  30. if(! $status) {
  31. $this->error = $msg;
  32. return;
  33. }
  34. //是否需要连接u8数据库
  35. if($is_need_connect){
  36. //构建数据库连接对象
  37. list($status,$msg) = $this->settingDb();
  38. if(! $status) {
  39. $this->error = $msg;
  40. }
  41. }
  42. }
  43. //设置u8连接参数
  44. private function settingConnection(){
  45. $u8 = Setting::where('setting_name','u8')->where('setting_value','<>','')->first();
  46. if(empty($u8)) return [false, 'u8配置参数不存在!'];
  47. $u8 = $u8->toArray();
  48. // 使用 eval() 函数执行字符串并转换为数组
  49. $u8 = eval("return {$u8['setting_value']};");
  50. if(empty($u8['domain'])) return [false, '外部域名不能为空!'];
  51. if(empty($u8['u8_api_port'])) return [false, 'u8程序API端口不能为空!'];
  52. if(empty($u8['u8_database_port'])) return [false, 'u8程序数据库端口不能为空!'];
  53. if(empty($u8['database'])) return [false, 'u8程序数据库不能为空!'];
  54. if(empty($u8['database_account'])) return [false, 'u8程序数据库登录账号不能为空!'];
  55. if(empty($u8['database_password'])) return [false, 'u8程序数据库登录密码不能为空!'];
  56. if(empty($u8['sAccID'])) return [false, 'u8程序sAccID不能为空!'];
  57. if(empty($u8['sServer'])) return [false, 'u8程序sServer不能为空!'];
  58. if(empty($u8['sUserID'])) return [false, 'u8程序sUserID不能为空!'];
  59. if(empty($u8['sPassword'])) return [false, 'u8程序sPassword不能为空!'];
  60. $this->u8 = $u8;
  61. $this->u8_api = "https://" . $u8['domain'] . ":" . $u8['u8_api_port'] . "/U8Sys/U8API";
  62. $this->post_common = [
  63. "password"=>"cloud@123456",
  64. "entity"=>"", //调用方法
  65. "login"=>[
  66. "sAccID"=> $u8['sAccID'],
  67. "sDate"=> date("Y-m-d"),
  68. "sServer"=> $u8['sServer'],
  69. "sUserID"=> $u8['sUserID'],
  70. "sSerial"=> "",
  71. "sPassword"=> $u8['sPassword']
  72. ]
  73. ];
  74. return [true, ''];
  75. }
  76. //设置u8数据库连接
  77. private function settingDb(){
  78. if(empty($this->db)){
  79. $u8 = $this->u8;
  80. $config = [
  81. 'driver' => 'sqlsrv',
  82. 'host' => $u8['domain'],
  83. 'port' => $u8['u8_database_port'],
  84. 'database' => $u8['database'],
  85. 'username' => $u8['database_account'],
  86. 'password' => $u8['database_password'],
  87. ];
  88. // 数据库配置设置
  89. Config::set('database.connections.sqlsrvs', $config);
  90. // 连接
  91. try {
  92. $pdo = DB::connection('sqlsrvs')->getPdo();
  93. if ($pdo instanceof \PDO) {
  94. // 连接成功的逻辑代码
  95. $this->db = DB::connection('sqlsrvs');
  96. } else {
  97. return [false, '连接失败!'];
  98. }
  99. } catch (\Throwable $e) {
  100. return [false, $e->getMessage()];
  101. }
  102. }
  103. return [true, ''];
  104. }
  105. //采购订单保存
  106. public function U8PO_PomainSave($data){
  107. $id = $data;
  108. //映射ip是否通畅
  109. $bool = $this->isDomainAvailable($this->u8['domain']);
  110. if(! $bool) {
  111. $msg = 'U8程序外部域名不可达';
  112. $this->finalSettle($id, U8Job::one,$msg);
  113. return;
  114. }
  115. //获取数据
  116. $result = $this->getPurchaseData($id);
  117. if(empty($result)) {
  118. $msg = "同步数据获取失败";
  119. $this->finalSettle($id, U8Job::one, $msg);
  120. return;
  121. }
  122. //u8接口参数组织
  123. $post = $this->post_common;
  124. $post['entity'] = "U8PO_PomainSave";
  125. $time = date("Y-m-d");
  126. foreach ($result as $value){
  127. $bodys = [];
  128. foreach ($value['product'] as $son){
  129. //子表数据
  130. $bodys[] = [
  131. "iappids"=>"", //子表id
  132. "cinvcode"=>$son['code'], //存货编码
  133. "iquantity"=>$son['number'], //数量
  134. "inum"=>$son['number'], //件数
  135. "ipertaxrate"=>$son['ipertaxrate'], //税率
  136. "iunitprice"=>$son['iunitprice'], //原币单价
  137. "itaxprice"=>$son['itaxprice'], //原币含税单价
  138. "isum"=>$son['isum'], //原币价税合计
  139. "imoney"=>$son['imoney'], //原币无税金额
  140. "itax"=>$son['itax'],//原币税额
  141. "cbmemo"=>$son['mark'], //表体备注
  142. "cdefine22"=>"",
  143. "cdefine23"=>"",
  144. "cdefine24"=>"",
  145. "cdefine25"=>"",
  146. "cdefine26"=>"",
  147. "cdefine27"=>"",
  148. "cdefine28"=>"",
  149. "cdefine29"=>"",
  150. "cdefine30"=>"",
  151. "cdefine31"=>"",
  152. "cdefine32"=>"",
  153. "cdefine33"=>"",
  154. "cdefine34"=>"",
  155. "cdefine35"=>"",
  156. "cdefine36"=>"",
  157. "cdefine37"=>"",
  158. "cfree1"=>"",
  159. "cfree2"=>"",
  160. "cfree3"=>"",
  161. "cfree4"=>"",
  162. "cfree5"=>"",
  163. "cfree6"=>"",
  164. "cfree7"=>"",
  165. "cfree8"=>"",
  166. "cfree9"=>"",
  167. "cfree10"=>""
  168. ];
  169. }
  170. //最终数据
  171. $post['data'] = [
  172. "cpoid"=>$value['order_number'],
  173. "dpodate"=>date("Y-m-d H:i:s",$value['crt_time']),
  174. "cmemo"=>"T9同步采购单",
  175. "cmaker"=>"admin",
  176. "cmaketime"=>$time,
  177. "IsExamine"=>false,
  178. "cvencode"=>$value['cvencode'], //供应商编码
  179. "cdepcode"=>$value['cdepcode'], //部门编号
  180. "cpersoncode"=>$value['cpersoncode'], //业务员编码
  181. "cdefine1"=>"",
  182. "cdefine2"=>"",
  183. "cdefine3"=>"",
  184. "cdefine4"=>"",
  185. "cdefine5"=>"",
  186. "cdefine6"=>"",
  187. "cdefine7"=>"",
  188. "cdefine8"=>"",
  189. "cdefine9"=>"",
  190. "cdefine10"=>"",
  191. "cdefine11"=>"",
  192. "cdefine12"=>"",
  193. "cdefine13"=>"",
  194. "cdefine14"=>"",
  195. "cdefine15"=>"",
  196. "cdefine16"=>"",
  197. "bodys"=>$bodys
  198. ];
  199. file_put_contents('record_purchase.txt',"请求参数:" . json_encode($post) . PHP_EOL,8);
  200. $return = $this->post_helper($this->u8_api,json_encode($post), ['Content-Type:application/json']);
  201. file_put_contents('record_purchase.txt',"返回结果:" . json_encode($return). PHP_EOL,8);
  202. //剔除数据
  203. $id = array_diff($id, [$value['id']]);
  204. if(empty($return)) {
  205. $msg = '异常错误,请确认请求接口地址或地址不可达';
  206. $this->finalSettle($value['id'], U8Job::one, $msg);
  207. }else{
  208. if( ! empty($return['flag'])){
  209. $this->finalSettle($value['id'], U8Job::one);
  210. }else{
  211. $this->finalSettle($value['id'], U8Job::one, $return['msg']);
  212. }
  213. }
  214. }
  215. if(! empty($id)){
  216. $msg = "未找到同步数据";
  217. $this->finalSettle($id, U8Job::one, $msg);
  218. }
  219. }
  220. //销售订单(合同)保存
  221. public function U8SaleOrderSave($data){
  222. $id = $data;
  223. //映射ip是否通畅
  224. $bool = $this->isDomainAvailable($this->u8['domain']);
  225. if(! $bool) {
  226. $msg = 'U8程序外部域名不可达';
  227. $this->finalSettle($id, U8Job::two, $msg);
  228. return;
  229. }
  230. //获取数据
  231. $result = $this->getSaleOrderData($id);
  232. if(empty($result)) {
  233. $msg = "同步数据获取失败";
  234. $this->finalSettle($id, U8Job::two, $msg);
  235. return;
  236. }
  237. //u8接口参数组织
  238. $post = $this->post_common;
  239. $post['entity'] = "U8SaleOrderSave";
  240. $time = date("Y-m-d");
  241. $time1 = date("Y-m-d H:i:s");
  242. foreach ($result as $value){
  243. $bodys = [];
  244. foreach ($value['product'] as $son){
  245. //子表数据
  246. $bodys[] = [
  247. "iappids"=>"", //子表id
  248. "cinvcode"=>$son['code'], //存货编码
  249. "iquantity"=>$son['number'], //数量
  250. "inum"=>$son['number'], //件数
  251. "ipertaxrate"=>$son['ipertaxrate'], //税率
  252. "iunitprice"=>$son['iunitprice'], //原币单价
  253. "itaxprice"=>$son['itaxprice'], //原币含税单价
  254. "isum"=>$son['isum'], //原币价税合计
  255. "imoney"=>$son['imoney'], //原币无税金额
  256. "itax"=>$son['itax'],//原币税额
  257. "cbmemo"=>$son['mark'], //表体备注
  258. "cdefine22"=>"",
  259. "cdefine23"=>"",
  260. "cdefine24"=>"",
  261. "cdefine25"=>"",
  262. "cdefine26"=>"",
  263. "cdefine27"=>"",
  264. "cdefine28"=>"",
  265. "cdefine29"=>"",
  266. "cdefine30"=>"",
  267. "cdefine31"=>"",
  268. "cdefine32"=>"",
  269. "cdefine33"=>"",
  270. "cdefine34"=>"",
  271. "cdefine35"=>"",
  272. "cdefine36"=>"",
  273. "cdefine37"=>"",
  274. "cfree1"=>"",
  275. "cfree2"=>"",
  276. "cfree3"=>"",
  277. "cfree4"=>"",
  278. "cfree5"=>"",
  279. "cfree6"=>"",
  280. "cfree7"=>"",
  281. "cfree8"=>"",
  282. "cfree9"=>"",
  283. "cfree10"=>""
  284. ];
  285. }
  286. //最终数据
  287. $post['data'] = [
  288. "csocode"=>$value['order_number'],
  289. "ddate"=> $time,
  290. "cmaker"=>"admin",
  291. "dcreatesystime"=>$time1,
  292. "cstcode"=>$value['cstcode'],
  293. "ccuscode"=>$value['ccuscode'],
  294. "cdepcode"=>$value['cdepcode'],
  295. "cpersoncode"=>$value['cpersoncode'],
  296. "itaxrate"=>"0",
  297. "cmemo"=>"T9同步销售顶单",
  298. "cdefine1"=>"",
  299. "cdefine2"=>"",
  300. "cdefine3"=>"",
  301. "cdefine4"=>"",
  302. "cdefine5"=>"",
  303. "cdefine6"=>"",
  304. "cdefine7"=>"",
  305. "cdefine8"=>"",
  306. "cdefine9"=>"",
  307. "cdefine10"=>"",
  308. "cdefine11"=>"",
  309. "cdefine12"=>"",
  310. "cdefine13"=>"",
  311. "cdefine14"=>"",
  312. "cdefine15"=>"",
  313. "cdefine16"=>"",
  314. "cdefine16"=>"",
  315. "cdefine16"=>"",
  316. "bodys"=>$bodys
  317. ];
  318. file_put_contents('record_purchase.txt',"请求参数:" . json_encode($post) . PHP_EOL,8);
  319. $return = $this->post_helper($this->u8_api,json_encode($post), ['Content-Type:application/json']);
  320. file_put_contents('record_purchase.txt',"返回结果:" . json_encode($return). PHP_EOL,8);
  321. //剔除数据
  322. $id = array_diff($id, [$value['id']]);
  323. if(empty($return)) {
  324. $msg = '异常错误,请确认请求接口地址或地址不可达';
  325. $this->finalSettle($value['id'],U8Job::two, $msg);
  326. }else{
  327. if( ! empty($return['flag'])){
  328. $this->finalSettle($value['id'],U8Job::two);
  329. }else{
  330. $this->finalSettle($value['id'], U8Job::two, $return['msg']);
  331. }
  332. }
  333. }
  334. if(! empty($id)){
  335. $msg = "未找到同步数据";
  336. $this->finalSettle($id,U8Job::two, $msg);
  337. }
  338. }
  339. //最终处理
  340. public function finalSettle($data,$data_type, $msg = ''){
  341. if(! is_array($data)) $data = [$data];
  342. $time = time();
  343. $insert = [];
  344. U8Job::where('del_time',0)
  345. ->where('data_type',U8Job::one)
  346. ->whereIn('data',$data)
  347. ->update(['del_time' => $time]);
  348. foreach ($data as $value){
  349. if(empty($msg)){
  350. $insert[] = [
  351. 'data' => $value,
  352. 'data_type' => $data_type,
  353. 'crt_time' => $time,
  354. 'state' => U8Job::success,
  355. ];
  356. }else{
  357. $insert[] = [
  358. 'data' => $value,
  359. 'data_type' => $data_type,
  360. 'crt_time' => $time,
  361. 'state' => U8Job::failed,
  362. 'msg' => $msg
  363. ];
  364. }
  365. }
  366. U8Job::insert($insert);
  367. }
  368. public function getPurchaseData($id){
  369. $main = PurchaseOrder::whereIn('id',$id)
  370. ->where('del_time',0)
  371. ->get()->toArray();
  372. if(empty($main)) return [];
  373. $supplier = Supplier::whereIn('id',array_unique(array_column($main,'supplier')))
  374. ->pluck('title','id')
  375. ->toArray();
  376. $depart = Depart::whereIn('id',array_unique(array_column($main,'depart_id')))
  377. ->pluck('title','id')
  378. ->toArray();
  379. $emp = Employee::whereIn('id',array_unique(array_column($main,'purchase_id')))
  380. ->pluck('number','id')
  381. ->toArray();
  382. $sub = PurchaseOrderInfo::whereIn('purchase_order_id',$id)
  383. ->where('del_time',0)
  384. ->get()->toArray();
  385. $product = Product::whereIn('id',array_unique(array_column($sub,'product_id')))
  386. ->get()->toArray();
  387. $product_map = array_column($product,null,'id');
  388. $sub_map = [];
  389. foreach ($sub as $value){
  390. $product_tmp = $product_map[$value['product_id']] ?? [];
  391. $value['code'] = $product_tmp['code'];
  392. //计算金额
  393. if($value['rate'] > 0){
  394. $value['ipertaxrate'] = $value['rate'];
  395. $rate = round($value['rate'] / 100,2);
  396. $value['iunitprice'] = round($value['price'] / $rate,2);
  397. $value['itaxprice'] = $value['price'];
  398. $value['isum'] = $value['price'] * $value['number'];
  399. $value['imoney'] = $value['iunitprice'] * $value['number'];
  400. $value['itax'] = $value['isum'] - $value['imoney'];
  401. }else{
  402. $value['ipertaxrate'] = 0;
  403. $value['iunitprice'] = $value['price'];
  404. $value['itaxprice'] = $value['price'];
  405. $value['isum'] = $value['price'] * $value['number'];
  406. $value['imoney'] = $value['isum'];
  407. $value['itax'] = 0;
  408. }
  409. $sub_map[$value['purchase_order_id']][] = $value;
  410. }
  411. foreach ($main as $key => $value){
  412. $main[$key]['cvencode'] = $supplier[$value['supplier']] ?? "";
  413. $main[$key]['cdepcode'] = $depart[$value['depart_id']] ?? "";
  414. $main[$key]['cpersoncode'] = $emp[$value['purchase_id']] ?? "";
  415. $main[$key]['product'] = $sub_map[$value['id']] ?? [];
  416. }
  417. return $main;
  418. }
  419. public function getSaleOrderData($id){
  420. $main = SalesOrder::whereIn('id',$id)
  421. ->where('del_time',0)
  422. ->get()->toArray();
  423. if(empty($main)) return [];
  424. $sub = SalesOrderProductInfo::whereIn('sales_order_id',$id)
  425. ->where('del_time',0)
  426. ->get()->toArray();
  427. $product = Product::whereIn('id',array_unique(array_column($sub,'product_id')))
  428. ->get()->toArray();
  429. $product_map = array_column($product,null,'id');
  430. $code_map = BasicType::whereIn('id',array_unique(array_merge_recursive(array_column($main,'business_type'),array_column($main,'sale_type'),array_column($main,'plat_type'))))
  431. ->pluck('title','id')
  432. ->toArray();
  433. $customer_map = Customer::whereIn('id',array_unique(array_column($main,'customer_id')))
  434. ->pluck('title','id')
  435. ->toArray();
  436. $depart = Depart::whereIn('id',array_unique(array_column($main,'depart_id')))
  437. ->pluck('title','id')
  438. ->toArray();
  439. $emp = Employee::whereIn('id',array_unique(array_column($main,'crt_id')))
  440. ->pluck('number','id')
  441. ->toArray();
  442. $sub_map = [];
  443. foreach ($sub as $value){
  444. $product_tmp = $product_map[$value['product_id']] ?? [];
  445. //计算金额
  446. if($value['rate'] > 0){
  447. $value['ipertaxrate'] = $value['rate'];
  448. $rate = round($value['rate'] / 100,2);
  449. $value['iunitprice'] = round($value['price'] / $rate,2);
  450. $value['itaxprice'] = $value['price'];
  451. $value['isum'] = $value['price'] * $value['number'];
  452. $value['imoney'] = $value['iunitprice'] * $value['number'];
  453. $value['itax'] = $value['isum'] - $value['imoney'];
  454. }else{
  455. $value['ipertaxrate'] = 0;
  456. $value['iunitprice'] = $value['price'];
  457. $value['itaxprice'] = $value['price'];
  458. $value['isum'] = $value['price'] * $value['number'];
  459. $value['imoney'] = $value['isum'];
  460. $value['itax'] = 0;
  461. }
  462. $value['code'] = $product_tmp['code'];
  463. $sub_map[$value['sales_order_id']][] = $value;
  464. }
  465. foreach ($main as $key => $value){
  466. $main[$key]['cstcode'] = $code_map[$value['sale_type']] ?? ""; //销售类型
  467. $main[$key]['cbustype'] = $code_map[$value['business_type']] ?? ""; //业务类型
  468. $main[$key]['cdefine25'] = $code_map[$value['plat_type']] ?? ""; //平台类型
  469. $main[$key]['cdefine28'] = $code_map[$value['order_number']] ?? ""; //平台单号
  470. $main[$key]['ccuscode'] = $customer_map[$value['customer_id']] ?? "";
  471. $main[$key]['cdepcode'] = $depart[$value['depart_id']] ?? "";
  472. $main[$key]['cpersoncode'] = $emp[$value['crt_id']] ?? "";
  473. $main[$key]['product'] = $sub_map[$value['id']] ?? [];
  474. }
  475. return $main;
  476. }
  477. public function post_helper($url, $data, $header = [], $timeout = 20){
  478. $ch = curl_init();
  479. curl_setopt($ch, CURLOPT_URL, $url);
  480. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  481. curl_setopt($ch, CURLOPT_ENCODING, '');
  482. curl_setopt($ch, CURLOPT_POST, 1);
  483. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  484. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  485. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  486. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  487. if(!is_null($data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  488. $r = curl_exec($ch);
  489. curl_close($ch);
  490. return json_decode($r, true);
  491. }
  492. }