SystemTicketServices.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <?php
  2. namespace app\services\system;
  3. use app\dao\system\SystemTicketDao;
  4. use app\services\BaseServices;
  5. use crmeb\exceptions\AdminException;
  6. use crmeb\services\FormBuilder as Form;
  7. use crmeb\services\printer\Printer;
  8. class SystemTicketServices extends BaseServices
  9. {
  10. public function __construct(SystemTicketDao $dao)
  11. {
  12. $this->dao = $dao;
  13. }
  14. public function ticketList($where)
  15. {
  16. [$page, $limit] = $this->getPageValue();
  17. $list = $this->dao->ticketList($where, $page, $limit);
  18. foreach ($list as &$item) {
  19. $item['add_time'] = date('Y-m-d H:i:s', $item['add_time']);
  20. }
  21. $count = $this->dao->ticketCount($where);
  22. return compact('list', 'count');
  23. }
  24. public function ticketForm($id)
  25. {
  26. $info = $this->dao->get($id) ?? [];
  27. if ($info) $info = $info->toArray();
  28. $field[] = Form::input('print_name', '打印机名称', $info['print_name'] ?? '')->required('请输入打印机名称')->placeholder('打印机名称');
  29. $field[] = Form::radio('type', '平台选择', $info['type'] ?? 1)
  30. ->options([['label' => '易联云', 'value' => 1], ['label' => '飞鹅云', 'value' => 2]])
  31. ->appendControl(1, [
  32. Form::input('yly_user_id', '用户ID:', $info['yly_user_id'] ?? '')->required('请输入用户ID')->placeholder('易联云开发者ID'),
  33. Form::input('yly_app_id', '应用ID:', $info['yly_app_id'] ?? '')->required('请输入应用ID')->placeholder('易联应用ID'),
  34. Form::input('yly_app_secret', '应用密钥:', $info['yly_app_secret'] ?? '')->required('请输入应用密钥')->placeholder('易联应用密钥'),
  35. Form::input('yly_sn', '终端号:', $info['yly_sn'] ?? '')->required('请输入终端号')->placeholder('易联云打印机终端号,打印机型号:易联云打印机 K4无线版'),
  36. ]
  37. )->appendControl(2, [
  38. Form::input('fey_user', '飞鹅云USER:', $info['fey_user'] ?? '')->required('请输入飞鹅云USER')->placeholder('飞鹅云后台注册账号'),
  39. Form::input('fey_ukey', '飞鹅云UYEK:', $info['fey_ukey'] ?? '')->required('请输入飞鹅云UYEK')->placeholder('飞鹅云后台注册账号后生成的UKEY 【备注:这不是填打印机的KEY】'),
  40. Form::input('fey_sn', '飞鹅云SN:', $info['fey_sn'] ?? '')->required('请输入飞鹅云SN')->placeholder('打印机标签上的编号,必须要在管理后台里添加打印机或调用API接口'),
  41. ]
  42. );
  43. $field[] = Form::number('times', '打印联数', $info['times'] ?? 1)->min(1)->required('请输入打印联数')->placeholder('打印机单次打印张数');
  44. $field[] = Form::radio('print_type', '打印时机', $info['print_type'] ?? 1)->options([['label' => '支付后打印', 'value' => 1], ['label' => '下单后打印', 'value' => 2]]);
  45. $field[] = Form::radio('status', '打印开关', $info['status'] ?? 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
  46. return create_form('小票打印', $field, $this->url('/system/ticket/save/' . $id), 'POST');
  47. }
  48. public function ticketSave($id, $data)
  49. {
  50. if ($id) {
  51. $this->dao->update($id, $data);
  52. } else {
  53. $data['add_time'] = time();
  54. $this->dao->save($data);
  55. }
  56. return true;
  57. }
  58. public function ticketSetStatus($id, $status)
  59. {
  60. $this->dao->update($id, ['status' => $status]);
  61. return true;
  62. }
  63. public function ticketDel($id)
  64. {
  65. $this->dao->update($id, ['is_del' => 1]);
  66. return true;
  67. }
  68. public function ticketContent($id)
  69. {
  70. $print_content = $this->dao->value(['id' => $id], 'print_content');
  71. return $print_content ? json_decode($print_content, true) : [];
  72. }
  73. public function ticketContentSave($id, $data)
  74. {
  75. $print_content = json_encode($data);
  76. $this->dao->update($id, ['print_content' => $print_content]);
  77. return true;
  78. }
  79. public function startPrint($order, $product, $print_type = 1)
  80. {
  81. $list = $this->dao->ticketList(['status' => 1, 'print_type' => $print_type]);
  82. foreach ($list as $item) {
  83. if ($item['type'] == 1) { //易联云
  84. $name = 'yi_lian_yun';
  85. $configData = [
  86. 'partner' => $item['yly_user_id'],
  87. 'clientId' => $item['yly_app_id'],
  88. 'apiKey' => $item['yly_app_secret'],
  89. 'terminal' => $item['yly_sn']
  90. ];
  91. $print_content = json_decode($item['print_content'], true);
  92. if (is_null($print_content) || !count($print_content)) throw new AdminException('请先配置打印内容');
  93. $content = $this->ylyContent($print_content, $order, $product, $item['times'], $print_type);
  94. } else { //飞鹅云
  95. $name = 'fei_e_yun';
  96. $configData = [
  97. 'feyUser' => $item['fey_user'],
  98. 'feyUkey' => $item['fey_ukey'],
  99. 'feySn' => $item['fey_sn']
  100. ];
  101. $print_content = json_decode($item['print_content'], true);
  102. if (is_null($print_content) || !count($print_content)) throw new AdminException('请先配置打印内容');
  103. $content = $this->feyContent($print_content, $order, $product, $print_type);
  104. }
  105. $printer = new Printer($name, $configData);
  106. $printer->setPrinterContent($content, $item['times'])->startPrinter();
  107. }
  108. }
  109. public function ylyContent($printContent, $orderInfo, $product, $times, $print_type)
  110. {
  111. $goodsStr = '<table><tr><td>名称</td><td>单价</td><td>数量</td><td>金额</td></tr>';
  112. foreach ($product as $item) {
  113. $goodsStr .= '<tr><td><FH2><FW2>----------------</FW2></FH2></td></tr>';
  114. $goodsStr .= '<tr>';
  115. $price = $item['sum_price'];
  116. $num = $item['cart_num'];
  117. $prices = bcmul((string)$item['cart_num'], (string)$item['sum_price'], 2);
  118. $goodsStr .= "<td>{$item['productInfo']['store_name']} | {$item['productInfo']['attrInfo']['suk']}</td><td>{$price}</td><td>{$num}</td><td>{$prices}</td>";
  119. $goodsStr .= '</tr>';
  120. if (in_array(1, $printContent['goods'])) {
  121. $goodsStr .= '<tr>';
  122. $goodsStr .= "<td>规格编码:{$item['productInfo']['attrInfo']['bar_code']}</td>";
  123. $goodsStr .= '</tr>';
  124. }
  125. unset($price, $num, $prices);
  126. }
  127. $goodsStr .= '</table>';
  128. $total_price = bcadd($orderInfo['total_price'], $orderInfo['pay_postage'], 2);
  129. $addTime = date('Y-m-d H:i:s', $orderInfo['add_time']);
  130. $payTime = isset($orderInfo['pay_time']) ? date('Y-m-d H:i:s', $orderInfo['pay_time']) : '';
  131. $printTime = date('Y-m-d H:i:s', time());
  132. $content = '';
  133. $content .= '<MN>' . $times . '</MN>';
  134. if ($printContent['header']) {
  135. $content .= '<FS2><center>' . sys_config('site_name') . '</center></FS2>';
  136. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  137. }
  138. if ($printContent['delivery']) {
  139. if ($orderInfo['shipping_type'] == 1) {
  140. $content .= '配送方式:商家配送 \r';
  141. } else {
  142. $content .= '配送方式:门店自提 \r';
  143. }
  144. $content .= '客户姓名: ' . $orderInfo['real_name'] . ' \r';
  145. $content .= '客户电话: ' . $orderInfo['user_phone'] . ' \r';
  146. if ($orderInfo['shipping_type'] == 1) $content .= '收货地址: ' . $orderInfo['user_address'] . ' \r';
  147. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  148. }
  149. if ($printContent['buyer_remarks']) {
  150. $content .= '买家备注: ' . $orderInfo['mark'] . ' \r';
  151. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  152. }
  153. if (in_array(0, $printContent['goods'])) {
  154. $content .= '*************商品***************';
  155. $content .= ' \r';
  156. $content .= $goodsStr;
  157. $content .= '********************************\r';
  158. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  159. $content .= '<RA>合计:' . $total_price . '元</RA>';
  160. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  161. }
  162. if ($printContent['preferential'] || $printContent['freight']) {
  163. if ($printContent['freight']) {
  164. $content .= '<RA>邮费:' . $orderInfo['pay_postage'] . '元</RA>';
  165. }
  166. if ($printContent['preferential']) {
  167. $discount_price = bcsub(bcadd($orderInfo['total_price'], $orderInfo['pay_postage'], 2), bcadd($orderInfo['deduction_price'], $orderInfo['pay_price'], 2), 2);
  168. $content .= '<RA>优惠:-' . $discount_price . '元</RA>';
  169. $content .= '<RA>抵扣:-' . $orderInfo['deduction_price'] . '元</RA>';
  170. }
  171. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  172. }
  173. if (in_array(0, $printContent['pay'])) {
  174. if ($print_type == 1) {
  175. switch ($orderInfo['pay_type']) {
  176. case 'weixin':
  177. $content .= '<RA>支付方式:微信支付</RA>';
  178. break;
  179. case 'alipay':
  180. $content .= '<RA>支付方式:支付宝支付</RA>';
  181. break;
  182. case 'yue':
  183. $content .= '<RA>支付方式:余额支付</RA>';
  184. break;
  185. case 'offline':
  186. $content .= '<RA>支付方式:线下支付</RA>';
  187. break;
  188. default:
  189. $content .= '<RA>支付方式:暂无</RA>';
  190. break;
  191. }
  192. } else {
  193. $content .= '<RA>支付方式:暂无</RA>';
  194. }
  195. }
  196. if (in_array(1, $printContent['pay'])) {
  197. $content .= '<RA>实际支付:' . $orderInfo['pay_price'] . '元</RA>';
  198. }
  199. if (count($printContent['pay'])) {
  200. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  201. }
  202. if (in_array(0, $printContent['order'])) {
  203. $content .= '订单编号:' . $orderInfo['order_id'] . '\r';
  204. }
  205. if (in_array(1, $printContent['order'])) {
  206. $content .= '下单时间:' . $addTime . '\r';
  207. }
  208. if (in_array(2, $printContent['order'])) {
  209. $content .= '支付时间:' . $payTime . '\r';
  210. }
  211. if (in_array(3, $printContent['order'])) {
  212. $content .= '打印时间:' . $printTime . '\r';
  213. }
  214. if (count($printContent['order'])) {
  215. $content .= '<FH2><FW2>----------------</FW2></FH2>';
  216. }
  217. if ($printContent['code'] && $printContent['code_url']) {
  218. $content .= '<QR>' . sys_config('site_url') . $printContent['code_url'] . '</QR>';
  219. $content .= ' \r';
  220. }
  221. if ($printContent['show_notice']) {
  222. $content .= '<center>' . $printContent['notice_content'] . '</center>';
  223. $content .= ' \r';
  224. }
  225. return $content;
  226. }
  227. public function feyContent($printContent, $orderInfo, $product, $print_type)
  228. {
  229. $printTime = date('Y-m-d H:i:s', time());
  230. $addTime = date('Y-m-d H:i:s', $orderInfo['add_time']);
  231. $payTime = isset($orderInfo['pay_time']) ? date('Y-m-d H:i:s', $orderInfo['pay_time']) : '';
  232. $content = '';
  233. if ($printContent['header']) {
  234. $content .= '<CB>' . sys_config('site_name') . '</CB><BR>';
  235. $content .= '--------------------------------<BR>';
  236. }
  237. if ($printContent['delivery']) {
  238. if ($orderInfo['shipping_type'] == 1) {
  239. $content .= '配送方式:商家配送<BR>';
  240. } else {
  241. $content .= '配送方式:门店自提<BR>';
  242. }
  243. $content .= '客户姓名: ' . $orderInfo['real_name'] . '<BR>';
  244. $content .= '客户电话: ' . $orderInfo['user_phone'] . '<BR>';
  245. if ($orderInfo['shipping_type'] == 1) $content .= '收货地址:' . $orderInfo['user_address'] . '<BR>';
  246. $content .= '--------------------------------<BR>';
  247. }
  248. if ($printContent['buyer_remarks']) {
  249. $content .= '买家备注:' . $orderInfo['mark'] . '<BR>';
  250. $content .= '--------------------------------<BR>';
  251. }
  252. if (in_array(0, $printContent['goods'])) {
  253. $content .= '<BR>';
  254. $content .= '**************商品**************<BR>';
  255. $content .= '<BR>';
  256. $content .= '名称 单价 数量 金额<BR>';
  257. foreach ($product as $item) {
  258. $content .= '--------------------------------<BR>';
  259. $name = $item['productInfo']['store_name'] . " | " . $item['productInfo']['attrInfo']['suk'];
  260. $price = $item['sum_price'];
  261. $num = $item['cart_num'];
  262. $prices = bcmul((string)$item['cart_num'], (string)$item['sum_price'], 2);
  263. $kw3 = '';
  264. $kw1 = '';
  265. $kw2 = '';
  266. $kw4 = '';
  267. $str = $name;
  268. $blankNum = 14;//名称控制为14个字节
  269. $lan = mb_strlen($str, 'utf-8');
  270. $m = 0;
  271. $j = 1;
  272. $blankNum++;
  273. $result = array();
  274. if (strlen($price) < 6) {
  275. $k1 = 6 - strlen($price);
  276. for ($q = 0; $q < $k1; $q++) {
  277. $kw1 .= ' ';
  278. }
  279. $price = $price . $kw1;
  280. }
  281. if (strlen($num) < 3) {
  282. $k2 = 3 - strlen($num);
  283. for ($q = 0; $q < $k2; $q++) {
  284. $kw2 .= ' ';
  285. }
  286. $num = $num . $kw2;
  287. }
  288. if (strlen($prices) < 6) {
  289. $k3 = 6 - strlen($prices);
  290. for ($q = 0; $q < $k3; $q++) {
  291. $kw4 .= ' ';
  292. }
  293. $prices = $prices . $kw4;
  294. }
  295. for ($i = 0; $i < $lan; $i++) {
  296. $new = mb_substr($str, $m, $j, 'utf-8');
  297. $j++;
  298. if (mb_strwidth($new, 'utf-8') < $blankNum) {
  299. if ($m + $j > $lan) {
  300. $m = $m + $j;
  301. $tail = $new;
  302. $lenght = iconv("UTF-8", "GBK//IGNORE", $new);
  303. $k = 14 - strlen($lenght);
  304. for ($q = 0; $q < $k; $q++) {
  305. $kw3 .= ' ';
  306. }
  307. if ($m == $j) {
  308. $tail .= $kw3 . ' ' . $price . ' ' . $num . ' ' . $prices;
  309. } else {
  310. $tail .= $kw3 . '<BR>';
  311. }
  312. break;
  313. } else {
  314. $next_new = mb_substr($str, $m, $j, 'utf-8');
  315. if (mb_strwidth($next_new, 'utf-8') < $blankNum) {
  316. continue;
  317. } else {
  318. $m = $i + 1;
  319. $result[] = $new;
  320. $j = 1;
  321. }
  322. }
  323. }
  324. }
  325. $head = '';
  326. foreach ($result as $key => $value) {
  327. if ($key < 1) {
  328. $v_lenght = iconv("UTF-8", "GBK//IGNORE", $value);
  329. $v_lenght = strlen($v_lenght);
  330. if ($v_lenght == 13) $value = $value . " ";
  331. $head .= $value . ' ' . $price . ' ' . $num . ' ' . $prices;
  332. } else {
  333. $head .= $value . '<BR>';
  334. }
  335. }
  336. $content .= $head . $tail;
  337. if (in_array(1, $printContent['goods'])) {
  338. $content .= '规格编码:' . $item['productInfo']['attrInfo']['bar_code'] . '<BR>';
  339. }
  340. unset($price);
  341. }
  342. $content .= '<BR>';
  343. $content .= '********************************<BR>';
  344. $content .= '<BR>';
  345. $content .= '--------------------------------<BR>';
  346. $total_price = bcadd($orderInfo['total_price'], $orderInfo['pay_postage'], 2);
  347. $content .= '<RIGHT>合计:' . number_format($total_price, 2) . '元</RIGHT>';
  348. $content .= '--------------------------------<BR>';
  349. }
  350. if ($printContent['preferential'] || $printContent['freight']) {
  351. if ($printContent['freight']) {
  352. $content .= '<RIGHT>邮费:' . number_format($orderInfo['pay_postage'], 2) . '元</RIGHT><BR>';
  353. }
  354. if ($printContent['preferential']) {
  355. $discount_price = bcsub(bcadd($orderInfo['total_price'], $orderInfo['pay_postage'], 2), bcadd($orderInfo['deduction_price'], $orderInfo['pay_price'], 2), 2);
  356. $content .= '<RIGHT>优惠:-' . number_format($discount_price, 2) . '元</RIGHT><BR>';
  357. $content .= '<RIGHT>抵扣:-' . number_format($orderInfo['deduction_price'], 2) . '元</RIGHT>';
  358. }
  359. $content .= '--------------------------------<BR>';
  360. }
  361. if (in_array(0, $printContent['pay'])) {
  362. if ($print_type == 1) {
  363. switch ($orderInfo['pay_type']) {
  364. case 'weixin':
  365. $content .= '<RIGHT>支付方式:微信支付</RIGHT><BR>';
  366. break;
  367. case 'alipay':
  368. $content .= '<RIGHT>支付方式:支付宝支付</RIGHT><BR>';
  369. break;
  370. case 'yue':
  371. $content .= '<RIGHT>支付方式:余额支付</RIGHT><BR>';
  372. break;
  373. case 'offline':
  374. $content .= '<RIGHT>支付方式:线下支付</RIGHT><BR>';
  375. break;
  376. default:
  377. $content .= '<RIGHT>支付方式:暂无</RIGHT><BR>';
  378. break;
  379. }
  380. } else {
  381. $content .= '<RIGHT>支付方式:暂无</RIGHT><BR>';
  382. }
  383. }
  384. if (in_array(1, $printContent['pay'])) {
  385. $content .= '<RIGHT>实际支付:' . number_format($orderInfo['pay_price'], 2) . '元</RIGHT>';
  386. }
  387. if (count($printContent['pay'])) {
  388. $content .= '--------------------------------<BR>';
  389. }
  390. if (in_array(0, $printContent['order'])) {
  391. $content .= '订单编号:' . $orderInfo['order_id'] . '<BR>';
  392. }
  393. if (in_array(1, $printContent['order'])) {
  394. $content .= '下单时间: ' . $addTime . '<BR>';
  395. }
  396. if (in_array(2, $printContent['order'])) {
  397. $content .= '付款时间: ' . $payTime . '<BR>';
  398. }
  399. if (in_array(3, $printContent['order'])) {
  400. $content .= '打印时间: ' . $printTime . '<BR>';
  401. }
  402. if (count($printContent['order'])) {
  403. $content .= '--------------------------------<BR>';
  404. $content .= '<BR>';
  405. }
  406. if ($printContent['code'] && $printContent['code_url']) {
  407. $content .= '<QR>' . sys_config('site_url') . $printContent['code_url'] . '</QR>';
  408. }
  409. if ($printContent['show_notice']) {
  410. $content .= '<C>' . $printContent['notice_content'] . '</C>';
  411. }
  412. return $content;
  413. }
  414. }