FormService.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. namespace App\JsonRpc;
  3. use Hyperf\RpcServer\Annotation\RpcService;
  4. use App\Tools\Result;
  5. use App\Model\GlobalTable;
  6. use Hyperf\DbConnection\Db;
  7. use App\Model\GlobalTableField;
  8. use App\Model\GlobalTableFieldType;
  9. use App\Model\GlobalTableFieldValue;
  10. use App\Model\Website;
  11. use Hyperf\Di\Annotation\Inject;
  12. use Hyperf\Redis\Redis;
  13. #[RpcService(name: "FormService", protocol: "jsonrpc-http", server: "jsonrpc-http")]
  14. class FormService implements FormServiceInterface
  15. {
  16. #[Inject]
  17. protected Redis $redis;
  18. /**
  19. * 添加全局表单
  20. * @param array $data
  21. * @return array|mixed
  22. */
  23. public function addGlobalTable(array $data): array
  24. {
  25. // 过滤掉空值
  26. $data = array_filter($data, function($value) {
  27. return !empty($value);
  28. });
  29. // 检查是否已存在相同名称的记录
  30. $globalTable = GlobalTable::on('global')->where(['table'=> $data['table']])->first();
  31. if (empty($globalTable)) {
  32. $id = GlobalTable::on('global')->insertGetId($data);
  33. //给global库创建表 表名为$data['table'] 的值,并初始化一个字段id,类型为int,自增,主键,再初始化一个字段title,类型为varchar,长度为255
  34. Db::connection('global')->statement("CREATE TABLE IF NOT EXISTS `{$data['table']}` (
  35. `id` int(11) NOT NULL AUTO_INCREMENT,
  36. `title` varchar(255) DEFAULT NULL,
  37. `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  38. `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  39. PRIMARY KEY (`id`)
  40. )");
  41. //给GlobalTableField表初始化数据
  42. GlobalTableField::on('global')->insert([
  43. [
  44. 'table_id' => $id,
  45. 'field_name' => 'id',
  46. 'title' => '编号',
  47. 'field_type' => '1',
  48. 'length' => 255,
  49. 'sort' => 0,
  50. 'is_check' => 1,
  51. 'admin_display' => 1,
  52. 'home_display' => 1,
  53. 'disable_del' => 1,
  54. ],
  55. [
  56. 'table_id' => $id,
  57. 'field_name' => 'title',
  58. 'title' => '标题',
  59. 'field_type' => '1',
  60. 'length' => 255,
  61. 'sort' => 0,
  62. 'is_check' => 1,
  63. 'admin_display' => 1,
  64. 'home_display' => 1,
  65. 'disable_del' => 1,
  66. ],
  67. [
  68. 'table_id' => $id,
  69. 'field_name' => 'updated_at',
  70. 'title' => '更新时间',
  71. 'field_type' => '1',
  72. 'length' => 255,
  73. 'sort' => 999,
  74. 'is_check' => 1,
  75. 'admin_display' => 1,
  76. 'home_display' => 0,
  77. 'disable_del' => 1,
  78. ],
  79. [
  80. 'table_id' => $id,
  81. 'field_name' => 'created_at',
  82. 'title' => '创建时间',
  83. 'field_type' => '1',
  84. 'length' => 255,
  85. 'sort' => 1000,
  86. 'is_check' => 1,
  87. 'admin_display' => 0,
  88. 'home_display' => 0,
  89. 'disable_del' => 1,
  90. ],
  91. ]);
  92. return Result::success('添加成功');
  93. }
  94. return Result::error('表单已存在');
  95. }
  96. /**
  97. * 获取全局表单列表
  98. * @param array $data
  99. * @return array
  100. */
  101. public function getGlobalTableList(array $data): array
  102. {
  103. try {
  104. // 构建查询
  105. $query = GlobalTable::query()
  106. ->when(!empty($data['name']), function($q) use ($data) {
  107. return $q->where('name', 'like', '%' . $data['name'] . '%');
  108. })
  109. ->when(!empty($data['website_id']), function($q) use ($data) {
  110. return $q->where('website_id', $data['website_id']);
  111. })
  112. ->leftJoin('hyperf.website', 'hyperf.website.id', '=', 'global_table.website_id')
  113. ->select('global_table.*', 'hyperf.website.website_name');
  114. // 分页参数
  115. $page = (int)($data['page'] ?? 1);
  116. $pageSize = (int)($data['pageSize'] ?? 10);
  117. // 先获取总数
  118. $total = $query->count();
  119. // 获取数据
  120. $list = $query->orderBy('updated_at', 'desc')
  121. ->offset(($page - 1) * $pageSize)
  122. ->limit($pageSize)
  123. ->get();
  124. // 如果没有数据,直接返回空结果
  125. if ($list->isEmpty()) {
  126. return Result::success([
  127. 'list' => [],
  128. 'total' => $total,
  129. 'page' => $page,
  130. 'pageSize' => $pageSize
  131. ]);
  132. }
  133. // 合并数据并返回
  134. return Result::success([
  135. 'list' => $list,
  136. 'total' => $total,
  137. 'page' => $page,
  138. 'pageSize' => $pageSize
  139. ]);
  140. } catch (\Throwable $e) {
  141. return Result::error('查询失败:' . $e->getMessage());
  142. }
  143. }
  144. /**
  145. * 获取全局表单
  146. * @param array $data
  147. * @return array
  148. */
  149. public function getGlobalTable(array $data): array
  150. {
  151. $globalTable = GlobalTable::where('id',$data['id'])->first();
  152. return Result::success($globalTable);
  153. }
  154. /**
  155. * 修改全局表单
  156. * @param array $data
  157. * @return array
  158. */
  159. public function upGlobalTable(array $data): array
  160. {
  161. $globalTable = GlobalTable::where('id',$data['id'])->first();
  162. if(empty($globalTable)){
  163. return Result::error('表单不存在');
  164. }
  165. $data = array_filter($data,function($value){
  166. return $value !== null;
  167. });
  168. GlobalTable::where(['id'=>$data['id']])->update($data);
  169. return Result::success('修改成功');
  170. }
  171. /**
  172. * 删除全局表单
  173. * @param array $data
  174. * @return array
  175. */
  176. public function delGlobalTable(array $data): array
  177. {
  178. $globalTable = GlobalTable::where('id', $data['id'])->first();
  179. if(empty($globalTable)){
  180. return Result::error('表单不存在');
  181. }
  182. //删除global库的表
  183. Db::connection('global')->statement("DROP TABLE IF EXISTS `{$globalTable->table}`");
  184. //删除GlobalTableField表中table_id为$data['id']的数据
  185. GlobalTableField::where('table_id', $data['id'])->delete();
  186. GlobalTable::where('id', $data['id'])->delete();
  187. return Result::success('删除成功');
  188. }
  189. /**
  190. * 获取表单字段列表
  191. * @param array $data
  192. * @return array
  193. */
  194. public function getGlobalTableFieldList(array $data): array
  195. {
  196. $fields = GlobalTableField::from('global_table_field as a')
  197. ->join('global_table_field_type as b', 'a.field_type', '=', 'b.id')
  198. ->where('a.table_id', $data['id'])
  199. ->whereNotIn('a.field_name',['id','created_at','updated_at'])
  200. ->orderBy('a.sort', 'asc')
  201. ->select(
  202. // global_table_field 所有字段
  203. 'a.*',
  204. // global_table_field_type 字段
  205. 'b.type_name',
  206. 'b.type_name_alias',
  207. 'b.field_type as type_definition'
  208. )
  209. ->get();
  210. return Result::success($fields);
  211. }
  212. /**
  213. * 获取表单字段
  214. * @param array $data
  215. * @return array
  216. */
  217. public function getGlobalTableField(array $data): array
  218. {
  219. $globalTableField = GlobalTableField::where('id',$data['id'])->first();
  220. return Result::success($globalTableField);
  221. }
  222. /**
  223. * 添加表单字段
  224. * @param array $data
  225. * @return array
  226. * @throws \Throwable
  227. */
  228. public function addGlobalTableField(array $data): array
  229. {
  230. $globalTable = GlobalTable::where('id',$data['table_id'])->first();
  231. if(empty($globalTable)){
  232. return Result::error('表单不存在');
  233. }
  234. //检查是否已存在相同名称的记录
  235. $globalTableField = GlobalTableField::where(['table_id'=>$data['table_id'],'field_name'=>$data['field_name']])->first();
  236. if(!empty($globalTableField)){
  237. return Result::error('字段已存在');
  238. }
  239. // 检查表中是否已存在该列
  240. try {
  241. $columns = Db::connection('global')->select("SHOW COLUMNS FROM `{$globalTable->table}`");
  242. $columnNames = array_column($columns, 'Field');
  243. if (in_array($data['field_name'], $columnNames)) {
  244. return Result::error('字段名已存在于数据表中');
  245. }
  246. } catch (\Throwable $e) {
  247. return Result::error('检查字段是否存在时出错:' . $e->getMessage());
  248. }
  249. $globalTableFieldTypeInfo = GlobalTableFieldType::where('id',$data['field_type'])->first();
  250. //给global库的表添加字段
  251. Db::connection('global')->statement("ALTER TABLE `{$globalTable->table}` ADD COLUMN `{$data['field_name']}` {$globalTableFieldTypeInfo['field_type']}({$data['length']}) COMMENT '{$data['title']}'");
  252. //给GlobalTableField表添加数据
  253. GlobalTableField::create($data);
  254. return Result::success('添加成功');
  255. }
  256. /**
  257. * 修改表单字段
  258. * @param array $data
  259. * @return array
  260. * @throws \Throwable
  261. */
  262. public function upGlobalTableField(array $data): array
  263. {
  264. $globalTable = GlobalTable::where('id',$data['table_id'])->first();
  265. if(empty($globalTable)){
  266. return Result::error('表单不存在');
  267. }
  268. //检查是否已存在相同名称的记录
  269. $globalTableField = GlobalTableField::where(['table_id'=>$data['table_id'],'field_name'=>$data['field_name']])->first();
  270. if(!empty($globalTableField) && $globalTableField->id != $data['id']){
  271. return Result::error('字段已存在');
  272. }
  273. $globalTableFieldTypeInfo = GlobalTableFieldType::where('id',$data['field_type'])->first();
  274. //给global库的表修改字段
  275. Db::connection('global')->statement("ALTER TABLE `{$globalTable->table}` CHANGE COLUMN `{$data['field_name']}` `{$data['field_name']}` {$globalTableFieldTypeInfo['field_type']}({$data['length']}) COMMENT '{$data['title']}'");
  276. //给GlobalTableField表修改数据
  277. GlobalTableField::where('id',$data['id'])->update($data);
  278. return Result::success('修改成功');
  279. }
  280. /**
  281. * 删除表单字段
  282. * @param array $data
  283. * @return array
  284. * @throws \Throwable
  285. */
  286. public function delGlobalTableField(array $data): array
  287. {
  288. $tableFieldInfo = GlobalTableField::where('id',$data['id'])->first();
  289. if(empty($tableFieldInfo)){
  290. return Result::error('字段不存在');
  291. }
  292. $globalTable = GlobalTable::where('id',$tableFieldInfo['table_id'])->first();
  293. if(empty($globalTable)){
  294. return Result::error('表单不存在');
  295. }
  296. //给global库的表删除字段
  297. Db::connection('global')->statement("ALTER TABLE `{$globalTable->table}` DROP COLUMN `{$tableFieldInfo['field_name']}`");
  298. //给GlobalTableField表删除数据
  299. GlobalTableField::where('id',$data['id'])->delete();
  300. return Result::success('删除成功');
  301. }
  302. /**
  303. * 获取自定义生成表里面的数据
  304. */
  305. public function getGlobalTableData(array $data): array
  306. {
  307. try {
  308. //查询global库的表GlobalTableField模型中table_id为$data['id']的数据条件为admin_display=1的数据
  309. $globalTableFields = GlobalTableField::where(['table_id'=>$data['id'],'admin_display'=>1])->orderBy('sort','asc')->get();
  310. $globalTableFields->transform(function ($field) {
  311. $optionValue = [];
  312. $optionStr = trim((string) $field->option);
  313. if (!empty($optionStr)) {
  314. $options = explode("\n", $optionStr);
  315. foreach ($options as $option) {
  316. $parts = explode('|', $option);
  317. if (count($parts) === 2) {
  318. $optionValue[$parts[1]] = $parts[0];
  319. }
  320. }
  321. }
  322. $field->option_value = $optionValue;
  323. return $field;
  324. });
  325. //查询global库的表GlobalTable模型中id为$data['id']的数据
  326. $globalTable = GlobalTable::where('id',$data['id'])->first();
  327. if(empty($globalTable)){
  328. return Result::error('表单不存在');
  329. }
  330. // 构建查询
  331. $query = Db::connection('global')->table($globalTable->table);
  332. // 添加title模糊搜索
  333. if (!empty($data['title'])) {
  334. $query->where('title', 'like', '%' . $data['title'] . '%');
  335. }
  336. // 分页参数
  337. $page = (int)($data['page'] ?? 1);
  338. $pageSize = (int)($data['pageSize'] ?? 10);
  339. // 先获取总数
  340. $total = $query->count();
  341. // 获取分页数据
  342. $list = $query->select($globalTableFields->pluck('field_name')->toArray())
  343. ->orderBy('id', 'desc')
  344. ->offset(($page - 1) * $pageSize)
  345. ->limit($pageSize)
  346. ->get();
  347. // 转换字符串数组为实际数组
  348. $list->transform(function ($item) use ($globalTableFields) {
  349. foreach ($globalTableFields as $field) {
  350. $fieldName = $field->field_name;
  351. if (isset($item->$fieldName) && is_string($item->$fieldName)) {
  352. // 尝试解析JSON格式的字符串
  353. $decoded = json_decode($item->$fieldName, true);
  354. if (json_last_error() === JSON_ERROR_NONE) {
  355. $item->$fieldName = $decoded;
  356. }
  357. // 如果是简单的逗号分隔字符串,也可以转换为数组
  358. elseif (strpos($item->$fieldName, ',') !== false) {
  359. $item->$fieldName = array_map('trim', explode(',', $item->$fieldName));
  360. }
  361. }
  362. }
  363. return $item;
  364. });
  365. return Result::success([
  366. 'tableFields' => $globalTableFields,
  367. 'list' => $list,
  368. 'total' => $total,
  369. 'page' => $page,
  370. 'pageSize' => $pageSize
  371. ]);
  372. } catch (\Throwable $e) {
  373. return Result::error('查询失败:' . $e->getMessage());
  374. }
  375. }
  376. /**
  377. * 获取字段类型列表
  378. */
  379. public function getGlobalTableFieldTypeList(array $data): array
  380. {
  381. try {
  382. $list = Db::connection('global')->table("global_table_field_type")->get();
  383. return Result::success($list);
  384. }catch (\Throwable $e){
  385. return Result::error('查询失败:' . $e->getMessage());
  386. }
  387. }
  388. /**
  389. * 删除自定义表里面的某一条数据
  390. */
  391. public function delGlobalTableData(array $data): array
  392. {
  393. try {
  394. //查询global库的表GlobalTable模型中id为$data['id']的数据
  395. $globalTable = GlobalTable::where('id',$data['table_id'])->first();
  396. if(empty($globalTable)){
  397. return Result::error('表单不存在');
  398. }
  399. // 构建查询
  400. $query = Db::connection('global')->table($globalTable->table);
  401. $query->where('id',$data['id']);
  402. $query->delete();
  403. return Result::success('删除成功');
  404. }catch (\Throwable $e){
  405. return Result::error('删除失败:' . $e->getMessage());
  406. }
  407. }
  408. /**
  409. * 修改自定义表里面的某一条数据
  410. */
  411. public function updateGlobalTableData(array $data): array
  412. {
  413. try {
  414. $globalTable = GlobalTable::where('id', $data['table_id'])->first();
  415. if (empty($globalTable)) {
  416. return Result::error('表单不存在');
  417. }
  418. unset($data['table_id']);
  419. // 转换数组字段为字符串
  420. $data = array_map(function ($value) {
  421. if (is_array($value)) {
  422. return json_encode($value, JSON_UNESCAPED_UNICODE);
  423. }
  424. return $value;
  425. }, $data);
  426. $query = Db::connection('global')->table($globalTable->table);
  427. $query->where('id', $data['id'])->update($data);
  428. return Result::success('修改成功');
  429. } catch (\Throwable $e) {
  430. return Result::error('修改失败:' . $e->getMessage());
  431. }
  432. }
  433. /**
  434. * 查看自定义表里面的某条数据
  435. */
  436. public function getGlobalTableDataById(array $data): array
  437. {
  438. try {
  439. //查询
  440. $globalTable = GlobalTable::where('id',$data['table_id'])->first();
  441. if(empty($globalTable)){
  442. return Result::error('表单不存在');
  443. }
  444. $query = Db::connection('global')->table($globalTable->table);
  445. $query->where('id',$data['id']);
  446. $dataInfo = $query->first();
  447. $globalTableField = GlobalTableField::where(['table_id'=>$data['table_id']])->get();
  448. $globalTableField->transform(function ($field) {
  449. $optionValue = [];
  450. $optionStr = trim((string) $field->option);
  451. if (!empty($optionStr)) {
  452. $options = explode("\n", $optionStr);
  453. foreach ($options as $option) {
  454. $parts = explode('|', $option);
  455. if (count($parts) === 2) {
  456. $optionValue[$parts[1]] = $parts[0];
  457. }
  458. }
  459. }
  460. $field->option_value = $optionValue;
  461. return $field;
  462. });
  463. $return = [
  464. 'data'=>$dataInfo,
  465. 'tableFields'=>$globalTableField->toArray(),
  466. ];
  467. return Result::success($return);
  468. }catch (\Throwable $e){
  469. return Result::error('查询失败:' . $e->getMessage());
  470. }
  471. }
  472. /**
  473. * 查询网站下表单自定义字段
  474. */
  475. public function getWebGlobalTableFieldList(array $data): array
  476. {
  477. try {
  478. $globalTable = GlobalTable::where('id',$data['table_id'])->first();
  479. $websiteInfo = Website::where('id',$data['website_id'])->first();
  480. if(empty($websiteInfo)){
  481. return Result::error('网站不存在');
  482. }else{
  483. $globalTable['website_name'] = $websiteInfo['website_name'];
  484. $globalTable['suffix'] = $websiteInfo['suffix'];
  485. }
  486. $fields = GlobalTableField::from('global_table_field as a')
  487. ->join('global_table_field_type as b', 'a.field_type', '=', 'b.id')
  488. ->where('a.table_id', $data['table_id'])
  489. ->where('a.field_name',"<>",'id')
  490. ->where('a.home_display', 1)
  491. ->orderBy('a.sort', 'asc')
  492. ->select(
  493. // global_table_field 所有字段
  494. 'a.*',
  495. // global_table_field_type 字段
  496. 'b.type_name',
  497. 'b.type_name_alias',
  498. 'b.field_type as type_definition'
  499. )
  500. ->get();
  501. $fields->transform(function ($field) {
  502. $optionValue = [];
  503. $optionStr = trim((string) $field->option);
  504. if (!empty($optionStr)) {
  505. $options = explode("\n", $optionStr);
  506. foreach ($options as $option) {
  507. $parts = explode('|', $option);
  508. if (count($parts) === 2) {
  509. $optionValue[$parts[1]] = $parts[0];
  510. }
  511. }
  512. }
  513. $field->option_value = $optionValue;
  514. return $field;
  515. });
  516. $config = new \EasySwoole\VerifyCode\Config();
  517. $code = new \EasySwoole\VerifyCode\VerifyCode($config);
  518. $img_code = '';
  519. $characters = '0123456789';
  520. $charLength = strlen($characters);
  521. for ($i = 0; $i < 4; $i++) {
  522. $img_code .= $characters[rand(0, $charLength - 1)];
  523. }
  524. //重写验证码
  525. $result = $code->DrawCode((string)$img_code);
  526. $img_code = $result->getImageCode();
  527. var_dump("验证码:",$img_code);
  528. $code_uniqid = uniqid("code");
  529. //写入缓存 用于其他方法验证 并且设置过期时间
  530. $this->redis->set($code_uniqid,$img_code,60000);
  531. $rep = [
  532. 'fields' => $fields,
  533. 'table'=>$globalTable,
  534. ];
  535. if($globalTable->is_code){
  536. $rep['code']['code_uniqid'] = $code_uniqid;
  537. $rep['code']['img'] = $result->getImageBase64();
  538. }
  539. return Result::success($rep);
  540. }catch (\Throwable $e){
  541. return Result::error('查询失败:' . $e->getMessage());
  542. }
  543. }
  544. /**
  545. * web端创建数据
  546. * @param array $data
  547. * @return array
  548. */
  549. public function addWebGlobalTableData(array $data): array
  550. {
  551. try {
  552. $globalTable = GlobalTable::where('id',$data['otherData']['table_id'])->first();
  553. if($globalTable->is_code){
  554. if(empty($data['otherData']['code'])){
  555. return Result::error('请输入验证码');
  556. }
  557. $code = $this->redis->get($data['otherData']['code_uniqid']);
  558. if(empty($code)){
  559. return Result::error('验证码已过期');
  560. }
  561. if($data['otherData']['code'] != $code){
  562. return Result::error('验证码错误');
  563. }
  564. }
  565. if(empty($globalTable)){
  566. return Result::error('表单不存在');
  567. }
  568. $query = Db::connection('global')->table($globalTable->table);
  569. $data['data'] = array_map(function ($value) {
  570. if (is_array($value)) {
  571. return json_encode($value, JSON_UNESCAPED_UNICODE);
  572. }
  573. return $value;
  574. }, $data['data']);
  575. $query->insert($data['data']);
  576. return Result::success([]);
  577. }catch (\Throwable $e){
  578. return Result::error('添加失败:' . $e->getMessage());
  579. }
  580. }
  581. }