ProcessController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Administrator
  5. * Date: 2019/4/16 0016
  6. * Time: 9:51
  7. */
  8. namespace App\Http\Controllers\Admin;
  9. use App\Http\Controllers\Controller;
  10. use App\Http\Logics\Admin\ProcessLogic;
  11. use App\Http\Models\Process;
  12. use App\Http\Models\Site;
  13. use App\Http\Models\SiteProcess;
  14. use App\Http\Models\SiteRenewHistory;
  15. use App\Http\Requests\Process\RenewFormRequest;
  16. use App\Http\Traits\HasSites;
  17. use App\Libs\Ssh;
  18. use Illuminate\Http\Request;
  19. use Illuminate\Support\Facades\DB;
  20. use Illuminate\Support\Facades\Log;
  21. /**
  22. *项目流程
  23. * Class ProcessController
  24. * @package App\Http\Controllers\Admin
  25. */
  26. class ProcessController extends Controller
  27. {
  28. use HasSites;
  29. protected $logic;
  30. public function __construct(ProcessLogic $logic)
  31. {
  32. $this->logic = $logic;
  33. }
  34. //客户界面的流程
  35. public function customer()
  36. {
  37. $site = $this->hasUserOneSite();
  38. if (!$site) {
  39. return view('admin/errors/tips');
  40. }
  41. $processes = Process::query()->orderByDesc('order')->get();
  42. $siteProcessList = SiteProcess::query()->where(['site_id' => $site->id])->get()->keyBy('process_id')->toArray();
  43. return view('admin/process/customer', [
  44. 'processes' => $processes,
  45. 'siteId' => $site->id,
  46. 'processIdMapSiteProcessList' => $siteProcessList,
  47. 'site' => Site::query()->select(['id', 'domain'])->where(['id' => $site->id])->first()
  48. ]);
  49. }
  50. /**
  51. * 项目详情中的流程
  52. * @param $siteId
  53. * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
  54. */
  55. public function siteProcess($siteId)
  56. {
  57. $processes = Process::query()->orderByDesc('order')->get();
  58. $siteProcessList = SiteProcess::query()->where(['site_id' => $siteId])->get()->keyBy('process_id')->toArray();
  59. return view('admin/process/site_process', [
  60. 'processes' => $processes,
  61. 'siteId' => $siteId,
  62. 'processIdMapSiteProcessList' => $siteProcessList,
  63. 'site' => Site::query()->select(['id', 'domain'])->where(['id' => $siteId])->first()
  64. ]);
  65. }
  66. /**
  67. * 确认
  68. * @param $id
  69. * @return \Illuminate\Http\JsonResponse
  70. */
  71. public function confirm($id)
  72. {
  73. $siteProcess = SiteProcess::query()->where(['id' => $id])->first();
  74. if (!$siteProcess) return response()->json(['message' => '具体流程信息不存在'], 400);
  75. if ($siteProcess->active != 2) {
  76. return response()->json(['message' => '此流程已完成请刷新页面查看最新数据'], 400);
  77. }
  78. //判断是否全部完成检查项
  79. if (in_array($siteProcess->process_id, Process::HAS_CHECK_ITEM_IDS)) {
  80. $process = Process::query()->where(['id' => $siteProcess->process_id])->first();
  81. if (!$process) {
  82. return response()->json(['message' => '主流程信息不存在'], 400);
  83. }
  84. if (array_diff(array_column($process->check_item_scopes, 'inx'), $siteProcess->check_items ?? [])) {
  85. return response()->json(['message' => '请先完成全部检查项'], 400);
  86. }
  87. }
  88. $siteProcess->active = 1;
  89. $siteProcess->save();
  90. $logic = new ProcessLogic;
  91. $logic->changeStatus($siteProcess);
  92. $logic->nextProcess($siteProcess);
  93. return response()->json(['message' => '操作成功']);
  94. }
  95. /**
  96. * 流程检查项
  97. * @param Request $request
  98. * @param $siteProcessId
  99. * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
  100. */
  101. public function checkItem(Request $request, $siteProcessId)
  102. {
  103. $siteProcess = SiteProcess::query()->with('process')->where(['id' => $siteProcessId])->first();
  104. if (!$siteProcess) return response()->json(['message' => '流程信息不存在'], 400);
  105. if (!$request->ajax()) {
  106. return view('admin/process/check_item', [
  107. 'siteProcess' => $siteProcess
  108. ]);
  109. }
  110. $checkItems = $request->input('checkItems');
  111. if (!is_array($checkItems)) return response()->json(['message' => '检查项参数错误'], 400);
  112. $siteProcess->check_items = $checkItems;
  113. $siteProcess->save();
  114. return response()->json(['message' => '操作成功']);
  115. }
  116. /**
  117. * 续签表单
  118. * @param RenewFormRequest $request
  119. * @param $siteProcessId
  120. * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
  121. */
  122. public function renewForm(RenewFormRequest $request, $siteProcessId)
  123. {
  124. $siteProcess = SiteProcess::query()->where(['id' => $siteProcessId])->first();
  125. if (!$siteProcess) return response()->json(['message' => '续签流程信息不存在'], 400);
  126. if (!$request->ajax()) {
  127. return view('admin/process/renew_form', [
  128. 'siteProcessId' => $siteProcessId
  129. ]);
  130. }
  131. $site = Site::query()->where(['id' => $siteProcess->site_id])->first();
  132. if (!$site) return response()->json(['message' => '站点信息不存在'], 400);
  133. $validated = $request->validated();
  134. $validated['site_id'] = $siteProcess->site_id;
  135. $recordBak = [
  136. 'keyword_goal' => $site->keyword_goal,
  137. 'link_goal' => $site->link_goal,
  138. 'article_goal' => $site->article_goal,
  139. 'other_demand' => $site->other_demand
  140. ];
  141. $validated['remark'] = json_encode($recordBak);
  142. SiteRenewHistory::query()->create($validated);
  143. $site->update([
  144. 'keyword_goal' => $validated['keyword_goal'],
  145. 'link_goal' => $validated['link_goal'],
  146. 'article_goal' => $validated['article_goal'],
  147. 'other_demand' => $validated['other_demand']
  148. ]);
  149. return response()->json(['message' => '操作成功']);
  150. }
  151. //初始化项目流程
  152. public function initProcess($siteId)
  153. {
  154. if (SiteProcess::query()->where(['site_id' => $siteId])->exists()) {
  155. return response()->json(['message' => '流程已经存在不需要初始化'], 400);
  156. }
  157. $this->logic->initProcess($siteId);
  158. return response()->json(['message' => '操作成功']);
  159. }
  160. //续费历史记录
  161. public function renewHistory($siteId)
  162. {
  163. $historyList = SiteRenewHistory::query()->where(['site_id' => $siteId])->orderByDesc('id')->get();
  164. return view('admin/process/renew_history', [
  165. 'historyList' => $historyList
  166. ]);
  167. }
  168. //打分和反馈
  169. public function scoreFeedback(Request $request, $id)
  170. {
  171. $siteProcess = SiteProcess::query()->where(['id' => $id])->first();
  172. if (!$siteProcess) return response()->json(['message' => '流程信息不存在'], 400);
  173. if (!$request->ajax()) {
  174. return view('admin/process/score_feedback', [
  175. 'siteProcess' => $siteProcess
  176. ]);
  177. }
  178. $inputs = $request->input();
  179. if (empty($inputs['score']) || empty($inputs['feedback'])) {
  180. return response()->json(['message' => '请填写表单内容'], 422);
  181. }
  182. if ($siteProcess->active != 2) {
  183. return response()->json(['message' => '此流程已完成请刷新页面查看最新数据'], 400);
  184. }
  185. $siteProcess->active = 1;
  186. $siteProcess->save();
  187. $logic = new ProcessLogic;
  188. $logic->changeStatus($siteProcess);
  189. $logic->nextProcess($siteProcess);
  190. $siteProcess->evaluate = [
  191. 'score' => $inputs['score'],
  192. 'feedback' => $inputs['feedback']
  193. ];
  194. $siteProcess->save();
  195. return response()->json(['message' => '操作成功']);
  196. }
  197. //回复
  198. public function reply(Request $request, $siteProcessId)
  199. {
  200. $siteProcess = SiteProcess::query()->where(['id' => $siteProcessId])->first();
  201. if (!$siteProcess) return response()->json(['message' => '流程信息不存在'], 400);
  202. if (!$request->ajax()) {
  203. return view('admin/process/reply', [
  204. 'siteProcess' => $siteProcess
  205. ]);
  206. }
  207. $reply = $request->input('reply');
  208. if (!$reply) {
  209. return response()->json(['message' => '回访记录不能为空'], 422);
  210. }
  211. $siteProcess->reply = $reply;
  212. $siteProcess->save();
  213. return response()->json(['message' => '操作成功']);
  214. }
  215. /**
  216. * 流程激活
  217. * @param Request $request
  218. * @return \Illuminate\Http\JsonResponse
  219. */
  220. public function active(Request $request)
  221. {
  222. $siteProcess = SiteProcess::query()->where(['id' => $request->input('siteProcessId')])->first();
  223. if (!$siteProcess) {
  224. return response()->json(['message' => '流程信息不存在'], 400);
  225. }
  226. $siteProcess->active = 1;
  227. $siteProcess->save();
  228. return response()->json(['message' => '操作成功']);
  229. }
  230. /**
  231. * 文件上传
  232. * @param Request $request
  233. * @param $siteProcessId
  234. * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
  235. */
  236. public function fileUpload(Request $request, $siteProcessId)
  237. {
  238. $siteProcess = SiteProcess::query()->where(['id' => $siteProcessId])->first();
  239. if (!$request->ajax()) {
  240. return view('admin/process/file_upload', [
  241. 'siteProcess' => $siteProcess
  242. ]);
  243. }
  244. if (!$siteProcess) return response()->json(['message' => '流程信息不存在'], 400);
  245. $siteProcessFileList = $siteProcess->file_list ?? [];
  246. $fileList = $request->input('file_list');
  247. if ($fileList) {
  248. $mergeFileList = array_merge($fileList, $siteProcessFileList);
  249. $siteProcess->file_list = $mergeFileList;
  250. $siteProcess->save();
  251. }
  252. return response()->json(['message' => '操作成功']);
  253. }
  254. /**
  255. * 项目部署
  256. * @param $siteId
  257. * @return \Illuminate\Http\JsonResponse
  258. */
  259. public function deploy($siteId)
  260. {
  261. /* $siteProcess = SiteProcess::query()->where(['id' => $siteProcessId])->first();
  262. if (!$siteProcess) return response()->json(['message' => '部署流程信息不存在'], 400);*/
  263. $site = Site::query()->with('server')->where(['id' => $siteId])->first();
  264. if (empty($site->server)) return response()->json(['message' => '站点服务器信息不存在'], 400);
  265. if (empty($site->domain)) return response()->json(['message' => '域名信息不存在'], 400);
  266. if ($site->database || $site->code_dir) {
  267. return response()->json(['message' => '项目数据库信息与代码目录都存在,推测该站点之前已经部署'], 400);
  268. }
  269. if (!empty($site->database)) {
  270. return response()->json(['message' => '项目已部署'], 400);
  271. }
  272. //if ($siteProcess->deploy) return response()->json(['message' => '项目已部署'], 400);
  273. $ph = pathinfo($site->domain); // pathinfo() 函数以数组的形式返回文件路径的信息
  274. $dbName = 'sdb_' . str_replace(array('-', '.'), '', $ph['filename']);
  275. $srcPath = '/repo/_sitetpl/';
  276. $tarPath = '/repo/' . $site->domain;
  277. try {
  278. Ssh::factory($site->server->server_ip, $site->server->server_user_name, $site->server->server_passwd);
  279. } catch (\Throwable $throwable) {
  280. return response()->json(['message' => $throwable->getMessage()], 400);
  281. }
  282. Log::info(Ssh::exec('cp -rf ' . $srcPath . ' ' . $tarPath));
  283. //新建数据库
  284. $db_config = array(
  285. 'connection_name' => 'new_db',
  286. 'host' => $site->server->server_ip,
  287. 'port' => '3306',
  288. 'database' => 'sdb_sucocms',
  289. 'username' => $site->server->mysql_user_name,
  290. 'password' => $site->server->mysql_passwd
  291. );
  292. $new_db = config_connection($db_config);
  293. try {
  294. DB::connection($new_db)->statement('create database ' . $dbName);
  295. } catch (\Throwable $throwable) {
  296. Log::error(var_export($throwable->getMessage(), 1));
  297. return response()->json(['message' => $throwable->getMessage()], 400);
  298. }
  299. Log::info(Ssh::exec("mysqldump sdb_sucocms -u root -p" . $site->server->mysql_passwd . " --add-drop-table | mysql " . $dbName . " -u root -p" . $site->server->mysql_passwd));
  300. //数据库配置文件
  301. $db_config_data = file_get_contents(public_path() . '/remote/db.conf.php');
  302. $db_config_data = str_replace('{$dbname}', $dbName, $db_config_data);
  303. $db_config_data = str_replace('{$mysql_user_name}', $site->server->mysql_user_name, $db_config_data);
  304. $db_config_data = str_replace('{$mysql_passwd}', $site->server->mysql_passwd, $db_config_data);
  305. file_put_contents(public_path() . '/remote/temp.db.conf.php', $db_config_data);
  306. Ssh::send(public_path() . '/remote/temp.db.conf.php', $tarPath . '/appdata/conf/db.conf.php');
  307. //vhost配置文件
  308. $vhost_config_data = file_get_contents(public_path() . '/remote/vhost.conf');
  309. $vhost_config_data = str_replace('$server_name', $ph['filename'] . '.' . $site->server->server_alias, $vhost_config_data);
  310. $vhost_config_data = str_replace('$server_alias', $ph['filename'] . '.' . $site->server->server_alias, $vhost_config_data);
  311. $vhost_config_data = str_replace('$domain', $tarPath, $vhost_config_data);
  312. file_put_contents(public_path() . '/remote/temp.vhost.conf', $vhost_config_data);
  313. Ssh::send(public_path() . '/remote/temp.vhost.conf', '/etc/httpd/conf/vhosts/' . $site->domain . '.conf');
  314. //setting配置文件
  315. $setting_config_data = file_get_contents(public_path() . '/remote/setting.conf.php');
  316. $setting_config_data = str_replace('{$sitename}', $site->en_title, $setting_config_data);
  317. $setting_config_data = str_replace('{$domain}', $site->domain, $setting_config_data);
  318. file_put_contents(public_path() . '/remote/temp.setting.conf.php', $setting_config_data);
  319. Ssh::send(public_path() . '/remote/temp.setting.conf.php', $tarPath . '/appdata/conf/setting.conf.php');
  320. //设置权限
  321. Ssh::exec('chmod -R 777 ' . $tarPath . '/appdata');
  322. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/uploads');
  323. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/sitemap.php');
  324. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/.htaccess');
  325. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/tmp.xls');
  326. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/tag_tpl.xlsx');
  327. Ssh::exec('chmod -R 777 ' . $tarPath . '/wwwroot/robots.txt');
  328. //重启服务
  329. if ($site->server->server_ip == '47.89.219.88') {
  330. Log::info(Ssh::exec('/usr/bin/sudo /etc/init.d/httpd reload'));
  331. } else {
  332. Log::info(Ssh::exec('lnmp restart'));
  333. }
  334. $site->database = $dbName;
  335. $site->code_dir = $tarPath;
  336. $site->save();
  337. $deploy=[
  338. 'db' => $dbName,
  339. 'dir' => $tarPath,
  340. 'domain' => sprintf('%s.yinqingli.net', $ph['filename'] . '.' . $site->server->server_alias)
  341. ];
  342. $data = [
  343. 'process_id' => 7,
  344. 'active' => 2,
  345. 'site_id'=>$siteId,
  346. 'deploy'=>\GuzzleHttp\json_encode($deploy)
  347. ];
  348. SiteProcess::query()->insert($data);
  349. return response()->json(['message' => '部署完成']);
  350. }
  351. }