FormService.php 23 KB

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