ConfigRepository.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\system\config;
  12. use app\common\dao\system\config\SystemConfigDao;
  13. use app\common\model\system\config\SystemConfigClassify;
  14. use app\common\repositories\BaseRepository;
  15. use app\common\repositories\system\CacheRepository;
  16. use FormBuilder\Exception\FormBuilderException;
  17. use FormBuilder\Factory\Elm;
  18. use FormBuilder\Form;
  19. use think\db\exception\DataNotFoundException;
  20. use think\db\exception\DbException;
  21. use think\db\exception\ModelNotFoundException;
  22. use think\facade\Db;
  23. use think\facade\Route;
  24. /**
  25. * 系统配置
  26. */
  27. class ConfigRepository extends BaseRepository
  28. {
  29. const TYPES = ['input' => '文本框', 'number' => '数字框', 'textarea' => '多行文本框', 'radio' => '单选框', 'switches' => '开关', 'checkbox' => '多选框', 'select' => '下拉框', 'file' => '文件上传', 'image' => '图片上传', 'images' => '多图片上传', 'color' => '颜色选择框'];
  30. /**
  31. * ConfigRepository constructor.
  32. * @param SystemConfigDao $dao
  33. */
  34. public function __construct(SystemConfigDao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * 根据商家ID、配置分类和配置信息,生成表单规则。
  40. * 该方法主要用于构建表单的规则和结构,根据不同的商家ID和配置分类,动态生成表单用于数据的录入和修改。
  41. *
  42. * @param int $merId 商家ID,用于区分是商家配置还是平台配置。
  43. * @param SystemConfigClassify $configClassify 配置分类对象,包含分类的键和名称。
  44. * @param array $configs 配置信息数组,包含所有的配置项。
  45. * @param array $formData 已填写的表单数据数组,用于预填充表单。
  46. * @return Elm|Form
  47. */
  48. public function formRule(int $merId, SystemConfigClassify $configClassify, array $configs, array $formData = [])
  49. {
  50. // 根据配置信息和商家ID获取表单组件规则
  51. $components = $this->getRule($configs, $merId);
  52. // 创建表单,设置表单的提交URL和组件
  53. $form = Elm::createForm(Route::buildUrl($merId ? 'merchantConfigSave' : 'configSave', ['key' => $configClassify->classify_key])->build(), $components);
  54. // 设置表单的标题为配置分类的名称,并过滤掉表单数据中的空值
  55. return $form->setTitle($configClassify->classify_name)->formData(array_filter($formData, function ($item) {
  56. return $item !== '' && !is_null($item);
  57. }));
  58. }
  59. /**
  60. * 根据配置数组和商家ID获取组件规则
  61. *
  62. * 本函数通过遍历给定的配置数组,针对每个配置项调用getComponent方法,
  63. * 并将结果收集到一个数组中返回。这样做的目的是为了根据不同的配置和商家ID,
  64. * 组装出一系列的组件规则。
  65. *
  66. * @param array $configs 配置数组,包含需要生成组件的配置信息
  67. * @param string $merId 商家ID,用于生成特定商家的组件规则
  68. * @return array 返回包含所有组件的数组
  69. */
  70. public function getRule(array $configs, $merId)
  71. {
  72. // 初始化一个空数组,用于存放遍历过程中生成的组件
  73. $components = [];
  74. // 遍历配置数组,针对每个配置生成一个组件
  75. foreach ($configs as $config) {
  76. // 调用getComponent方法生成组件,并将结果添加到组件数组中
  77. $component = $this->getComponent($config, $merId);
  78. $components[] = $component;
  79. }
  80. // 返回包含所有组件的数组
  81. return $components;
  82. }
  83. /**
  84. * 根据配置信息获取组件实例
  85. *
  86. * 该方法根据传入的配置信息和商家ID,动态生成并返回相应的组件实例。
  87. * 支持的组件类型包括图片、图片组、文件上传、下拉选择、复选框、单选框、开关等。
  88. * 对于不同的组件类型,会根据配置规则设置相应的属性和选项。
  89. *
  90. * @param array $config 配置信息,包含组件的类型、键、名及其他配置项
  91. * @param int $merId 商家ID,用于判断是商家后台还是管理员后台的配置
  92. * @return \think\component\Elm 组件实例
  93. */
  94. public function getComponent($config, $merId)
  95. {
  96. // 根据配置的类型动态处理
  97. switch ($config['config_type']) {
  98. case 'image':
  99. // 创建图片组件,设置图片地址和一些属性
  100. $component = Elm::frameImage($config['config_key'], $config['config_name'], '/' . config('admin.' . ($merId ? 'merchant' : 'admin') . '_prefix') . '/setting/uploadPicture?field=' . $config['config_key'] . '&type=1')->icon('el-icon-camera')->modal(['modal' => false])->width('1000px')->height('600px')->props(['footer' => false]);
  101. break;
  102. case 'images':
  103. // 创建图片组组件,设置图片地址和一些属性
  104. $component = Elm::frameImage($config['config_key'], $config['config_name'], '/' . config('admin.' . ($merId ? 'merchant' : 'admin') . '_prefix') . '/setting/uploadPicture?field=' . $config['config_key'] . '&type=2')->maxLength(5)->icon('el-icon-camera')->modal(['modal' => false])->width('1000px')->height('600px')->props(['footer' => false]);
  105. break;
  106. case 'file':
  107. // 创建文件上传组件,设置上传地址和头部令牌
  108. $component = Elm::uploadFile($config['config_key'], $config['config_name'], rtrim(systemConfig('site_url'), '/') . Route::buildUrl('configUpload', ['field' => 'file'])->build())->headers(['X-Token' => request()->token()]);
  109. break;
  110. case 'select':
  111. case 'checkbox':
  112. // 处理下拉选择和复选框,根据配置规则生成选项
  113. $options = array_map(function ($val) {
  114. [$value, $label] = explode(':', $val, 2);
  115. return compact('value', 'label');
  116. }, explode("\n", $config['config_rule']));
  117. $component = Elm::{$config['config_type']}($config['config_key'], $config['config_name'])->options($options);
  118. break;
  119. case 'radio':
  120. // 处理单选框,包括联动效果
  121. $options = array_map(function ($val) {
  122. [$value, $label] = explode(':', $val, 2);
  123. return compact('value', 'label');
  124. }, explode("\n", $config['config_rule']));
  125. $component = Elm::{$config['config_type']}($config['config_key'], $config['config_name'])->options($options);
  126. //处理联动显示
  127. $controls = $this->dao->search([])->where('linked_status', 1)->where('linked_id', $config['config_id'])->column('config_id,config_key,linked_value');
  128. $restructuredArray = [];
  129. foreach ($controls as $c) {
  130. $restructuredArray[$c['linked_value']][] = $c['config_key'];
  131. }
  132. $restructuredArray = array_map(function($k, $v) {
  133. return ['value' => (string) $k, 'rule' => $v];
  134. }, array_keys($restructuredArray), $restructuredArray);
  135. if (!empty($restructuredArray)) {
  136. $component->control($restructuredArray);
  137. }
  138. break;
  139. case 'switches':
  140. // 创建开关组件,并处理联动效果
  141. $component = Elm::{$config['config_type']}($config['config_key'], $config['config_name'])->activeText('开')->inactiveText('关');
  142. //处理联动显示
  143. $controls = $this->dao->search([])->where('linked_status', 1)->where('linked_id', $config['config_id'])->column('config_id,config_key,linked_value');
  144. $restructuredArray = [];
  145. foreach ($controls as $c) {
  146. $restructuredArray[$c['linked_value']][] = $c['config_key'];
  147. }
  148. $restructuredArray = array_map(function($k, $v) {
  149. return ['value' => (string) $k, 'rule' => $v];
  150. }, array_keys($restructuredArray), $restructuredArray);
  151. if (!empty($restructuredArray)) {
  152. $component->control($restructuredArray);
  153. }
  154. break;
  155. default:
  156. // 默认情况下,直接创建对应类型的组件
  157. $component = Elm::{$config['config_type']}($config['config_key'], $config['config_name']);
  158. break;
  159. }
  160. // 设置组件的必填属性
  161. if ($config['required']) $component->required();
  162. // 处理额外的配置属性
  163. if ($config['config_props'] ?? '') {
  164. $props = @parse_ini_string($config['config_props'], false, INI_SCANNER_TYPED);
  165. if (is_array($props)) {
  166. $guidance_uri = $props['guidance_uri'] ?? '';
  167. $guidance_image = $props['guidance_image'] ?? '';
  168. if ($guidance_image) {
  169. $config['guidance'] = [
  170. 'uri' => $guidance_uri,
  171. 'image' => $guidance_image,
  172. ];
  173. }
  174. if (isset($props['required']) && $props['required']) {
  175. $component->required();
  176. }
  177. if (isset($props['defaultValue'])) {
  178. $component->value($props['defaultValue']);
  179. }
  180. unset($props['guidance_image'], $props['guidance_uri']);
  181. $component->props($props);
  182. }
  183. }
  184. // 添加额外的规则信息,如帮助信息
  185. if ($config['info']) {
  186. $component->appendRule('suffix', [
  187. 'type' => 'guidancePop',
  188. 'props' => [
  189. 'info' => $config['info'],
  190. 'url' => $config['guidance']['uri'] ?? '',
  191. 'image' => $config['guidance']['image'] ?? '',
  192. ]
  193. ]);
  194. }
  195. return $component;
  196. }
  197. /**
  198. * 切换实体的状态。
  199. *
  200. * 本函数用于通过指定的ID和新的状态来更新数据库中相应实体的状态字段。
  201. * 它封装了与数据访问对象(DAO)的交互,使得业务逻辑层可以更方便地进行状态更新操作,
  202. * 而无需直接处理数据库层面的细节。
  203. *
  204. * @param int $id 实体的唯一标识符。用于在数据库中定位到特定的实体。
  205. * @param int $status 新的状态值。该值会被用于更新实体的状态字段。
  206. * @return mixed 返回DAO更新操作的结果。具体类型取决于DAO的实现。
  207. */
  208. public function switchStatus(int $id, int $status)
  209. {
  210. // 使用compact函数将$status变量打包成一个名为'status'的键值对数组,
  211. // 然后调用dao的update方法,通过$id更新数据库中的对应记录的状态。
  212. return $this->dao->update($id, compact('status'));
  213. }
  214. /**
  215. * 根据表单规则获取配置ID
  216. *
  217. * 本函数主要用于根据给定的系统配置分类和商家ID,通过特定的逻辑
  218. * 获取相应的配置ID。此过程涉及查询配置数据库并根据条件组装返回的数据。
  219. *
  220. * @param SystemConfigClassify $configClassify 系统配置分类对象,包含配置分类ID
  221. * @param int $merId 商家ID,用于确定是系统配置还是商家配置
  222. * @return mixed 返回根据表单规则处理后的配置数据
  223. */
  224. public function cidByFormRule(SystemConfigClassify $configClassify, int $merId)
  225. {
  226. // 根据配置分类ID和商家ID(0代表系统配置)查询配置信息
  227. $config = $this->dao->cidByConfig($configClassify->config_classify_id, $merId == 0 ? 0 : 1);
  228. // 获取查询到的配置项的键名集合
  229. $keys = $config->column('config_key');
  230. // 组装并返回表单规则数据,包括配置ID、分类、配置项及对应的值
  231. $formData = app()->make(ConfigValueRepository::class)->more($keys, $merId);
  232. return $this->formRule($merId, $configClassify, $config->toArray(), $formData);
  233. }
  234. /**
  235. * 创建或编辑配置项的表单
  236. *
  237. * 该方法用于生成一个包含各种输入字段的表单,用于创建或编辑配置项。表单字段包括配置的分类、类型、名称、键值等必需信息,
  238. * 以及一些可选信息如配置的说明、规则、属性等。表单的动作URL根据配置项是否有ID来决定,没有ID时创建新配置项,有ID时编辑已有的配置项。
  239. *
  240. * @param int|null $id 配置项的ID,如果为null则表示创建新配置项
  241. * @param array $formData 表单的初始数据,用于填充表单字段
  242. * @return Form 返回生成的表单对象
  243. */
  244. public function form($cid, ?int $id = null, array $formData = []): Form
  245. {
  246. $configClassifyRepository = app()->make(ConfigClassifyRepository::class);
  247. $linkData = $this->linkData($cid);
  248. if ($cid) {
  249. $formData['config_classify_id'] = (int)$cid;
  250. }
  251. $form = Elm::createForm(is_null($id) ? Route::buildUrl('configSettingCreate')->build() : Route::buildUrl('configSettingUpdate', ['id' => $id])->build());
  252. $rule = [
  253. Elm::cascader('config_classify_id', '上级分类:')->options(function () use
  254. ($configClassifyRepository){
  255. return array_merge([['value' => 0, 'label' => '请选择']], $configClassifyRepository->options());
  256. })->placeholder('请选择上级分类')->props(['props' => ['checkStrictly' => true, 'emitPath' => false]]),
  257. Elm::select('user_type', '后台类型:', 0)->options([
  258. ['label' => '总后台配置', 'value' => 0],
  259. ['label' => '商户后台配置', 'value' => 1],
  260. ])->requiredNum(),
  261. Elm::input('config_name', '配置名称:')->placeholder('请输入配置名称')->required()->placeholder('请选择后台类型')->appendRule('suffix', [
  262. 'type' => 'div',
  263. 'style' => ['color' => 'red'],
  264. 'domProps' => [
  265. 'innerHTML' =>'配置联动显示选项,需从[ 配置分类 ]菜单中的[ 配置列表 ]进入配置页',
  266. ]
  267. ]),
  268. ];
  269. if ($cid) {
  270. $rule[] = Elm::radio('linked_status', '联动显示:', 0)->options([
  271. ['label' => '否', 'value' => 0],
  272. ['label' => '是', 'value' => 1],
  273. ])->control([
  274. // 当选择未通过状态时,显示未通过原因的文本区域
  275. ['value' => 1, 'rule' => [
  276. Elm::cascader('linked_data', '上级联动:')
  277. ->options($linkData)
  278. ->props(['props' => ['multiple' => false, 'checkStrictly' => false, 'emitPath' => true]])
  279. ->placeholder('请选择上级分类')
  280. ]]
  281. ])->appendRule('suffix', [
  282. 'type' => 'div',
  283. 'style' => ['color' => '#999999'],
  284. 'domProps' => [
  285. 'innerHTML' =>'否:默认正常展示此配置;是:此配置默认隐藏,当选中下方对应配置的值时,此配置才会显示',
  286. ]
  287. ]);
  288. }
  289. $rule = array_merge($rule, [
  290. Elm::input('config_key', '配置key:')->placeholder('请输入配置key')->required(),
  291. Elm::textarea('info', '说明:')->placeholder('请输入说明'),
  292. Elm::select('config_type', '配置类型:')->options(function () {
  293. $options = [];
  294. foreach (self::TYPES as $value => $label) {
  295. $options[] = compact('value', 'label');
  296. }
  297. return $options;
  298. })->placeholder('请选择配置类型')->required(),
  299. Elm::textarea('config_rule', '选择项:')->placeholder('请输入选择项'),
  300. Elm::textarea('config_props', '配置:')->placeholder('请输入配置'),
  301. Elm::number('sort', '排序:', 0)->precision(0)->max(99999),
  302. Elm::switches('required', '必填:', 0)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开'),
  303. Elm::switches('status', '是否显示:', 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开'),
  304. ]) ;
  305. $form->setRule($rule);
  306. return $form->setTitle(is_null($id) ? '添加配置' : '编辑配置')->formData($formData);
  307. }
  308. /**
  309. * 获取联动表单数据
  310. * @param $tab_id
  311. * @return mixed
  312. * @author Qinii
  313. */
  314. public function linkData($cid)
  315. {
  316. $linkData = $this->dao->getSearch([])
  317. ->where('config_classify_id', $cid)
  318. ->whereIn('config_type',['switches','radio'])
  319. ->field('config_id value,config_name label,config_rule parameter,config_type')
  320. ->select()->toArray();
  321. foreach ($linkData as &$item) {
  322. $parameter = [];
  323. $parameter = explode("\n", $item['parameter']);
  324. if (count($parameter) > 1) {
  325. foreach ($parameter as $pv) {
  326. $pvArr = explode(':', $pv);
  327. $item['children'][] = ['label' => $pvArr[1], 'value' => (int)$pvArr[0]];
  328. }
  329. } else {
  330. $item['children'] = [
  331. ['label' => '开', 'value' => 1],
  332. ['label' => '关', 'value' => 0],
  333. ];
  334. }
  335. unset($item['parameter'], $item['config_type']);
  336. }
  337. return $linkData;
  338. }
  339. /**
  340. * 更新表单数据。
  341. * 该方法通过指定的ID获取表单数据,并使用这些数据来更新表单。
  342. * 主要用于在前端展示已存在数据的表单,以便用户可以查看并修改这些数据。
  343. *
  344. * @param int $id 表单数据的唯一标识ID。
  345. * @return array 返回包含表单数据的数组。
  346. */
  347. public function updateForm(int $id)
  348. {
  349. // 通过ID获取表单数据,并转换为数组格式,用于更新表单
  350. $formData = $this->dao->get($id)->append(['linked_data'])->toArray();
  351. return $this->form($formData['config_classify_id'],$id, $formData);
  352. }
  353. /**
  354. * 根据条件获取配置列表
  355. *
  356. * 本函数用于根据给定的条件数组$where,从数据库中检索配置列表。它支持分页查询,每页返回$limit条记录,从$page页开始。
  357. * 查询结果包括配置项的列表和总数,方便前端进行分页显示。
  358. *
  359. * @param array $where 查询条件,以键值对形式表示,用于构建SQL的WHERE子句。
  360. * @param int $page 当前页码,用于确定要返回哪一页的记录。
  361. * @param int $limit 每页返回的记录数,用于控制分页大小。
  362. * @return array 返回一个包含两个元素的数组,'count'表示记录总数,'list'表示当前页的配置项列表。
  363. */
  364. public function lst(array $where, int $page, int $limit)
  365. {
  366. // 根据$where条件搜索配置项
  367. $query = $this->dao->search($where);
  368. // 计算满足条件的配置项总数
  369. $count = $query->count();
  370. // 对查询结果进行分页,每页返回$limit条记录,并处理配置项的'typeName'属性
  371. // 通过闭包函数动态获取'types'数组中对应'config_type'的值作为'typeName'
  372. // 隐藏'config_classify_id'字段,并附加'typeName'字段后进行查询
  373. $list = $query->page($page, $limit)
  374. ->withAttr('typeName', function ($value, $data) {
  375. return self::TYPES[$data['config_type']];
  376. })
  377. ->hidden(['config_classify_id'])
  378. ->append(['typeName'])
  379. ->select();
  380. // 返回记录总数和分页后的配置项列表
  381. return compact('count', 'list');
  382. }
  383. /**
  384. * 根据分类组和商家ID生成表单选项
  385. * 该方法主要用于生成基于不同分类的配置表单。它通过遍历分类列表,并为每个分类生成相应的表单字段。
  386. * @param object $group 分类组对象,包含配置分类ID等信息。
  387. * @param int $merId 商家ID,用于确定表单数据的保存路径。
  388. * @param int $tab_id 当前选中的标签页ID,用于设置默认选中的标签页。
  389. * @return object 返回生成的表单对象,设置了标题和表单内容。
  390. */
  391. public function tabForm($group, $merId, $tab_id = 0)
  392. {
  393. $make = app()->make(ConfigClassifyRepository::class);
  394. $list = $make->children($group->config_classify_id, 'config_classify_id,classify_key,classify_name,info');
  395. $children = [];
  396. $name = '';
  397. foreach ($list as $item) {
  398. $_children = $this->cidByFormRule($make->keyByData($item['classify_key']), $merId)->formRule();
  399. if ($tab_id && $tab_id == $item['config_classify_id']) {
  400. $name = $item['classify_key'];
  401. }
  402. if ($item['info']) {
  403. array_unshift($_children, [
  404. 'type' => 'el-alert',
  405. 'props' => [
  406. 'type' => 'warning',
  407. 'closable' => false,
  408. 'title' => $item['info']
  409. ]
  410. ], ['type' => 'div', 'style' => ['height' => '20px', 'width' => '100%']]);
  411. }
  412. $children[] = [
  413. 'type' => 'el-tab-pane',
  414. 'props' => [
  415. 'label' => $item['classify_name'],
  416. 'name' => $item['classify_key']
  417. ],
  418. 'children' => $_children
  419. ];
  420. }
  421. if ($group['classify_key'] === 'distribution_tabs') {
  422. $action = Route::buildUrl('configOthersSettingUpdate')->build();
  423. } else {
  424. $action = Route::buildUrl($merId ? 'merchantConfigSave' : 'configSave', ['key' => $group['classify_key']])->build();
  425. }
  426. $form = Elm::createForm($action, [
  427. [
  428. 'type' => 'el-tabs',
  429. 'native' => true,
  430. 'props' => [
  431. 'value' => $name ?: $list[0]['classify_key'] ?? ''
  432. ],
  433. 'children' => $children
  434. ]
  435. ]);
  436. return $form->setTitle($group['classify_name']);
  437. }
  438. /**
  439. * 创建上传配置表单
  440. * 该方法用于生成上传配置的表单,根据不同的上传类型(如本地、七牛云、阿里云OSS等),
  441. * 动态配置表单的规则,以便用户可以根据需求配置不同的上传方式。
  442. *
  443. * @return \EasyWeChat\Kernel\Messages\ElementForm|Form
  444. */
  445. public function uploadForm()
  446. {
  447. // 获取上传类型配置
  448. $config = $this->getWhere(['config_key' => 'upload_type']);
  449. // 根据上传类型配置,获取对应的组件规则
  450. $rule = $this->getComponent($config, 0)->value(systemConfig('upload_type'));
  451. // 实例化配置分类仓库
  452. $make = app()->make(ConfigClassifyRepository::class);
  453. // 配置不同的上传类型对应的表单规则
  454. $rule->control([
  455. [
  456. 'value' => '1',
  457. 'rule' => $this->cidByFormRule($make->keyByData('local'), 0)->formRule()
  458. ],
  459. [
  460. 'value' => '2',
  461. 'rule' => $this->cidByFormRule($make->keyByData('qiniuyun'), 0)->formRule()
  462. ],
  463. [
  464. 'value' => '3',
  465. 'rule' => $this->cidByFormRule($make->keyByData('aliyun_oss'), 0)->formRule()
  466. ],
  467. [
  468. 'value' => '4',
  469. 'rule' => $this->cidByFormRule($make->keyByData('tengxun'), 0)->formRule()
  470. ],
  471. [
  472. 'value' => '5',
  473. 'rule' => $this->cidByFormRule($make->keyByData('huawei_obs'), 0)->formRule()
  474. ],
  475. [
  476. 'value' => '6',
  477. 'rule' => $this->cidByFormRule($make->keyByData('ucloud'), 0)->formRule()
  478. ],
  479. [
  480. 'value' => '7',
  481. 'rule' => $this->cidByFormRule($make->keyByData('jdoss'), 0)->formRule()
  482. ],
  483. [
  484. 'value' => '8',
  485. 'rule' => $this->cidByFormRule($make->keyByData('ctoss'), 0)->formRule()
  486. ],
  487. ]);
  488. return Elm::createForm(Route::buildUrl('systemSaveUploadConfig')->build(), [$rule])->setTitle('上传配置');
  489. }
  490. /**
  491. * 保存上传配置
  492. *
  493. * 该方法用于根据传入的上传类型数据,保存相应的上传配置。它支持多种上传方式,
  494. * 通过switch语句根据上传类型确定具体的上传配置键名。然后,在数据库事务中,
  495. * 先更新上传类型配置,如果上传类型有具体的配置键名,则进一步保存该上传方式的详细配置。
  496. * 这样做的目的是确保上传配置的完整性和一致性。
  497. *
  498. * @param array $data 包含上传类型等信息的数据数组
  499. */
  500. public function saveUpload($data)
  501. {
  502. // 实例化配置值仓库,用于后续保存配置数据
  503. $configValueRepository = app()->make(ConfigValueRepository::class);
  504. // 默认上传类型为1,代表本地上传
  505. $uploadType = $data['upload_type'] ?? '1';
  506. // 根据上传类型确定具体的上传方式键名
  507. $key = '';
  508. switch ($uploadType) {
  509. case 1:
  510. $key = 'local';
  511. break;
  512. case 2:
  513. $key = 'qiniuyun';
  514. break;
  515. case 3:
  516. $key = 'aliyun_oss';
  517. break;
  518. case 4:
  519. $key = 'tengxun';
  520. break;
  521. case 5:
  522. $key = 'huawei_obs';
  523. break;
  524. case 6:
  525. $key = 'ucloud';
  526. break;
  527. case 7:
  528. $key = 'jdoss';
  529. break;
  530. case 8:
  531. $key = 'ctoss';
  532. break;
  533. }
  534. // 使用数据库事务来确保配置更新和保存操作的一致性
  535. Db::transaction(function () use ($data, $key, $uploadType, $configValueRepository) {
  536. // 更新上传类型配置
  537. $configValueRepository->setFormData([
  538. 'upload_type' => $uploadType
  539. ], 0);
  540. // 如果上传方式有具体的配置键名,则进一步保存上传方式的详细配置
  541. if ($key) {
  542. // 实例化配置分类仓库,用于获取配置分类ID
  543. $make = app()->make(ConfigClassifyRepository::class);
  544. // 根据上传方式键名获取对应的配置分类ID,如果获取失败则返回错误信息
  545. if (!($cid = $make->keyById($key))) return app('json')->fail('保存失败');
  546. // 保存上传方式的详细配置
  547. $configValueRepository->save($cid, $data, 0);
  548. }
  549. });
  550. }
  551. /**
  552. * 创建微信配置上传校验文件的表单
  553. *
  554. * 本函数用于生成一个表单,该表单旨在上传一个校验文件以配置微信相关功能。
  555. * 它首先尝试从缓存中获取之前可能已上传的校验文件路径,如果文件不存在,则清空该路径。
  556. * 接着,利用ElementUI的表单构建器创建表单,并设置表单的验证规则,包括一个文件上传字段。
  557. * 最后,返回构造好的表单,表单标题为“上传校验文件”,并包含之前获取的校验文件路径数据。
  558. *
  559. * @return \Illuminate\Http\Response 返回构造好的表单视图。
  560. */
  561. public function wechatForm()
  562. {
  563. // 从缓存中获取微信校验文件的路径
  564. $formData['wechat_chekc_file'] = app()->make(CacheRepository::class)->getWhere(['key' => 'wechat_chekc_file']);
  565. // 如果文件路径存在但文件实际不存在,则清空文件路径
  566. if ($formData['wechat_chekc_file'] && !is_file($formData['wechat_chekc_file'])) {
  567. $formData['wechat_chekc_file'] = '';
  568. }
  569. // 创建表单实例,表单提交地址为配置微信上传设置的路由
  570. $form = Elm::createForm(Route::buildUrl('configWechatUploadSet')->build());
  571. // 设置表单验证规则,包括一个文件上传字段
  572. $form->setRule([
  573. // 文件上传字段,用于上传微信校验文件,设置文件上传的URL地址和安全令牌
  574. Elm::uploadFile('wechat_chekc_file', '上传校验文件:', rtrim(systemConfig('site_url'), '/') . Route::buildUrl('configUploadName', ['field' => 'file'])->build())->headers(['X-Token' => request()->token()]),
  575. ]);
  576. // 设置表单标题并返回表单实例,包含之前获取的微信校验文件路径数据
  577. return $form->setTitle('上传校验文件')->formData($formData);
  578. }
  579. /**
  580. * 替换appid
  581. * @param string $appid
  582. * @param string $projectanme
  583. */
  584. public function updateConfigJson($appId = '', $projectName = '', $path = '')
  585. {
  586. $fileUrl = $path . "/download/project.config.json";
  587. $string = file_get_contents($fileUrl); //加载配置文件
  588. // 替换appid
  589. $appIdOld = '/"appid"(.*?),/';
  590. $appIdNew = '"appid"' . ': ' . '"' . $appId . '",';
  591. $string = preg_replace($appIdOld, $appIdNew, $string); // 正则查找然后替换
  592. // 替换小程序名称
  593. $projectNameOld = '/"projectname"(.*?),/';
  594. $projectNameNew = '"projectname"' . ': ' . '"' . $projectName . '",';
  595. $string = preg_replace($projectNameOld, $projectNameNew, $string); // 正则查找然后替换
  596. $newFileUrl = $path . "/download/project.config.json";
  597. @file_put_contents($newFileUrl, $string); // 写入配置文件
  598. }
  599. /**
  600. * 替换url
  601. * @param $url
  602. */
  603. public function updateUrl($url, $path)
  604. {
  605. $fileUrl = $path . "/download/common/vendor.js";
  606. $string = file_get_contents($fileUrl); //加载配置文件
  607. $string = str_replace('https://mer.crmeb.net', $url, $string); // 正则查找然后替换
  608. $ws = str_replace('https', 'wss', $url);
  609. $string = str_replace('wss://mer.crmeb.net', $ws, $string); // 正则查找然后替换
  610. $newFileUrl = $path . "/download/common/vendor.js";
  611. @file_put_contents($newFileUrl, $string); // 写入配置文件
  612. }
  613. /**
  614. * 关闭直播
  615. * @param int $iszhibo
  616. */
  617. public function updateAppJson($path)
  618. {
  619. $fileUrl = $path . "/download/app.json";
  620. $string = file_get_contents($fileUrl); //加载配置文件
  621. $pats = '/,
  622. "plugins": \{
  623. "live-player-plugin": \{
  624. "version": "(.*?)",
  625. "provider": "(.*?)"
  626. }
  627. }/';
  628. $string = preg_replace($pats, '', $string); // 正则查找然后替换
  629. $newFileUrl = $path . "/download/app.json";
  630. @file_put_contents($newFileUrl, $string); // 写入配置文件
  631. }
  632. /**
  633. * 去掉菜单
  634. * @param int $iszhibo
  635. */
  636. public function updateRouteJson($path)
  637. {
  638. $fileUrl = $path . "/download/app.json";
  639. $string = file_get_contents($fileUrl); //加载配置文件
  640. $pats = '/
  641. {
  642. "pagePath": "pages\/plant_grass\/index",
  643. "iconPath": "static\/images\/5-001.png",
  644. "selectedIconPath": "static\/images\/5-002.png",
  645. "text": "逛逛"
  646. },/';
  647. $string = preg_replace($pats, '', $string); // 正则查找然后替换
  648. $newFileUrl = $path . "/download/app.json";
  649. @file_put_contents($newFileUrl, $string); // 写入配置文件
  650. }
  651. /**
  652. * 请求方式
  653. * @param $path
  654. * @param bool $plant
  655. * @author Qinii
  656. * @day 1/4/22
  657. */
  658. public function updatePlantJson(string $path, int $plant)
  659. {
  660. $fileUrl = $path . "/download/common/vendor.js";
  661. $string = file_get_contents($fileUrl); //加载配置文件
  662. $string = str_replace('"-openPlantGrass-"', $plant ? 'true' : 'false', $string); // 正则查找然后替换
  663. $newFileUrl = $path . "/download/common/vendor.js";
  664. @file_put_contents($newFileUrl, $string); // 写入配置文件
  665. }
  666. /**
  667. * 根据配置分类的key获取配置项key
  668. * @param string $key
  669. * @return array
  670. * @author Qinii
  671. */
  672. public function getConfigKey(string $key)
  673. {
  674. $repository = app()->make(ConfigClassifyRepository::class);
  675. $config_classify = $repository->getSearch(['classify_key' => $key])->find();
  676. $config_keys = [];
  677. if ($config_classify) {
  678. $config_keys = $this->dao->search(['config_classify_id' => $config_classify['config_classify_id']])->column('config_name,config_key');
  679. }
  680. $config_value = [];
  681. if ($config_keys) {
  682. $config_value = systemConfig(array_column($config_keys,'config_key'));
  683. }
  684. return compact('config_keys','config_value');
  685. }
  686. }