GenAMSXmlFile.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. namespace App\Console\Commands\Temp;
  3. use App\Modules\Book\Models\BookConfig;
  4. use Illuminate\Console\Command;
  5. use Hashids;
  6. use Matrix\Exception;
  7. use OSS\OssClient;
  8. use OSS\Core\OssException;
  9. use DB;
  10. class GenAMSXmlFile extends Command
  11. {
  12. /**
  13. * The name and signature of the console command.
  14. *
  15. * @var string
  16. */
  17. protected $signature = 'gen_ams_xml_file';
  18. /**
  19. * The console command description.
  20. *
  21. * @var string
  22. */
  23. protected $description = '腾讯商品库xml生成';
  24. /**
  25. * Create a new command instance.
  26. *
  27. * @return void
  28. */
  29. public function __construct()
  30. {
  31. parent::__construct();
  32. }
  33. private $emails = [
  34. 'lisy@zw88.net',
  35. // 'songdb@iqiyoo.com',
  36. 'zhoulj@iqiyoo.com',
  37. // 'zhaoy@zw88.net'
  38. ];
  39. /**
  40. * Execute the console command.
  41. *
  42. * @return mixed
  43. */
  44. public function handle()
  45. {
  46. $this->genProductXml();
  47. }
  48. /**
  49. * genProductXml
  50. */
  51. public function genProductXml()
  52. {
  53. //筛选出上架状态为2的书籍上传
  54. $now = date('Y-m-d H:i:s');
  55. $gdt_new_bids = DB::table('gdt_new_books')->where('is_deleted', 0)->where('start_time', '<=', $now)->where('end_time', '>=', $now)->pluck('bid')->toArray();
  56. $books = BookConfig::join('books', 'book_configs.bid', '=', 'Books.id')
  57. ->leftjoin('book_categories', 'book_categories.id', 'books.category_id')
  58. ->leftjoin('chapters', 'books.last_cid', 'chapters.id')
  59. ->select(
  60. 'books.intro',
  61. 'books.status',
  62. 'books.size',
  63. 'books.chapter_count',
  64. 'books.last_chapter',
  65. 'book_configs.book_name',
  66. 'book_configs.bid',
  67. 'book_configs.cover',
  68. 'book_configs.vip_seq',
  69. 'book_configs.cover',
  70. 'book_configs.is_on_shelf',
  71. 'book_categories.id as second_category_id',
  72. 'book_categories.pid as first_category_id',
  73. 'book_categories.channel_name as first_category_name',
  74. 'book_categories.category_name as second_category_name',
  75. 'chapters.recent_update_at as latest_renew_time',
  76. 'chapters.sequence as latest_renew_chapter'
  77. )
  78. //->where('book_configs.is_on_shelf','2')
  79. ->where(function ($query) {
  80. $query->where('book_configs.is_on_shelf', '2');
  81. // ->orWhereIn('book_configs.bid', []);//豁免名单
  82. })
  83. ->get();
  84. $string = <<<XML
  85. <?xml version='1.0' encoding='utf-8'?>
  86. <product_set>
  87. </product_set>
  88. XML;
  89. $xml = new \SimpleXMLElement($string);
  90. foreach ($books as $book) {
  91. //在管理后台设置为新书的书籍标记成新书
  92. $is_new_book = in_array($book->bid, $gdt_new_bids) ? '是' : '否';
  93. $bid = Hashids::encode($book->bid);
  94. $data =
  95. array(
  96. 'product_id' => $bid,
  97. 'product_name' => $book->book_name,
  98. 'first_category_id' => $book->first_category_id,
  99. 'second_category_id' => $book->second_category_id,
  100. 'first_category_name' => $book->first_category_name,
  101. 'second_category_name' => $book->second_category_name,
  102. 'expiration_time' => '2022-05-19 23:59:59',
  103. 'target_url_mobile' => 'https://site8y1vm7kwvv850opx.wd.amanbook.com/detail?id=' . $bid,
  104. 'target_url_wechat' => 'https://site8y1vm7kwvv850opx.wd.amanbook.com/detail?id=' . $bid,
  105. 'description' => $this->special_filter(htmlspecialchars($book->intro)),
  106. 'image_url' => $book->cover,
  107. 'word_count' => $book->size,
  108. 'serial_status' => $book->status == 1 ? '完结' : '连载',
  109. 'chapter_count' => $book->chapter_count,
  110. 'started_pay_chapter' => $book->vip_seq,
  111. 'latest_renew_time' => $book->latest_renew_time,
  112. 'latest_renew_chapter' => $book->latest_renew_chapter,
  113. 'if_new_book' => $is_new_book,
  114. 'pay_status' => '付费',
  115. );
  116. $item = $xml->addChild('product');
  117. if (is_array($data)) {
  118. foreach ($data as $key => $row) {
  119. //生成子节点
  120. try {
  121. $node = $item->addChild($key, $row);
  122. } catch (\Exception $e) {
  123. $msg = "======腾讯商品库xml生成出错=====" . date("y-m-d H:i:s" . "\n");
  124. \Log::info($msg);
  125. \Log::info($e->getMessage());
  126. $notify = MessageNotify::mail([
  127. 'to_emails' => implode(",", $this->emails),
  128. 'subject' => $msg,
  129. 'body' => $e->getMessage(),
  130. 'delay_times' => 0,
  131. ]);
  132. $notify->notify();
  133. exit();
  134. }
  135. }
  136. }
  137. }
  138. $file_path = 'storage/tx_product.xml';
  139. echo $xml->asXML($file_path);
  140. //上传到OSS
  141. $ori_file = DB::table('tencent_product_configs')->where('type', 'SITE_MAP_XML_URL')->first();
  142. $verify_code = md5_file($file_path);
  143. if ($ori_file && $ori_file->verify_code == $verify_code) {
  144. \Log::info("======腾讯商品库xml已是最新=====" . date("y-m-d H:i:s" . "\n"));
  145. } else {
  146. $file_name = 'tx_product_wdy.xml';
  147. //解析一遍看是否出错
  148. try {
  149. $load_xml = simplexml_load_file($file_path);
  150. } catch (\Exception $e) {
  151. $msg = "======腾讯商品库xml解析出错=====" . date("y-m-d H:i:s" . "\n");
  152. \Log::info($msg);
  153. \Log::info($e->getMessage());
  154. $notify = MessageNotify::mail([
  155. 'to_emails' => implode(",", $this->emails),
  156. 'subject' => $msg,
  157. 'body' => $e->getMessage(),
  158. 'delay_times' => 0,
  159. ]);
  160. $notify->notify();
  161. //删除文件以防权限问题
  162. if (file_exists($file_path)) unlink($file_path);
  163. exit();
  164. }
  165. $url = $this->saveXmlToOss($file_name, $file_path);
  166. DB::table('tencent_product_configs')
  167. ->updateOrInsert(
  168. ['type' => 'SITE_MAP_XML_URL'],
  169. [
  170. 'value' => $url,
  171. 'updated_at' => date('Y-m-d H:i:s'),
  172. 'verify_code' => $verify_code,
  173. ]
  174. );
  175. }
  176. //上传到OSS后删除,防止权限问题
  177. if (file_exists($file_path)) unlink($file_path);
  178. \Log::info("======腾讯商品库xml生成=====" . date("y-m-d H:i:s" . "\n"));
  179. return;
  180. }
  181. public function dealSpecialCharacters($char)
  182. {
  183. $char = preg_replace("[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]", '', $char);
  184. $char = preg_replace("/&/", '&amp', $char);
  185. $char = preg_replace("/'/", '&apos', $char);
  186. $char = preg_replace("/\"/", '&quot', $char);
  187. $char = preg_replace("/</", '&lt', $char);
  188. $char = preg_replace("/>/", '&gt', $char);
  189. return $char;
  190. }
  191. private function special_filter($string)
  192. {
  193. if (!$string) return '';
  194. $new_string = '';
  195. for ($i = 0; isset($string[$i]); $i++) {
  196. $asc_code = ord($string[$i]); //得到其asc码
  197. // 以下代码旨在过滤非法字符
  198. // ** 数值 8、9、10 和 13 可以分别转换为退格符、制表符、换行符和回车符。
  199. // 这些字符都没有图形表示,但是对于不同的应用程序,这些字符可能会影响文本的显示效果。
  200. if (in_array($asc_code, [8, 9, 10, 13], true)) {
  201. $new_string .= '';
  202. } else {
  203. $new_string .= $string[$i];
  204. }
  205. }
  206. return trim($new_string);
  207. }
  208. /**
  209. * 将xml保存到oss
  210. * @return string
  211. */
  212. function saveXmlToOss($file_name, $file)
  213. {
  214. $accessKeyId = env('OSS_ACCESS_ID');
  215. $accessKeySecret = env('OSS_ACCESS_KEY');
  216. $endpoint = env('OSS_END_POINT');
  217. $bucket = env('OSS_BUCKET');
  218. try {
  219. $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
  220. $upload_res = $ossClient->uploadFile($bucket, $file_name, $file);
  221. \Log::info('saveXmlToOss:'.$bucket.' $file_name:'.$file_name.' $file:'.$file);
  222. $url = str_ireplace('wangduyun.oss-cn-hangzhou.aliyuncs.com', 'cdn-novel.wd.amanbook.com', $upload_res['oss-request-url']);
  223. $url = str_ireplace('http://', 'https://', $url);
  224. } catch (OssException $e) {
  225. \Log::info($e->getMessage());
  226. }
  227. return $url;
  228. }
  229. }