ClientService.php 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. <?php
  2. namespace App\JsonRpc;
  3. use Hyperf\RpcServer\Annotation\RpcService;
  4. use App\Tools\Result;
  5. use Hyperf\DbConnection\Db;
  6. //mocle
  7. use App\Model\Complaint;
  8. use App\Model\JobEnum;
  9. use App\Model\User;
  10. use App\Model\webisitecategory;
  11. use App\Model\WebsiteTemplate;
  12. use Hyperf\Coroutine\Coroutine;
  13. use Hyperf\Redis\Redis;
  14. use Hyperf\Di\Annotation\Inject;
  15. use function Hyperf\Support\env;
  16. use Symfony\Component\Filesystem\Filesystem;
  17. #[RpcService(name: "ClientService", protocol: "jsonrpc-http", server: "jsonrpc-http")]
  18. class ClientService implements ClientServiceInterface
  19. {
  20. #[Inject]
  21. protected Redis $redis;
  22. /**
  23. * @param array $data
  24. * @return array
  25. */
  26. public function test(array $data): array
  27. {
  28. var_dump($data, '-------1--------');
  29. $time = date('Y-m-d H:i:s', time());
  30. $data = [
  31. 'code' => 200,
  32. 'msg' => 'success',
  33. 'data' => [
  34. 'time' => $time,
  35. 'data' => $data,
  36. ]
  37. ];
  38. //mysql直接查询连接数
  39. $activeConnections = Db::select("SHOW STATUS LIKE 'Threads_connected'");
  40. // $activeConnectionsCount = $activeConnections[0]->Value ?? 0;
  41. // $users = Db::select('SELECT * FROM article;');
  42. return ['code' => 200, 'msg' => 'success', 'data' => $activeConnections];
  43. }
  44. public function indexData(array $data): array
  45. {
  46. $time1 = microtime(true);
  47. // 调整获取方式
  48. // 根据网站id获取,从website_template中获取 website_template
  49. $website_id = $data['website_id'] ?? 2;
  50. var_dump("网站id:", $website_id);
  51. $template = Db::table('website_template')->where('website_id', $website_id)->first();
  52. var_dump("模板:", $template);
  53. $template = $template->template_data;
  54. $data = json_decode($template, true);
  55. // $data = json_decode($data['template'], true);
  56. // $website_id = $data['base']['website_id'] ?? 2;
  57. //设置缓存
  58. $websiteInfoCacheKey = "awebsite:category:{$website_id}";
  59. $websiteInfo = $this->redis->get($websiteInfoCacheKey); //false;
  60. if ($websiteInfo === false) {
  61. // Redis 中没有缓存,从数据库中查询
  62. $websiteInfo = Db::table('website_category')->where('website_id', $website_id)->get()->toArray();
  63. // 将查询结果存入 Redis,设置缓存时间为 3600 秒(1 小时)
  64. $this->redis->setex($websiteInfoCacheKey, 3600, json_encode($websiteInfo));
  65. } else {
  66. // 从 Redis 中获取的数据需要反序列化
  67. $websiteInfo = json_decode($websiteInfo, true);
  68. }
  69. $websiteInfo = Db::table('website_category')->where('website_id', $website_id)->get()->toArray();
  70. //取出website
  71. var_dump($websiteInfo, 'websiteInfo');
  72. //取出category_id 对应的数据
  73. $websiteInfoIndexed = array_column($websiteInfo, null, 'category_id');
  74. // 取出category_id 对应的aLIas_pinyin
  75. $categoryIds = array_column($websiteInfo, 'category_id');
  76. $aliasPinyins = array_column($websiteInfo, 'aLIas_pinyin');
  77. $cat_arr = array_combine($categoryIds, $aliasPinyins);
  78. // var_dump($cat_arr, 'cat_arr');
  79. //根据 category_arr_id 组合出 aLIas_pinyin
  80. $catiall = [];
  81. //一级所有子级的记录
  82. $cat_1st_arr = [];
  83. foreach ($websiteInfo as $key => $value) {
  84. //算出路由拼音
  85. $category_arr_id = json_decode($value->category_arr_id);
  86. $pinyin_str = '';
  87. foreach ($category_arr_id as $k => $v) {
  88. $pinyin_str .= $cat_arr[$v] . '/';
  89. }
  90. $pinyin_str = rtrim($pinyin_str, '/');
  91. $catiall[$value->category_id][] = $pinyin_str;
  92. // $cat_id = $value->category_id;
  93. $websiteInfoIndexed[$value->category_id]->pinyin = $pinyin_str;
  94. // 算出一级 并且算出子级
  95. if ($value->pid == 0) {
  96. if (empty($cat_1st_arr[$value->category_id]))
  97. $cat_1st_arr[$value->category_id] = [];
  98. } else {
  99. if ($value->pid == 11) {
  100. var_dump($value->category_id, 'value->category_id');
  101. }
  102. $cat_1st_arr[$value->pid][] = $value->category_id;
  103. }
  104. }
  105. var_dump($cat_1st_arr, 'cat_1st_arr');
  106. $time2 = microtime(true);
  107. $time_ = ($time2 - $time1);
  108. var_dump($time2, $time1, $time_, '返回路由需要多少时间');
  109. //获取
  110. // $getpage = $data['base']['getpage'] ?? 'index';
  111. $getpage = $data['getpage'] ?? 'index';
  112. var_dump($getpage, 'leixing ');
  113. // index = 首页
  114. // class = 频道页
  115. // list = 列表页
  116. // article = 详情页
  117. // search = 搜索页
  118. // aboutList = 底部导航列表页
  119. // aboutArticle = 底部导航详情页
  120. // return $cat_1st_arr;
  121. // return $cat_1st_arr;
  122. // var_dump($cat_1st_arr[11], 'cat_1st_arr'); //一级所有子级的记录
  123. // var_dump($catiall, 'catiall');//拼音
  124. $templateData = [];
  125. switch ($getpage) {
  126. case 'index':
  127. $ceng = $data['template']['index'];
  128. var_dump($ceng, 'ceng================');
  129. foreach ($ceng as $k_ceng => $v_ceng) {
  130. $componetList = $v_ceng['componentList'];
  131. //计算一级的所有子级;组成一个数据,key是一级的category_id,value是所有的子级数据,加上个二级的pinyin属性,放的是catiall的数据
  132. foreach ($componetList as $key => $value) {
  133. //取出componentData
  134. $componentData = $value['componentData'];
  135. // $page = $componentData['page'];
  136. // $pageSize = $componentData['pageSize'];
  137. // $listType = $componentData['listType'];
  138. $category_id = $componentData['category_id'] ?? $categoryIds[0];
  139. //此处应该有值
  140. $imgSize = $componentData['imgSize'] ?? 1;
  141. $textSize = $componentData['textSize'] ?? 1;
  142. $level = $componentData['level'] ?? 1;
  143. $child = $componentData['child'] ?? [];
  144. //获取子级
  145. if ($child) {
  146. }
  147. $child_id = $child['id'] ?? $categoryIds[0];
  148. $child_imgSize = $child['imgSize'] ?? 1;
  149. $child_textSize = $child['textSize'] ?? 1;
  150. // 拼音就是路由----
  151. // unset($listType['pinyin']);
  152. //查询查询数据,返回到data字段里,根据这几个
  153. if ($category_id > 0) {
  154. var_dump($category_id, '------------------category_id');
  155. var_dump($cat_1st_arr, '-----------1-------2');
  156. // 第一次查询:imgurl 不为空的数据
  157. $imgArticles = Db::table('article')->leftJoin('article_ignore', function ($join) use ($website_id) {
  158. $join->on('article.id', '=', 'article_ignore.article_id')->where('article_ignore.website_id', '=', $website_id);
  159. })->whereNull('article_ignore.article_id')->whereIn('catid', $temp_arr = array_merge([$category_id], $cat_1st_arr[$category_id]))->where('status', 1)->whereNotNull('imgurl')->where('imgurl', '!=', '')->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  160. //拼接上拼音
  161. foreach ($imgArticles as $k => $v) {
  162. $imgArticles[$k]->pinyin = $catiall[$v->catid][0];
  163. }
  164. // 第二次查询:imgurl 为空的数据
  165. $textArticles = Db::table('article')->whereIn('catid', $temp_arr = array_merge([$category_id], $cat_1st_arr[$category_id]))->where('status', 1)->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  166. //拼接上拼音
  167. foreach ($textArticles as $k => $v) {
  168. $textArticles[$k]->pinyin = $catiall[$v->catid][0];
  169. }
  170. }
  171. var_dump($level, 'level');
  172. if ($level > 0) {
  173. // 取出一级的所有子级
  174. //取出所有的子级的imgurl 不为空的数据
  175. $imgArticles = Db::table('article')->whereRaw('MATCH(level_text) AGAINST(? IN NATURAL LANGUAGE MODE)', [$level])->where('status', 1)->whereIn('catid', $categoryIds)->whereNotNull('imgurl')->where('imgurl', '!=', '')->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  176. //拼接上拼音
  177. foreach ($imgArticles as $k => $v) {
  178. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  179. }
  180. //取出所有的子级的imgurl 为空的数据
  181. $textArticles = Db::table('article')->where('status', 1)->whereRaw('MATCH(level_text) AGAINST(? IN NATURAL LANGUAGE MODE)', [$level])->whereIn('catid', $categoryIds)->whereNull('imgurl')->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  182. //拼接上拼音
  183. foreach ($textArticles as $k => $v) {
  184. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  185. }
  186. }
  187. //将查询到的数据放到componentData里
  188. $componetList[$key]['componentData']['data']['alias'] = $websiteInfoIndexed[$category_id]->alias ?? 'aliasnull' . $category_id;
  189. $componetList[$key]['componentData']['data']['pinyin'] = $websiteInfoIndexed[$category_id]->pinyin ?? 'aliasnull' . $category_id;
  190. $componetList[$key]['componentData']['data']['category_id'] = $category_id;
  191. $componetList[$key]['componentData']['data']['textnum'] = $textArticles;
  192. $componetList[$key]['componentData']['data']['imgnum'] = $imgArticles;
  193. //判断child
  194. if ($child_id > 0) {
  195. //取出子级的imgurl 不为空的数据
  196. $child_imgArticles = Db::table('article')->where('catid', $child_id)->whereNotNull('imgurl')->limit($child_imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  197. //取出子级的imgurl 为空的数据
  198. $child_textArticles = Db::table('article')->where('catid', $child_id)->whereNull('imgurl')->limit($child_textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  199. //将查询到的数据放到componentData里
  200. $componetList[$key]['componentData']['data']['child']['alias'] = $websiteInfoIndexed[$child_id]->alias;
  201. $componetList[$key]['componentData']['data']['child']['pinyin'] = $websiteInfoIndexed[$child_id]->pinyin;
  202. $componetList[$key]['componentData']['data']['child']['category_id'] = $child_id;
  203. $componetList[$key]['componentData']['data']['child']['textnum'] = $child_textArticles;
  204. $componetList[$key]['componentData']['data']['child']['imgnum'] = $child_imgArticles;
  205. //取出自己
  206. $all_childcat = $cat_1st_arr[$category_id];
  207. $processedChildCat = array_map(function ($v) use ($websiteInfoIndexed) {
  208. // 从 $websiteInfoIndexed 中获取对应的数据
  209. $info = $websiteInfoIndexed[$v];
  210. // 返回一个包含所需信息的数组
  211. return ['pinyin' => $info->pinyin, 'alias' => $info->alias, 'category_id' => $info->category_id, 'aLIas_pinyin' => $info->aLIas_pinyin, 'pid' => $info->pid, 'cat_arr_id' => $info->category_arr_id ?? ['出错']];
  212. }, $all_childcat);
  213. $componetList[$key]['componentData']['data']['child']['all_childcat'] = $processedChildCat ?? [];
  214. }
  215. }
  216. $data['template']['index'][$k_ceng]['componentList'] = $componetList;
  217. }
  218. //将修改后的数据放到template里
  219. break;
  220. case 'class':
  221. $componetList = $data['template']['class']['data'][0]['componentList'];
  222. $class_count = count($componetList);
  223. $parent_id = $data['template']['class']['parent_id'] ?? 0;
  224. //获取子级;
  225. $child = $cat_1st_arr[$parent_id]; //获取子级
  226. // var_dump($child, 'child');
  227. //如果$child的数量小于$class_count,就填充一样多的数据给child,如果大于就截取一样的数量给child
  228. if (count($child) < $class_count) {
  229. $child = array_pad($child, $class_count, end($child) ?? 0);
  230. } elseif (count($child) > $class_count) {
  231. $child = array_slice($child, 0, $class_count);
  232. }
  233. foreach ($componetList as $key => $value) {
  234. $componentData = $value['componentData'];
  235. //取出imgSize和textSize,获取相应的文章,
  236. $category_id = $child[$key] ?? 0;
  237. $imgSize = $componentData['imgSize'] ?? 0;
  238. $textSize = $componentData['textSize'] ?? 0;
  239. $listType = $componentData['listType'] ?? [];
  240. var_dump($listType, 'before unset listType');
  241. // 定义要移除的元素数组
  242. $valuesToRemove = ['category_name', 'pinyin'];
  243. // 循环移除每个元素
  244. foreach ($valuesToRemove as $value) {
  245. while (($key = array_search($value, $listType)) !== false) {
  246. // 移除该元素
  247. unset($listType[$key]);
  248. }
  249. }
  250. var_dump($listType, 'listType');
  251. //child
  252. $child = $componentData['child'] ?? [];
  253. $data_class = [];
  254. //查询imgurl不为空的数据
  255. $imgArticles = Db::table('article')
  256. ->where('catid', $category_id)
  257. ->whereNotNull('imgurl')
  258. ->limit($imgSize)
  259. // ->select($listType)
  260. ->orderBy('updated_at', 'desc')
  261. ->get()
  262. ->toArray();
  263. //拼接上拼音
  264. foreach ($imgArticles as $k => $v) {
  265. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  266. }
  267. //查询imgurl为空的数据
  268. $textArticles = Db::table('article')
  269. ->where('catid', $category_id)
  270. ->whereNull('imgurl')
  271. ->limit($textSize)
  272. ->orderBy('updated_at', 'desc')
  273. ->get()
  274. ->toArray();
  275. //拼接上拼音
  276. foreach ($textArticles as $k => $v) {
  277. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  278. }
  279. $data_class['alias'] = $websiteInfoIndexed[$category_id]->alias ?? 'aliasnull' . $category_id;
  280. $data_class['pinyin'] = $websiteInfoIndexed[$category_id]->pinyin ?? 'aliasnull' . $category_id;
  281. $data_class['category_id'] = $category_id;
  282. $data_class['textnum'] = $textArticles;
  283. $data_class['imgnum'] = $imgArticles;
  284. $data['data'] = $data_class;
  285. }
  286. break;
  287. case 'list':
  288. $componetListdata = $data['template']['list']['data'];
  289. $category_id = $data['template']['list']['category_id'] ?? 0;
  290. foreach ($componetListdata as $k => $v) {
  291. if (!isset($v['componentList']) || !is_array($v['componentList'])) {
  292. continue; // 如果 componentList 不存在或不是数组,跳过当前循环
  293. }
  294. $componentList = &$data['template']['list']['data'][$k]['componentList'];
  295. var_dump(count($componentList), 'componentList111');
  296. foreach ($componentList as $key => $value) {
  297. $componentData = $value['componentData'];
  298. if (isset($value['componentData']['category_id'])) {
  299. $value['componentData']['category_id'] = $category_id;
  300. $page = $componentData['papageTypege']['page'] ?? 1;
  301. $pageSize = $componentData['papageTypege']['pageSize'] ?? 10;
  302. $listType = $componentData['listType'];
  303. $articals = Db::table('article')
  304. ->where('catid', $category_id)
  305. ->where('status', 1)
  306. ->orderBy('updated_at', 'desc')
  307. ->get();
  308. // ->paginate($pageSize, ['*'], 'page', $page);
  309. //拼接上拼音
  310. foreach ($articals as $k => $v) {
  311. $articals[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  312. }
  313. $value['componentData']['data'] = $articals;
  314. }
  315. var_dump(isset($value['componentData']['level']), $key, '---------------------------------------');
  316. if (isset($value['componentData']['level'])) {
  317. //取出imgSize和textSize,获取相应的文章,
  318. $imgSize = $componentData['imgnum'] ?? 0;
  319. $textSize = $componentData['textnum'] ?? 0;
  320. $listType = $componentData['listType'] ?? [];
  321. // 定义要移除的元素数组
  322. $valuesToRemove = ['category_name', 'pinyin'];
  323. // 循环移除每个元素
  324. foreach ($valuesToRemove as $value) {
  325. while (($key = array_search($value, $listType)) !== false) {
  326. // 移除该元素
  327. unset($listType[$key]);
  328. }
  329. }
  330. //查询imgurl不为空的数据
  331. $imgArticles = Db::table('article')
  332. ->where('catid', $category_id)
  333. ->whereNotNull('imgurl')
  334. ->limit($imgSize)
  335. ->orderBy('updated_at', 'desc')
  336. ->get()
  337. ->toArray();
  338. //拼接上拼音
  339. foreach ($imgArticles as $k => $v) {
  340. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  341. }
  342. //查询imgurl为空的数据
  343. $textArticles = Db::table('article')
  344. ->where('catid', $category_id)
  345. ->whereNull('imgurl')
  346. ->limit($textSize)
  347. ->orderBy('updated_at', 'desc')
  348. ->get()
  349. ->toArray();
  350. //拼接上拼音
  351. foreach ($textArticles as $k => $v) {
  352. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  353. }
  354. //将查询到的数据放到componentData里
  355. $componetList[$key]['componentData']['data']['alias'] = $websiteInfoIndexed[$category_id]->alias ?? 'aliasnull' . $category_id;
  356. $componetList[$key]['componentData']['data']['pinyin'] = $websiteInfoIndexed[$category_id]->pinyin ?? 'aliasnull' . $category_id;
  357. $componetList[$key]['componentData']['data']['category_id'] = $category_id;
  358. $componetList[$key]['componentData']['data']['textnum'] = $textArticles;
  359. $componetList[$key]['componentData']['data']['imgnum'] = $imgArticles;
  360. //将修改后的数据放到template里
  361. // $data['template']['list']['data'][0]['componentList'] = $componetList;
  362. }
  363. }
  364. }
  365. break;
  366. case 'article':
  367. $article_id = 51434; //假设这是文章ID
  368. $componetListdata = &$data['template']['article']['data'];
  369. var_dump($categoryIds, '----------------');
  370. // $category_id = $data['template']['article']['category_id'] ?? 0;
  371. foreach ($componetListdata as $k => $v) {
  372. foreach ($v['componentList'] as $key => $value) {
  373. $componentData = $value['componentData'];
  374. if (isset($value['componentData']['article_id'])) {
  375. $value['componentData']['article_id'] = $article_id;
  376. // $page = $componentData['papageTypege']['page'] ?? 1;
  377. // $pageSize = $componentData['papageTypege']['pageSize'] ?? 10;
  378. $listType = $componentData['listType'];
  379. //查询数据
  380. $articals = Db::table('article')
  381. ->where('id', $article_id)
  382. ->where('status', 1)
  383. ->leftJoin('article_data', 'article.id', '=', 'article_data.article_id')
  384. ->select('article.*', 'article_data.content')
  385. ->orderBy('updated_at', 'desc')
  386. ->get();
  387. //拼接上拼音
  388. $value['componentData']['data'] = $articals;
  389. }
  390. if (isset($value['componentData']['level'])) {
  391. //:1:头条 2:轮播图 3:推荐图 4:最新新闻;5:推荐新闻;6:热点资讯 7:自动关联
  392. //4 update 5 30天之内 6 库中
  393. $level = $componentData['level'] ?? 0;
  394. $imgSize = $componentData['imgnum'] ?? 0;
  395. $textSize = $componentData['textnum'] ?? 0;
  396. if (in_array($level, [1, 2, 3, 6])) {
  397. //查询imgurl不为空的数据
  398. $imgArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNotNull('imgurl')
  399. ->where('status', 1)
  400. ->whereRaw('MATCH(level_text) AGAINST(? IN NATURAL LANGUAGE MODE)', [$level])
  401. ->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  402. //拼接上拼音
  403. foreach ($imgArticles as $k => $v) {
  404. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  405. }
  406. //查询imgurl为空的数据
  407. $textArticles = Db::table('article')->where('catid', $categoryIds)->whereNull('imgurl')
  408. ->where('status', 1)
  409. ->whereRaw('MATCH(level_text) AGAINST(? IN NATURAL LANGUAGE MODE)', [$level])
  410. ->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  411. //拼接上拼音
  412. foreach ($textArticles as $k => $v) {
  413. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  414. }
  415. } else if ($level == 4) {
  416. //查询imgurl不为空的数据
  417. $imgArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNotNull('imgurl')
  418. ->where('status', 1)
  419. ->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  420. //拼接上拼音
  421. if (!empty($imgArticles)) {
  422. foreach ($imgArticles as $k => $v) {
  423. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  424. }
  425. }
  426. //查询imgurl为空的数据
  427. $textArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNull('imgurl')
  428. ->where('status', 1)
  429. ->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  430. //拼接上拼音
  431. var_dump('---4------');
  432. if (!empty($textArticles)) {
  433. foreach ($textArticles as $k => $v) {
  434. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  435. }
  436. }
  437. } else if ($level == 5) {
  438. var_dump($value['componentData']['level'], 'level');
  439. //查询imgurl不为空的数据
  440. $imgArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNotNull('imgurl')
  441. ->where('status', 1)
  442. //最近三十天
  443. ->where('updated_at', '>=', date('Y-m-d H:i:s', strtotime('-30 days')))
  444. ->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  445. //拼接上拼音
  446. if (!empty($imgArticles)) {
  447. foreach ($imgArticles as $k => $v) {
  448. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  449. }
  450. }
  451. //查询imgurl为空的数据
  452. $textArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNull('imgurl')
  453. ->where('status', 1)
  454. ->where('updated_at', '>=', date('Y-m-d H:i:s', strtotime('-30 days')))
  455. ->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  456. //拼接上拼音
  457. var_dump('---5------');
  458. if (!empty($textArticles)) {
  459. foreach ($textArticles as $k => $v) {
  460. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  461. }
  462. }
  463. } else if ($level == 7) {
  464. //获取artical的keyword
  465. $keword = DB::table('artical')->where('id', $article_id)->select('keyword')->get();
  466. $kewordl = $keword[0]->keyword;
  467. $kewordl = explode(',', $kewordl);
  468. //筛选出符合条件的article来
  469. $imgArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNotNull('imgurl')
  470. ->where('status', 1)
  471. // ->whereJsonContains('keyword', $kewordl)
  472. ->whereRaw('MATCH(keyword) AGAINST(? IN NATURAL LANGUAGE MODE)', [$kewordl])
  473. ->limit($imgSize)->orderBy('updated_at', 'desc')->get()->toArray();
  474. //拼接上拼音
  475. foreach ($imgArticles as $k => $v) {
  476. $imgArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  477. }
  478. $textArticles = Db::table('article')->whereIn('catid', $categoryIds)->whereNull('imgurl')
  479. ->where('status', 1)
  480. // ->whereJsonContains('keyword', $kewordl)
  481. ->whereRaw('MATCH(keyword) AGAINST(? IN NATURAL LANGUAGE MODE)', [$kewordl])
  482. ->limit($textSize)->orderBy('updated_at', 'desc')->get()->toArray();
  483. //拼接上拼音
  484. foreach ($textArticles as $k => $v) {
  485. $textArticles[$k]->pinyin = $catiall[$v->catid][0] ?? '=====';
  486. }
  487. }
  488. }
  489. $value['componentData']['data']['imgnum'] = $imgArticles ?? [];
  490. $value['componentData']['data']['textnum'] = $textArticles ?? [];
  491. }
  492. }
  493. break;
  494. case 'search':
  495. break;
  496. case 'aboutList':
  497. $fact_id = 7;
  498. $componetList = &$data['template']['aboutList']['componentData'];
  499. $componetList['fact_id'] = $fact_id;
  500. $content = Db::table('footer_content')
  501. ->where('fcat_id', $fact_id)
  502. ->orderBy('updated_at', 'desc')
  503. ->get()
  504. ->toArray();
  505. $componetList['data'] = $content;
  506. break;
  507. case 'aboutArticle':
  508. $fact_id = 7;
  509. $componetList = &$data['template']['aboutList']['componentData'];
  510. $componetList['fact_id'] = $fact_id;
  511. $content = Db::table('footer_content')
  512. ->where('id', $fact_id)
  513. ->orderBy('updated_at', 'desc')
  514. ->get()
  515. ->toArray();
  516. $componetList['data'] = $content;
  517. break;
  518. default:
  519. $componetList = [];
  520. break;
  521. }
  522. return $data;
  523. }
  524. public function indexData1(array $data): array
  525. {
  526. $time1 = microtime(true);
  527. // 解析模板数据
  528. $templateData = json_decode($data['template'], true);
  529. $website_id = $templateData['base']['website_id'] ?? 2;
  530. $componentList = $templateData['template']['index'][0]['componentList'];
  531. // 1️⃣ 获取网站分类信息
  532. $websiteInfo = Db::table('website_category')
  533. ->where('website_id', $website_id)
  534. ->get()
  535. ->toArray();
  536. // 构建索引和拼音映射
  537. $websiteInfoIndexed = array_column($websiteInfo, null, 'category_id');
  538. $categoryIds = array_column($websiteInfo, 'category_id');
  539. $aliasPinyins = array_column($websiteInfo, 'aLIas_pinyin');
  540. $cat_arr = array_combine($categoryIds, $aliasPinyins);
  541. // 构建 catiall 和 cat_1st_arr
  542. $catiall = [];
  543. $cat_1st_arr = [];
  544. foreach ($websiteInfo as $item) {
  545. $arrId = json_decode($item->category_arr_id);
  546. $pinyin_str = implode('/', array_map(fn($id) => $cat_arr[$id], $arrId));
  547. $pinyin_str = rtrim($pinyin_str, '/');
  548. $catiall[$item->category_id][] = $pinyin_str;
  549. $websiteInfoIndexed[$item->category_id]->pinyin = $pinyin_str;
  550. if ($item->pid == 0) {
  551. $cat_1st_arr[$item->category_id] = [];
  552. } else {
  553. $cat_1st_arr[$item->pid][] = $item->category_id;
  554. }
  555. }
  556. // 2️⃣ 提前聚合所有需要查询的 category_id 和限制参数
  557. $allCatIds = [];
  558. $imgLimits = [];
  559. $txtLimits = [];
  560. $childImgLimits = [];
  561. $childTxtLimits = [];
  562. foreach ($componentList as $item) {
  563. $componentData = $item['componentData'];
  564. $category_id = $componentData['category_id'] ?? 0;
  565. if ($category_id > 0) {
  566. $allCatIds[] = $category_id;
  567. $imgLimits[$category_id] = $componentData['imgSize'] ?? 0;
  568. $txtLimits[$category_id] = $componentData['textSize'] ?? 0;
  569. if (!empty($cat_1st_arr[$category_id])) {
  570. $allCatIds = array_merge($allCatIds, $cat_1st_arr[$category_id]);
  571. }
  572. }
  573. // 子级
  574. $child = $componentData['child'] ?? null;
  575. if ($child && isset($child['id']) && $child['id'] > 0) {
  576. $child_id = $child['id'];
  577. $childImgLimits[$child_id] = $child['imgSize'] ?? 0;
  578. $childTxtLimits[$child_id] = $child['textSize'] ?? 0;
  579. }
  580. }
  581. $allCatIds = array_unique(array_filter($allCatIds));
  582. // 3️⃣ 一次性查询所有 article 数据
  583. $allArticles = Db::table('article')
  584. ->whereIn('catid', $allCatIds)
  585. ->where('status', 1)
  586. ->get()
  587. ->toArray();
  588. // 构建按 imgurl 分类的文章集合
  589. $articlesByCat = ['img' => [], 'txt' => []];
  590. foreach ($allArticles as $article) {
  591. if (!empty($article->imgurl)) {
  592. $articlesByCat['img'][$article->catid][] = $article;
  593. } else {
  594. $articlesByCat['txt'][$article->catid][] = $article;
  595. }
  596. }
  597. // 4️⃣ 使用协程并发处理每个组件
  598. $results = [];
  599. foreach ($componentList as $key => $value) {
  600. $componentKey = $key;
  601. $componentData = $value['componentData'];
  602. Coroutine::create(function () use (&$results, $componentKey, $componentData, $websiteInfoIndexed, $cat_1st_arr, $catiall, $articlesByCat, $imgLimits, $txtLimits, $childImgLimits, $childTxtLimits) {
  603. $result = [];
  604. $category_id = $componentData['category_id'] ?? 0;
  605. $imgLimit = $imgLimits[$category_id] ?? 0;
  606. $txtLimit = $txtLimits[$category_id] ?? 0;
  607. if ($category_id > 0) {
  608. // 图文数据
  609. $imgArticles = array_slice($articlesByCat['img'][$category_id] ?? [], 0, $imgLimit);
  610. foreach ($imgArticles as &$v) {
  611. $v->pinyin = $catiall[$v->catid][0] ?? '';
  612. }
  613. // 纯文字数据
  614. $textArticles = array_slice($articlesByCat['txt'][$category_id] ?? [], 0, $txtLimit);
  615. foreach ($textArticles as &$v) {
  616. $v->pinyin = $catiall[$v->catid][0] ?? '';
  617. }
  618. $result['imgnum'] = $imgArticles;
  619. $result['textnum'] = $textArticles;
  620. $result['alias'] = $websiteInfoIndexed[$category_id]['alias'] ?? '';
  621. $result['pinyin'] = $websiteInfoIndexed[$category_id]['pinyin'] ?? '';
  622. $result['category_id'] = $category_id;
  623. }
  624. // 子级处理
  625. $child = $componentData['child'] ?? null;
  626. if ($child && isset($child['id']) && $child['id'] > 0) {
  627. $child_id = $child['id'];
  628. $c_imgLimit = $childImgLimits[$child_id] ?? 0;
  629. $c_txtLimit = $childTxtLimits[$child_id] ?? 0;
  630. $childImg = array_slice($articlesByCat['img'][$child_id] ?? [], 0, $c_imgLimit);
  631. foreach ($childImg as &$v) {
  632. $v->pinyin = $catiall[$v->catid][0] ?? '';
  633. }
  634. $childText = array_slice($articlesByCat['txt'][$child_id] ?? [], 0, $c_txtLimit);
  635. foreach ($childText as &$v) {
  636. $v->pinyin = $catiall[$v->catid][0] ?? '';
  637. }
  638. $result['child'] = [
  639. 'alias' => $websiteInfoIndexed[$child_id]['alias'] ?? '',
  640. 'pinyin' => $websiteInfoIndexed[$child_id]['pinyin'] ?? '',
  641. 'category_id' => $child_id,
  642. 'textnum' => $childText,
  643. 'imgnum' => $childImg,
  644. 'all_childcat' => array_map(fn($v) => $websiteInfoIndexed[$v], $cat_1st_arr[$category_id] ?? []),
  645. ];
  646. }
  647. $results[$componentKey] = $result;
  648. });
  649. }
  650. // 等待所有协程完成(生产环境应使用 WaitGroup)
  651. usleep(200000); // 示例中简单等待
  652. // 5️⃣ 回填结果到 componentList
  653. foreach ($componentList as $key => &$component) {
  654. $componentData = $component['componentData'];
  655. $category_id = $componentData['category_id'] ?? 0;
  656. if (isset($results[$key])) {
  657. $component['componentData']['data'] = $results[$key];
  658. }
  659. }
  660. // 6️⃣ 返回最终数据
  661. $templateData['template']['index'][0]['componentList'] = $componentList;
  662. return $templateData;
  663. }
  664. public function addWeb($data)
  665. {
  666. $result = WebsiteTemplate::insertGetId($data);
  667. if ($result) {
  668. return Result::success($result);
  669. } else {
  670. return Result::error('添加失败');
  671. }
  672. }
  673. public function deleteWeb($data)
  674. {
  675. $result = WebsiteTemplate::where('id', $data['id'])->delete();
  676. if ($result) {
  677. return Result::success($result);
  678. } else {
  679. return Result::error('删除失败');
  680. }
  681. }
  682. public function updateWeb($data)
  683. {
  684. $result = WebsiteTemplate::where('id', $data['id'])->update($data);
  685. if ($result) {
  686. return Result::success($result);
  687. } else {
  688. return Result::error('更新失败');
  689. }
  690. }
  691. public function getWebInfo($data)
  692. {
  693. $result = WebsiteTemplate::where('website_template.id', $data['id'])
  694. ->leftJoin('website', 'website.id', '=', 'website_template.website_id')
  695. ->select('website_template.*', 'website.website_name as website_name', 'website.website_url as website_url')
  696. ->first();
  697. return Result::success($result);
  698. }
  699. public function getWebList($data)
  700. {
  701. var_dump($data, 'data');
  702. $where = [];
  703. if (isset($data['website_name'])) {
  704. $where[] = ['website.website_name', 'like', '%' . $data['website_name'] . '%'];
  705. }
  706. if (isset($data['status'])) {
  707. $where[] = ['website_template.status', '=', $data['status']];
  708. }
  709. $result = WebsiteTemplate::where([])
  710. ->where($where)
  711. ->leftJoin('website', 'website.id', '=', 'website_template.website_id')
  712. ->select('website_template.*', 'website.website_name as website_name', 'website.website_url as website_url')
  713. ->get();
  714. if ($result) {
  715. return Result::success($result);
  716. } else {
  717. return Result::error('获取列表失败');
  718. }
  719. }
  720. public function updateWebConfig($data)
  721. {
  722. // 先根据
  723. // 根据是否测试环境配置不同 的vue项目的 配置文件
  724. //获取根目录下 yuan 源代码,开始处理
  725. //获取目前目录,获取根目录
  726. $root = dirname(dirname(__DIR__));
  727. $yuan = $root . '/yuan';
  728. //取出envAPP_ENV=dev
  729. $APP_ENV = env('APP_ENV');
  730. switch ($APP_ENV) {
  731. case 'dev':
  732. $file = $yuan . '/plugins/category.ts';
  733. break;
  734. case 'prod':
  735. $file = $yuan . '/plugins/category.ts';
  736. break;
  737. default:
  738. $file = $yuan . '/plugins/category.ts';
  739. }
  740. //处理文件plugins\category.ts
  741. //找到 export default defineNuxtPlugin((nuxtApp) => {,处理到文件结尾
  742. /*
  743. export default defineNuxtPlugin((nuxtApp) => {
  744. //master 环境
  745. nuxtApp.provide('pageNav', navMaster)
  746. //pre 环境
  747. // nuxtApp.provide('pageNav', navPre)
  748. })
  749. */
  750. if (0 == 1) {
  751. $content = file_get_contents($file);
  752. $content = str_replace("nuxtApp.provide('pageNav', navPre)", "//nuxtApp.provide('pageNav', navPre)", $content);
  753. $content = str_replace("//nuxtApp.provide('pageNav', navMaster)", "nuxtApp.provide('pageNav', navMaster)", $content);
  754. //写入文件
  755. $res = file_put_contents($file, $content);
  756. var_dump('已经处理/plugins/category.ts');
  757. //处理文件\plugins\globals.js
  758. $file = $yuan . '/plugins/globals.js';
  759. $content = file_get_contents($file);
  760. // 1️⃣ 将没有注释的 nuxtApp.provide(...) 行加上注释
  761. $content = preg_replace('/^(?!\s*\/\/)(?=.*nuxtApp\.provide)/m', '// ', $content);
  762. // 2️⃣ 找到 "//乡村网正式环境" 下面的注释行并取消注释
  763. $lines = explode("\n", $content);
  764. $output = [];
  765. $foundSection = false;
  766. foreach ($lines as $line) {
  767. // 判断是否进入目标区域
  768. if (preg_match('/\/\/乡村网正式环境/', $line)) {
  769. $foundSection = true;
  770. $output[] = $line;
  771. continue;
  772. }
  773. // 在目标区域内,去掉注释
  774. if ($foundSection && preg_match('/^\s*\/\/\s*(nuxtApp\.provide)/', $line, $matches)) {
  775. $output[] = preg_replace('/^\s*\/\/\s*/', '', $line, 1);
  776. } else {
  777. // 如果遇到下一个注释块或空白行,结束当前处理
  778. if ($foundSection && preg_match('/^\s*$/', $line)) {
  779. $foundSection = false;
  780. }
  781. $output[] = $line;
  782. }
  783. }
  784. // 合并回字符串
  785. $newContent = implode("\n", $output);
  786. // 写入文件
  787. $res1 = file_put_contents($file, $newContent);
  788. var_dump($res1, '已经处理/plugins/globals.js');
  789. //处理文件\plugins\request.js
  790. $file = $yuan . '/plugins/request.js';
  791. $content = file_get_contents($file);
  792. $lines = explode("\n", $content);
  793. $in_prod = false;
  794. $in_pre = false;
  795. for ($i = 0; $i < count($lines); $i++) {
  796. $line = $lines[$i];
  797. // 匹配 "//正式环境"
  798. if (preg_match('/\/\/正式环境/', $line)) {
  799. $in_prod = true;
  800. $in_pre = false;
  801. continue;
  802. }
  803. // 匹配 "//pre环境"
  804. if (preg_match('/\/\/pre环境/', $line)) {
  805. $in_pre = true;
  806. $in_prod = false;
  807. continue;
  808. }
  809. // 处理正式环境下的两行:去注释
  810. if ($in_prod && $i + 0 <= count($lines) && $i + 1 <= count($lines)) {
  811. for ($j = $i + 0; $j <= $i + 1; $j++) {
  812. if (isset($lines[$j])) {
  813. $lines[$j] = preg_replace('/^\s*\/\/\s*/', '', $lines[$j]);
  814. }
  815. }
  816. $in_prod = false; // 只处理一次
  817. }
  818. // 处理 pre 环境下的两行:添加注释
  819. if ($in_pre && $i + 0 <= count($lines) && $i + 1 <= count($lines)) {
  820. for ($j = $i + 1; $j <= $i + 2; $j++) {
  821. if (isset($lines[$j]) && !preg_match('/^\s*\/\//', $lines[$j])) {
  822. // $lines[$j] = '// ' . $lines[$j];
  823. }
  824. }
  825. $in_pre = false; // 只处理一次
  826. }
  827. }
  828. // 写回文件
  829. $res2 = file_put_contents($file, implode("\n", $lines));
  830. var_dump($res2, '已经处理/plugins/request.js');
  831. echo "✅ 环境配置切换完成!";
  832. //第三步 定位到yuan目录,执行 npm run build 生成output目录
  833. chdir($yuan);
  834. $APP_ENV = env('APP_ENV');
  835. $res3 = exec("npm run build");
  836. var_dump($res, '执行 npm run build');
  837. echo "✅ 构建完成!";
  838. //第四步
  839. //修改 .output\server\chunks\routes\index.mjs ,
  840. // 根据网站的id的port更改端口
  841. //第五步
  842. //x
  843. $file4 = $yuan . '/.output/server/chunks/routes/index.mjs';
  844. $content = file_get_contents($file4);
  845. // 使用正则将 "destr(...) || 3e3" 替换为 "destr(...) || 9000"
  846. $content = preg_replace(
  847. '/(destr$[^)]+$$\s*\|\|\s*)3e3/i',
  848. '$19000',
  849. $content
  850. );
  851. // 写回文件
  852. file_put_contents($file, $content);
  853. }
  854. //第六步 yuan压缩成压缩包,复制到/hyperf-skeleton/web1/,解压
  855. $dir_yuan = $yuan . '/.output/';
  856. // 移动到web 没有就创建
  857. $dir_web = '/hyperf-skeleton/' . '/web1/';
  858. if (!is_dir($dir_web)) {
  859. mkdir($dir_web, 0755, true);
  860. }
  861. $fs = new Filesystem();
  862. $fs->rename($dir_yuan, $dir_web . 'output', true);
  863. var_dump('已经移动到/hyperf-skeleton/web1/output');
  864. $result = [
  865. 'res' => $res,
  866. 'res1' => $res1,
  867. 'res2' => $res2,
  868. 'res3' => $res3,
  869. 'root' => $root,
  870. 'yuan' => $yuan,
  871. 'APP_ENV' => $APP_ENV,
  872. 'website_id' => $data['website_id'],
  873. ];
  874. if ($result) {
  875. return Result::success($result);
  876. } else {
  877. return Result::error('更新配置失败');
  878. }
  879. }
  880. public function updateWebOutput($data)
  881. {
  882. //根据源程序, 复制出来,更改配置文件,打包,
  883. $result = WebsiteTemplate::where('id', $data['id'])->update($data);
  884. if ($result) {
  885. return Result::success($result);
  886. } else {
  887. return Result::error('更新输出失败');
  888. }
  889. }
  890. public function updateWebMove($data)
  891. {
  892. //更改到dir目录,
  893. $result = WebsiteTemplate::where('id', $data['id'])->update($data);
  894. if ($result) {
  895. return Result::success($result);
  896. } else {
  897. return Result::error('更新移动失败');
  898. }
  899. }
  900. public function runWeb($data)
  901. {
  902. //运行网站, 先检查是否有配置文件, pm2启动
  903. $result = WebsiteTemplate::where('id', $data['id'])->update($data);
  904. if ($result) {
  905. return Result::success($result);
  906. } else {
  907. return Result::error('运行失败');
  908. }
  909. }
  910. public function stopWeb($data)
  911. {
  912. $result = WebsiteTemplate::where('id', $data['id'])->update($data);
  913. if ($result) {
  914. return Result::success($result);
  915. } else {
  916. return Result::error('停止失败');
  917. }
  918. }
  919. }