| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798 |
- <?php
- // +----------------------------------------------------------------------
- // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
- // +----------------------------------------------------------------------
- // | Author: CRMEB Team <admin@crmeb.com>
- // +----------------------------------------------------------------------
- namespace app\services\system\config;
- use app\dao\system\config\SystemConfigDao;
- use app\services\agent\AgentManageServices;
- use app\services\BaseServices;
- use crmeb\exceptions\AdminException;
- use crmeb\services\CacheService;
- use crmeb\services\FileService;
- use crmeb\services\FormBuilder;
- use think\facade\Log;
- /**
- * 系统配置
- * Class SystemConfigServices
- * @package app\services\system\config
- * @method count(array $where = []) 获取指定条件下的count
- * @method save(array $data) 保存数据
- * @method get(int $id, ?array $field = []) 获取一条数据
- * @method update($id, array $data, ?string $key = null) 修改数据
- * @method delete(int $id, ?string $key = null) 删除数据
- * @method getUploadTypeList(string $configName) 获取上传配置中的上传类型
- */
- class SystemConfigServices extends BaseServices
- {
- /**
- * 系统配置数据访问层
- * @var SystemConfigDao
- */
- protected $dao;
- /**
- * form表单句柄
- * @var FormBuilder
- */
- protected $builder;
- /**
- * 表单数据切割符号
- * @var string
- */
- protected $cuttingStr = '=>';
- /**
- * 表单提交url
- * @var string[]
- */
- protected $postUrl = [
- // 基础配置
- 'setting' => [
- 'url' => '/setting/config/save_basics',
- 'auth' => [],
- ],
- // 服务配置
- 'serve' => [
- 'url' => '/serve/sms_config/save_basics',
- 'auth' => ['short_letter_switch'],
- ],
- // 运费配置
- 'freight' => [
- 'url' => '/freight/config/save_basics',
- 'auth' => ['express'],
- ],
- // 分销配置
- 'agent' => [
- 'url' => '/agent/config/save_basics',
- 'auth' => ['fenxiao'],
- ],
- // 积分配置
- 'marketing' => [
- 'url' => '/marketing/integral_config/save_basics',
- 'auth' => ['point'],
- ]
- ];
- /**
- * 子集控制规则联动控制,新版单个配置可以配置联动,此配置为兼容旧版数据配置,不建议使用
- * @var array[]
- */
- protected $relatedRule = [
- 'sign_status' => [
- 'son_type' => [
- 'sign_mode' => '',
- 'sign_remind' => [
- 'son_type' => [
- 'sign_remind_time' => '',
- 'sign_remind_type' => '',
- ],
- 'show_value' => 1
- ],
- 'sign_give_point' => '',
- 'sign_give_exp' => '',
- ],
- 'show_value' => 1
- ],
- 'brokerage_func_status' => [
- 'son_type' => [
- 'store_brokerage_statu' => [
- 'son_type' => ['store_brokerage_price' => ''],
- 'show_value' => 3
- ],
- 'brokerage_bindind' => '',
- 'store_brokerage_binding_status' => [
- 'son_type' => ['store_brokerage_binding_time' => ''],
- 'show_value' => 2
- ],
- 'spread_banner' => '',
- 'brokerage_level' => '',
- 'division_status' => '',
- 'agent_apply_open' => '',
- 'brokerage_window_switch' => '',
- ],
- 'show_value' => 1
- ],
- 'brokerage_user_status' => [
- 'son_type' => [
- 'uni_brokerage_price' => '',
- 'day_brokerage_price_upper' => '',
- ],
- 'show_value' => 1
- ],
- 'invoice_func_status' => [
- 'son_type' => [
- 'special_invoice_status' => '',
- ],
- 'show_value' => 1
- ],
- 'member_func_status' => [
- 'son_type' => [
- 'order_give_exp' => '',
- 'invite_user_exp' => ''
- ],
- 'show_value' => 1
- ],
- 'balance_func_status' => [
- 'son_type' => [
- 'recharge_attention' => '',
- 'recharge_switch' => '',
- 'store_user_min_recharge' => '',
- ],
- 'show_value' => 1
- ],
- 'pay_wechat_type' => [
- 'son_type' => [
- 'pay_weixin_key' => '',
- ],
- 'show_value' => 0
- ],
- 'pay_wechat_type@' => [
- 'son_type' => [
- 'pay_weixin_serial_no' => '',
- 'v3_transfer_scene_id' => '',
- 'pay_weixin_key_v3' => '',
- 'v3_pay_public_key' => '',
- 'v3_pay_public_pem' => '',
- ],
- 'show_value' => 1
- ],
- 'image_watermark_status' => [
- 'son_type' => [
- 'watermark_type' => [
- 'son_type' => [
- 'watermark_image' => '',
- 'watermark_opacity' => '',
- 'watermark_rotate' => '',
- ],
- 'show_value' => 1
- ],
- 'watermark_position' => '',
- 'watermark_x' => '',
- 'watermark_y' => '',
- 'watermark_type@' => [
- 'son_type' => [
- 'watermark_text' => '',
- 'watermark_text_size' => '',
- 'watermark_text_color' => '',
- 'watermark_text_angle' => ''
- ],
- 'show_value' => 2
- ],
- ],
- 'show_value' => 1
- ],
- 'customer_type' => [
- 'son_type' => [
- 'service_feedback' => '',
- ],
- 'show_value' => 0
- ],
- 'customer_type#' => [
- 'son_type' => [
- 'customer_phone' => '',
- ],
- 'show_value' => 1
- ],
- 'customer_type@' => [
- 'son_type' => [
- 'customer_url' => '',
- 'customer_corpId' => '',
- ],
- 'show_value' => 2
- ],
- 'pay_new_weixin_open' => [
- 'son_type' => [
- 'pay_new_weixin_mchid' => ''
- ],
- 'show_value' => 1
- ],
- 'mer_type' => [
- 'son_type' => [
- 'pay_sub_merchant_id' => '',
- 'sp_appid' => ''
- ],
- 'show_value' => 1
- ],
- 'member_card_status' => [
- 'son_type' => [
- 'member_price_status' => '',
- ],
- 'show_value' => 1
- ],
- ];
- /**
- * SystemConfigServices constructor.
- * @param SystemConfigDao $dao
- * @param FormBuilder $builder
- */
- public function __construct(SystemConfigDao $dao, FormBuilder $builder)
- {
- $this->dao = $dao;
- $this->builder = $builder;
- }
-
- /**
- * 获取单个系统配置
- * @param string $configName
- * @param null $default
- * @return mixed|null
- * @throws \ReflectionException
- */
- public function getConfigValue(string $configName, $default = null)
- {
- $value = $this->dao->getConfigValue($configName);
- return is_null($value) ? $default : json_decode($value, true);
- }
- /**
- * 获取全部配置
- * @param array $configName
- * @return array
- * @throws \ReflectionException
- */
- public function getConfigAll(array $configName = [])
- {
- return array_map(function ($item) {
- return json_decode($item, true);
- }, $this->dao->getConfigAll($configName));
- }
- /**
- * 获取配置列表搜索并分页
- * @param array $where
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function getConfigList(array $where)
- {
- [$page, $limit] = $this->getPageValue();
- $list = $this->dao->getConfigList($where, $page, $limit);
- $count = $this->dao->count($where);
- $tidy_srr = [];
- $configTabList = app()->make(SystemConfigTabServices::class)->getColumn([], 'title', 'id');
- foreach ($list as &$item) {
- $item['value'] = $item['value'] ? (json_decode($item['value'], true) ?: '') : '';
- if ($item['type'] == 'radio' || $item['type'] == 'checkbox') {
- $item['value'] = $this->getRadioOrCheckboxValueInfo($item['menu_name'], $item['value']);
- }
- if ($item['type'] == 'upload' && !empty($item['value'])) {
- if ($item['upload_type'] == 1 || $item['upload_type'] == 3) {
- $item['value'] = [set_file_url($item['value'])];
- } elseif ($item['upload_type'] == 2) {
- $tempValue = set_file_url($item['value']);
- $item['value'] = is_array($tempValue) ? $tempValue : [];
- }
- if (is_array($item['value']) && !empty($item['value'])) {
- foreach ($item['value'] as $key => $value) {
- $tidy_srr[$key]['filepath'] = $value;
- $tidy_srr[$key]['filename'] = basename($value);
- }
- $item['value'] = $tidy_srr;
- } else {
- $item['value'] = [];
- }
- }
- if ($item['level'] == 1) {
- $item['link_data'] = $this->getLinkData($item['link_id'], $item['link_value']);
- }
- $item['config_tab_name'] = $configTabList[$item['config_tab_id']] ?? '';
- }
- return compact('count', 'list');
- }
- /**
- * 配置列表页获取关联的值,展示:关联配置名称/关联值
- * @param $id
- * @param $value
- * @return string
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author wuhaotian
- * @email 442384644@qq.com
- * @date 2024/5/31
- */
- private function getLinkData($id, $value)
- {
- $info = $this->dao->get($id);
- if (!$info) return '';
- $parameter = explode("\n", $info['parameter']);
- $result = [];
- foreach ($parameter as $item) {
- $parts = explode('=>', $item);
- $result[$parts[0]] = $parts[1];
- }
- return $info['info'] . ':' . $result[$value].'(显示)';
- }
- /**
- * 配置列表页获取单选按钮或者多选按钮的显示值
- * @param $menu_name
- * @param $value
- * @return string
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- private function getRadioOrCheckboxValueInfo(string $menu_name, $value): string
- {
- $option = [];
- $config_one = $this->dao->getOne(['menu_name' => $menu_name]);
- if (!$config_one) {
- return '';
- }
- $parameter = explode("\n", $config_one['parameter']);
- foreach ($parameter as $k => $v) {
- if (isset($v) && strlen($v) > 0) {
- $data = explode('=>', $v);
- $option[$data[0]] = $data[1];
- }
- }
- $str = '';
- if (is_array($value)) {
- foreach ($value as $v) {
- $str .= $option[$v] . ',';
- }
- } else {
- $str .= !empty($value) ? $option[$value] ?? '' : $option[0] ?? '';
- }
- return $str;
- }
- /**
- * 根据配置tab id获取系统配置信息
- * @param int $tabId
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function getReadList(int $tabId)
- {
- $info = $this->dao->getConfigTabAllList($tabId);
- foreach ($info as $k => $v) {
- if (!is_null(json_decode($v['value'])))
- $info[$k]['value'] = json_decode($v['value'], true);
- if ($v['type'] == 'upload' && !empty($v['value'])) {
- if ($v['upload_type'] == 1 || $v['upload_type'] == 3) $info[$k]['value'] = explode(',', $v['value']);
- }
- }
- return $info;
- }
- /**
- * 修改字段获取form表单
- * @param int $id
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function editFieldForm(int $id)
- {
- $menu = $this->dao->get($id)->getData();
- if (!$menu) {
- throw new AdminException('数据不存在');
- }
- /** @var SystemConfigTabServices $service */
- $service = app()->make(SystemConfigTabServices::class);
- $formbuider = [];
- $linkData = $this->linkData($menu['config_tab_id']);
- $formbuider[] = $this->builder->radio('level', '联动显示', $menu['level'])->options([['value' => 0, 'label' => '否'], ['value' => 1, 'label' => '是']])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '否:默认正常展示此配置;是:此配置默认隐藏,当选中下方对应配置的值时,此配置才会显示']
- ])->appendControl(1, [
- $this->builder->cascader('link_data', '关联配置/值', [$menu['link_id'], $menu['link_value']])->options($linkData)->props(['props' => ['multiple' => false, 'checkStrictly' => false, 'emitPath' => true]])->style(['width' => '100%']),
- ])->requiredNum();
- $formbuider[] = $this->builder->input('menu_name', '字段变量', $menu['menu_name'])->disabled(1);
- $formbuider[] = $this->builder->hidden('type', $menu['type']);
- [$configTabList, $data] = $service->getConfigTabListForm((int)($menu['config_tab_id'] ?? 0));
- $formbuider[] = $this->builder->cascader('config_tab_id', '分类', $data)->options($configTabList)->filterable(true)->props(['props' => ['multiple' => false, 'checkStrictly' => true, 'emitPath' => true]])->style(['width' => '100%']);
- $formbuider[] = $this->builder->input('info', '配置名称', $menu['info'])->required('配置名称不能为空')->autofocus(1);
- $formbuider[] = $this->builder->input('desc', '配置简介', $menu['desc']);
- switch ($menu['type']) {
- case 'text':
- $menu['value'] = json_decode($menu['value'], true);
- $formbuider[] = $this->createTextInputTypeForm($menu, true);
- break;
- case 'textarea':
- $menu['value'] = json_decode($menu['value'], true);
- $formbuider[] = $this->builder->textarea('value', '默认值', $menu['value'])->rows(3);
- $formbuider[] = $this->builder->number('width', '文本框宽', (int)$menu['width'])->min(1)->max(24);
- $formbuider[] = $this->builder->number('high', '多行文本框高', (int)$menu['high'])->min(1);
- break;
- case 'radio':
- $formbuider = array_merge($formbuider, $this->createRadioForm($menu));
- $formbuider[] = $this->builder->textarea('parameter', '配置参数', $menu['parameter'] ?? '')->rows(3)->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
- break;
-
- case 'upload':
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$menu['upload_type'], $menu, true));
- break;
- case 'checkbox':
- $menu['label'] = '默认值';
- $formbuider = array_merge($formbuider, $this->createCheckboxForm($menu));
- $formbuider[] = $this->builder->textarea('parameter', '配置参数', $menu['parameter'] ?? '')->rows(3)->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
- break;
- case 'select':
- $formbuider = array_merge($formbuider, $this->createSelectForm($menu));
- $formbuider[] = $this->builder->textarea('parameter', '配置参数', $menu['parameter'] ?? '')->rows(3)->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
- break;
- case 'switch':
- $formbuider = array_merge($formbuider, $this->createSwitchForm($menu));
- break;
- }
- // 是否必填(支持JSON格式)
- $requiredData = json_decode($menu['required'], true);
- if ($requiredData && isset($requiredData['required'])) {
- $menu['required'] = $requiredData['required'] ? 1 : 0;
- } else {
- $menu['required'] = $menu['required'] ? 1 : 0;
- }
- // 非switch类型,添加是否必填字段
- if ($menu['type'] != 'switch') {
- $formbuider[] = $this->builder->radio('required', '是否必填', $menu['required'] ?? 0)->options([
- ['value' => 0, 'label' => '否'],
- ['value' => 1, 'label' => '是'],
- ])->requiredNum();
- }
- $formbuider[] = $this->builder->number('sort', '排序', (int)$menu['sort']);
- $formbuider[] = $this->builder->radio('status', '状态', $menu['status'] ?? 0)->options([
- ['value' => 1, 'label' => '显示'],
- ['value' => 0, 'label' => '隐藏'],
- ])->requiredNum();
- return create_form('编辑字段', $formbuider, $this->url('/setting/config/' . $id), 'PUT');
- }
- /**
- * 创建和编辑文本类型的输入类型表单
- * @param array $data 配置数据
- * @param bool $isEdit 是否为编辑模式
- * @return BaseForm|BaseForm[]
- */
- private function createTextInputTypeForm(array $data, bool $isEdit = false)
- {
-
-
- // 拆分必填、格式规则和数字范围(支持JSON格式)
- $requiredRules = $data['required'] ?? '';
- $requiredData = [];
-
- // 尝试解析JSON格式的验证规则
- if ($requiredRules && $requiredData = json_decode($requiredRules, true)) {
- $data['required'] = isset($requiredData['required']) && $requiredData['required'] ? 'required:true' : '';
- $data['regex'] = $requiredData['regex'] ?? '';
- $data['min'] = $requiredData['min'] ?? '';
- $data['max'] = $requiredData['max'] ?? '';
- } else {
- // 兼容旧格式:逗号分隔的字符串格式
- $data['required'] = strpos($requiredRules, 'required:true') !== false ? 'required:true' : '';
- $data['regex'] = '';
- $data['min'] = '';
- $data['max'] = '';
-
- // 提取 min 和 max
- if (preg_match('/\bmin:(-?\d+)/', $requiredRules, $minMatch)) {
- $data['min'] = (int)$minMatch[1];
- }
- if (preg_match('/\bmax:(-?\d+)/', $requiredRules, $maxMatch)) {
- $data['max'] = (int)$maxMatch[1];
- }
-
- // 提取正则表达式
- if (preg_match('/regex:(\/.+\/[gimsuy]*)/', $requiredRules, $patternMatch)) {
- $data['regex'] = $patternMatch[1];
- }
- }
-
- // 创建输入类型选择器
- $inputTypeSelect = $this->builder->select('input_type', '类型', $data['input_type'] ?? 'input')->setOptions([
- ['value' => 'input', 'label' => '文本框'],
- ['value' => 'number', 'label' => '数字'],
- ['value' => 'dateTime', 'label' => '日期时间'],
- ['value' => 'date', 'label' => '日期'],
- ['value' => 'time', 'label' => '时间'],
- ['value' => 'color', 'label' => '颜色']
- ])->required();
-
- // 正则表达式(输入框)
- $regexField = $this->builder->input('regex', '表单验证', $data['regex'] ?? '')
- ->placeholder('输入正则表达式,如:/^\d+$/')
- ->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '邮箱:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/<br>手机号:/^1[3-9]\d{9}$/<br>URL:/^https?:\/\/.+/i<br>电话:/^1[3-9]\d{9}$|^0\d{2,3}-\d{7,8}$|^400-\d{3}-\d{3}$/<br>长度:/^.{6,20}$/']
- ]);
- // 宽度字段
- $col = isset($data['width']) && $data['width'] != 0 && $data['width'] >= 4 && $data['width'] <= 24 ? (int)$data['width'] : 13;
- $widthField = $this->builder->number('width', '表单框宽', $col)->min(4)->max(24);
-
- // 不同类型的默认值
- $inputValue = $data['input_type'] == 'input' ? ($data['value'] ?? '') : '';
- $inputValueField = $this->builder->input('value', '默认值', $inputValue);
-
- $numberValue = $data['input_type'] == 'number' ? ($data['value'] ?? '0') : '';
- $numberValueField = $this->builder->input('value', '默认值', $numberValue);
-
- $dateTimeValue = $data['input_type'] == 'dateTime' ? ($data['value'] ?? date('Y-m-d H:i:s')) : '';
- $dateTimeValueField = $this->builder->dateTime('value', '默认值', $dateTimeValue);
-
- $dateValue = $data['input_type'] == 'date' ? ($data['value'] ?? date('Y-m-d')) : '';
- $dateValueField = $this->builder->date('value', '默认值', $dateValue);
-
- $timeValue = $data['input_type'] == 'time' ? ($data['value'] ?? date('H:i:s')) : '';
- $timeValueField = $this->builder->time('value', '默认值', $timeValue);
-
- $colorValue = $data['input_type'] == 'color' ? ($data['value'] ?? '#000000') : '#000000';
- $colorValueField = $this->builder->color('value', '默认值', $colorValue);
-
- // 数字类型的最小值和最大值
- $numberMinField = $this->builder->input('min', '最小值', $data['min'] ?? '')->type('number');
- $numberMaxField = $this->builder->input('max', '最大值', $data['max'] ?? '')->type('number');
-
- // 根据类型联动显示不同的控件
- $inputTypeSelect->appendControl('input', [$regexField, $inputValueField, $widthField]);
- $inputTypeSelect->appendControl('number', [$numberMinField, $numberMaxField, $numberValueField, $widthField]);
- $inputTypeSelect->appendControl('dateTime', [$dateTimeValueField]);
- $inputTypeSelect->appendControl('date', [$dateValueField]);
- $inputTypeSelect->appendControl('time', [$timeValueField]);
- $inputTypeSelect->appendControl('color', [$colorValueField]);
-
- return $inputTypeSelect;
- }
- /**
- * 创建单行表单
- * @param string $type
- * @param array $data
- * @return array
- */
- public function createTextForm(string $type, array $data)
- {
- $formbuider = [];
- $inputRule = '';
- switch ($type) {
- case 'number':
- // 解析验证规则(支持 JSON 格式)
- $requiredRules = $data['required'] ?? '';
- $requiredData = json_decode($requiredRules, true);
-
- if ($requiredData) {
- // JSON 格式
- $data['min'] = $requiredData['min'] ?? null;
- $data['max'] = $requiredData['max'] ?? null;
- } else {
- // 兼容旧格式:提取 min 和 max
- $data['min'] = null;
- $data['max'] = null;
- if (preg_match('/\bmin:(-?\d+)/', $requiredRules, $minMatch)) {
- $data['min'] = (int)$minMatch[1];
- }
- if (preg_match('/\bmax:(-?\d+)/', $requiredRules, $maxMatch)) {
- $data['max'] = (int)$maxMatch[1];
- }
- }
-
- $data['value'] = isset($data['value']) ? json_decode($data['value'], true) : 0;
- // 最小值和最大值提示(有值才显示)
- $minMaxTip = '';
- if (isset($data['min']) && $data['min'] !== null) {
- $minMaxTip = '<br>最小值:' . $data['min'];
- }
- if (isset($data['max']) && $data['max'] !== null) {
- $minMaxTip .= ($minMaxTip ? ',' : '<br>') . '最大值:' . $data['max'];
- }
- // 宽度字段
- $col = isset($data['width']) && $data['width'] != 0 && $data['width'] >= 4 && $data['width'] <= 24 ? (int)$data['width'] : 13;
- $inputRule = $this->builder->number($data['menu_name'], $data['info'], (float)$data['value'])->controls(false)->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc'] . $minMaxTip]
- ])->col($col);
- break;
- case 'dateTime':
- $inputRule = $this->builder->dateTime($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ]);
- break;
- case 'date':
- $data['value'] = json_decode($data['value'], true) ?: '';
- $inputRule = $this->builder->date($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ]);
- break;
- case 'time':
- $data['value'] = json_decode($data['value'], true) ?: '';
- $inputRule = $this->builder->time($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ]);
- break;
- case 'color':
- $data['value'] = isset($data['value']) ? json_decode($data['value'], true) : '';
- $inputRule = $this->builder->color($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ]);
- break;
- default:
- $data['value'] = isset($data['value']) ? json_decode($data['value'], true) : '';
- // 如果配置项是api或routine_api,需要添加site_url,并且是只读的
- if ($data['menu_name'] == 'api' || $data['menu_name'] == 'routine_api') {
- $inputRule = $this->builder->input($data['menu_name'], $data['info'], strpos($data['value'], 'http') === false ? sys_config('site_url') . $data['value'] : $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->col($data['width'] ?? 13)->readonly(true);
- } else {
- // 宽宽度设置
- $col = isset($data['width']) && $data['width'] != 0 && $data['width'] >= 4 && $data['width'] <= 24 ? (int)$data['width'] : 13;
-
- $inputRule = $this->builder->input($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->col($col)->placeholder('请输入'.$data['info']);
- }
- break;
- }
- // 是否必填项
- $this->isRequired($data['required']) && $inputRule = $inputRule->required($data['info'].'不能为空');
- $formbuider[] = $inputRule;
- return $formbuider;
- }
-
- /**
- * 创建多行文本框
- * @param array $data
- * @return mixed
- */
- private function createTextareaForm(array $data)
- {
- $formbuider = [];
- $textareaRule = '';
- $data['value'] = json_decode($data['value'], true) ?: '';
- if ($data['menu_name'] == 'param_filter_data') $data['value'] = base64_decode($data['value']);
- // 宽度设置
- $col = isset($data['width']) && $data['width'] < 24 && $data['width'] > 4 ? $data['width'] : 13;
- $textareaRule = $this->builder->textarea($data['menu_name'], $data['info'], $data['value'])->placeholder($data['desc'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->rows($data['high'] ?? 6)->col($col);
- // 是否必填项
- $this->isRequired($data['required']) && $textareaRule = $textareaRule->required($data['info'].'不能为空')->placeholder($data['desc']);
- $formbuider[] = $textareaRule;
- return $formbuider;
- }
- /**
- * 创建单选表单
- * @param array $data
- * @param array $control
- * @param array $control_two
- * @return array
- */
- private function createRadioForm(array $data, $control = [], $control_two = [], $control_three = [])
- {
- $formbuider = [];
- $value = json_decode($data['value'], true);
- $data['value'] = $this->normalizeOptionValue(($value === null || $value === '' || $value === false) ? '0' : $value);
- $parameter = explode("\n", $data['parameter']);
- $options = [];
- if ($parameter) {
- foreach ($parameter as $v) {
- if (strstr($v, $this->cuttingStr) !== false) {
- $pdata = explode($this->cuttingStr, $v, 2);
- $options[] = ['label' => trim($pdata[1]), 'value' => $this->normalizeOptionValue($pdata[0])];
- }
- }
- $formbuider[] = $radio = $this->builder->radio($data['menu_name'], $data['info'], $data['value'])->options($options)->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->appendValidate([
- 'required' => true,
- 'message' => $data['info'] . '必选项',
- 'trigger' => 'change',
- ])->col(13);
- if ($control) {
- $radio->appendControl($data['show_value'] ?? 1, is_array($control) ? $control : [$control]);
- }
- if ($control_two && isset($data['show_value2'])) {
- $radio->appendControl($data['show_value2'] ?? 2, is_array($control_two) ? $control_two : [$control_two]);
- }
- if ($control_three && isset($data['show_value3'])) {
- $radio->appendControl($data['show_value3'] ?? 3, is_array($control_three) ? $control_three : [$control_three]);
- }
- return $formbuider;
- }
- }
- /**
- * 创建上传组件表单
- * @param int $type
- * @param array $data
- * @param bool $showTypeSelect 是否显示上传类型选择器
- * @return array
- */
- private function createUploadForm(int $type, array $data, bool $showTypeSelect = false)
- {
- $formbuider = [];
- // 单图控件
- if($type == 1){
- $singleDataValue = json_decode($data['value'], true) ?: '';
- if ($singleDataValue != '') $singleDataValue = set_file_url($singleDataValue);
- } else{
- $singleDataValue = '';
- }
- $singleImageField = $this->builder->frameImage($data['menu_name'], $data['info'], $this->url(config('app.admin_prefix', 'admin') . '/widget.images/index', ['fodder' => $data['menu_name']], true), $singleDataValue)
- ->icon('el-icon-picture-outline')->width('950px')->height('560px')->Props(['footer' => false, 'modalTitle' => '预览'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc'] ?? '']
- ])->col(13);
-
-
- // 多图控件
- if($type == 2){
- $multiDataValue = json_decode($data['value'], true) ?: [];
- if (!empty($multiDataValue)) {
- $multiDataValue = set_file_url($multiDataValue);
- }
- } else{
- $multiDataValue = [];
- }
-
- $multiImageField = $this->builder->frameImages($data['menu_name'], $data['info'], $this->url(config('app.admin_prefix', 'admin') . '/widget.images/index', ['fodder' => $data['menu_name'], 'type' => 'many', 'maxLength' => 5], true), $multiDataValue)
- ->maxLength(5)->icon('el-icon-picture-outline')->width('950px')->height('560px')->Props(['footer' => false, 'modalTitle' => '预览'])
- ->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc'] ?? '']
- ])->col(13);
-
- // 文件控件
- if($type == 3){
- $fileDataValue = json_decode($data['value'], true) ?: '';
- if ($fileDataValue != '') $fileDataValue = set_file_url($fileDataValue);
- } else{
- $fileDataValue = '';
- }
-
- $fileField = $this->builder->uploadFile($data['menu_name'], $data['info'], $this->url('/adminapi/file/upload/1', ['type' => 1], false, true), $fileDataValue)
- ->name('file')->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc'] ?? '']
- ])->col(13)->data(['menu_name' => $data['menu_name']])->headers([
- 'Authori-zation' => app()->request->header('Authori-zation'),
- ]);
-
- // 如果需要显示类型选择器(编辑模式)
- if ($showTypeSelect) {
- // 创建上传类型的radio选择器
- $uploadTypeSelect = $this->builder->radio('upload_type', '上传类型', $type)->options($this->uploadType());
- // 联动:切换类型时显示对应的上传控件
- $uploadTypeSelect->appendControl(1, [$singleImageField]);
- $uploadTypeSelect->appendControl(2, [$multiImageField]);
- $uploadTypeSelect->appendControl(3, [$fileField]);
-
- $uploadRule = $uploadTypeSelect;
- } else {
- // 新建模式:根据类型只显示对应的上传控件
- switch ($type) {
- case 1:
- // 是否必填项
- $this->isRequired($data['required']) && $singleImageField = $singleImageField->appendValidate((new \FormBuilder\UI\Elm\Validate(\FormBuilder\UI\Elm\Validate::TYPE_STRING))->required()->message($data['info'].'请选择图片'));
- $uploadRule = $singleImageField;
- break;
- case 2:
- // 是否必填项
- $this->isRequired($data['required']) && $multiImageField = $multiImageField->appendValidate((new \FormBuilder\UI\Elm\Validate(\FormBuilder\UI\Elm\Validate::TYPE_ARRAY))->required()->message($data['info'].'请选择图片'));
- $uploadRule = $multiImageField;
- break;
- case 3:
- // 是否必填项
- $this->isRequired($data['required']) && $fileField = $fileField->appendValidate((new \FormBuilder\UI\Elm\Validate(\FormBuilder\UI\Elm\Validate::TYPE_STRING))->required()->message($data['info'].'请选择文件'));
- $uploadRule = $fileField;
- break;
- }
- }
-
- $formbuider[] = $uploadRule;
-
- return $formbuider;
- }
- /**
- * 创建单选框
- * @param array $data
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- */
- private function createCheckboxForm(array $data)
- {
- $formbuider = [];
- $checkboxRule = null;
- $data['value'] = json_decode($data['value'], true) ?: [];
- $parameter = explode("\n", $data['parameter']);
- $options = [];
- if ($parameter) {
- foreach ($parameter as $v) {
- if (strstr($v, $this->cuttingStr) !== false) {
- $pdata = explode($this->cuttingStr, $v);
- $options[] = ['label' => $pdata[1], 'value' => $pdata[0]];
- }
- }
- $checkboxRule = $this->builder->checkbox($data['menu_name'], $data['info'], $data['value'])->options($options)->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->col(13);
- }
- // 是否必填项
- $isRequired = $this->isRequired($data['required']);
- if ($isRequired) {
- $checkboxRule = $checkboxRule->required($data['info'].'至少选择一个');
- }
- $formbuider[] = $checkboxRule;
- return $formbuider;
- }
- /**
- * 创建选择框表单
- * @param array $data
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- */
- private function createSelectForm(array $data)
- {
- $formbuider = [];
- $selectRule = null;
- $data['value'] = json_decode($data['value'], true) ?: [];
- $parameter = explode("\n", $data['parameter']);
- $options = [];
- if ($parameter) {
- foreach ($parameter as $v) {
- if (strstr($v, $this->cuttingStr) !== false) {
- $pdata = explode($this->cuttingStr, $v);
- $options[] = ['label' => $pdata[1], 'value' => $pdata[0]];
- }
- }
- $selectRule = $this->builder->select($data['menu_name'], $data['info'], $data['value'])->options($options)->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->col(13);
- }
- // 是否必填项
- $this->isRequired($data['required']) && $selectRule = $selectRule->required($data['info'].'请选择');
- $formbuider[] = $selectRule;
- return $formbuider;
- }
- /**
- * 开关选择
- * @param $data
- * @return array
- * @author: 吴汐
- * @email: 442384644@qq.com
- * @date: 2023/9/6
- */
- private function createSwitchForm($data)
- {
- $formbuider = [];
- $switchRule = null;
- $data['value'] = json_decode($data['value'], true) ?: '';
- $switchRule = $this->builder->switches($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->required($data['info'].'必选项')->col(13);
- $formbuider[] = $switchRule;
- return $formbuider;
- }
- /**
- * 创建颜色选择器
- * @param array $data
- * @return mixed
- */
- private function createColorForm(array $data)
- {
- $data['value'] = json_decode($data['value'], true) ?: '';
- $formbuider[] = $this->builder->color($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => $data['desc']]
- ])->col(13);
- return $formbuider;
- }
- /**
- * 统一配置项选项值类型:普通数字保持数字,字符串编码保持字符串。
- *
- * @param mixed $value
- * @return int|string
- */
- private function normalizeOptionValue($value)
- {
- if (is_int($value)) {
- return $value;
- }
- if (is_string($value)) {
- $value = trim($value);
- if (preg_match('/^-?(0|[1-9]\d*)$/', $value)) {
- return (int)$value;
- }
- }
- return $value;
- }
- /**
- * 上传类型
- * @return array
- */
- private function uploadType(): array
- {
- return [
- ['value' => 1, 'label' => '单图']
- , ['value' => 2, 'label' => '多图']
- , ['value' => 3, 'label' => '文件']
- ];
- }
- /**
- * 根据验证规则判断是否必填项
- * @param string $required
- * @return bool
- */
- private function isRequired(string $required)
- {
- // 支持 JSON 格式
- $requiredData = json_decode($required, true);
- if ($requiredData) {
- return isset($requiredData['required']) && $requiredData['required'] ? true : false;
- }
- // 兼容旧格式:逗号分隔
- return strpos($required, 'required:true') !== false;
- }
- /**
- * 获取系统配置表单
- * @param $data
- * @param bool $control
- * @param array $controle_two
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- */
- public function formTypeShine($data, $control = false, $controle_two = [], $controle_three = [])
- {
- switch ($data['type']) {
- case 'text'://文本框
- return $this->createTextForm($data['input_type'], $data);
- case 'radio'://单选框
- return $this->createRadioForm($data, $control, $controle_two, $controle_three);
- case 'textarea'://多行文本框
- return $this->createTextareaForm($data);
- case 'upload'://文件上传
- return $this->createUploadForm((int)$data['upload_type'], $data,false);
- case 'checkbox'://多选框
- return $this->createCheckboxForm($data);
- case 'select'://多选框
- return $this->createSelectForm($data);
- // case 'color':
- // return $this->createColorForm($data);
- case 'switch'://开关
- return $this->createSwitchForm($data);
- }
- }
-
- /**
- * 根据系统多个配置自动生成form表单页面
- * @param array $list
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- private function createForm(array $list)
- {
- if (!$list) return [];
- $list = array_combine(array_column($list, 'menu_name'), $list);
- $formbuider = [];
- $sonConfig = $this->getSonConfig();
- $sonConfig = array_merge($sonConfig, $this->dao->getColumn(['level' => 1], 'menu_name'));
- foreach ($list as $key => $data) {
- if (in_array($key, $sonConfig)) {
- continue;
- }
- switch ($data['type']) {
- case 'text'://文本框
- $formbuider = array_merge($formbuider, $this->createTextForm($data['input_type'], $data));
- break;
- case 'radio'://单选框
- $relateRule = $this->relatedRule;
- $builder = [];
- if (!isset($relateRule[$key])) {
- $relateRule = [];
- $sonData = $this->dao->getColumn(['level' => 1, 'link_id' => $data['id']], 'menu_name,link_value');
- $sonValue = [];
- foreach ($sonData as $sv) {
- $sonValue[$sv['link_value']][] = $sv['menu_name'];
- }
- $i = 0;
- foreach ($sonValue as $pk => $pv) {
- $label = $data['menu_name'];
- if ($i == 1) $label = $data['menu_name'] . '@';
- if ($i == 2) $label = $data['menu_name'] . '#';
- $relateRule[$label]['show_value'] = $this->normalizeOptionValue($pk);
- foreach ($pv as $pvv) {
- $relateRule[$label]['son_type'][$pvv] = '';
- }
- $i++;
- }
- } else {
- $sonData = $this->dao->getColumn(['level' => 1, 'link_id' => $data['id']], 'menu_name,link_value');
- if ($sonData) {
- $sonValue = [];
- foreach ($sonData as $sv) {
- $sonValue[$sv['link_value']][] = $sv['menu_name'];
- }
- $i = 0;
- foreach ($sonValue as $pk => $pv) {
- $label = $data['menu_name'];
- if ($i == 1) $label = $data['menu_name'] . '@';
- if ($i == 2) $label = $data['menu_name'] . '#';
- if (!isset($relateRule[$label])) {
- $relateRule[$label]['show_value'] = $this->normalizeOptionValue($pk);
- }
- foreach ($pv as $pvv) {
- $relateRule[$label]['son_type'][$pvv] = '';
- }
- $i++;
- }
- }
- }
- if (isset($relateRule[$key])) {
- $role = $relateRule[$key];
- $data['show_value'] = $role['show_value'];
- foreach ($role['son_type'] as $sk => $sv) {
- if (isset($list[$sk])) {
- $son_data = $list[$sk];
- $son_data['show_value'] = $role['show_value'];
- $son_build = [];
- if (isset($sv['son_type'])) {
- foreach ($sv['son_type'] as $ssk => $ssv) {
- $son_data['show_value'] = $sv['show_value'];
- $son_build[] = $this->formTypeShine($list[$ssk])[0];
- unset($list[$ssk]);
- }
- }
- $son_build_two = [];
- if (isset($role['son_type'][$sk . '@'])) {
- $son_type_two = $role['son_type'][$sk . '@'];
- $son_data['show_value2'] = $son_type_two['show_value'];
- if (isset($son_type_two['son_type'])) {
- foreach ($son_type_two['son_type'] as $ssk => $ssv) {
- if (isset($list[$ssk]['menu_name']) && $list[$ssk]['menu_name'] == 'watermark_text_color') $list[$ssk]['type'] = 'color';
- $son_build_two[] = $this->formTypeShine($list[$ssk])[0];
- unset($list[$ssk]);
- }
- }
- }
- $son_build_three = [];
- if (isset($role['son_type'][$sk . '#'])) {
- $son_type_three = $role['son_type'][$sk . '#'];
- $son_data['show_value3'] = $son_type_three['show_value'];
- if (isset($son_type_three['son_type'])) {
- foreach ($son_type_three['son_type'] as $ssk => $ssv) {
- if (isset($list[$ssk]['menu_name']) && $list[$ssk]['menu_name'] == 'watermark_text_color') $list[$ssk]['type'] = 'color';
- $son_build_three[] = $this->formTypeShine($list[$ssk])[0];
- unset($list[$ssk]);
- }
- }
- }
- $builder[] = $this->formTypeShine($son_data, $son_build, $son_build_two, $son_build_three)[0];
- unset($list[$sk]);
- }
- }
- $data['show_value'] = $role['show_value'];
- }
- $builder_two = [];
- if (isset($relateRule[$key . '@'])) {
- $role = $relateRule[$key . '@'];
- $data['show_value2'] = $role['show_value'];
- foreach ($role['son_type'] as $sk => $sv) {
- $son_data = $list[$sk];
- $son_data['show_value'] = $role['show_value'];
- $builder_two[] = $this->formTypeShine($son_data)[0];
- }
- }
- $builder_three = [];
- if (isset($relateRule[$key . '#'])) {
- $role = $relateRule[$key . '#'];
- $data['show_value3'] = $role['show_value'];
- foreach ($role['son_type'] as $sk => $sv) {
- $son_data = $list[$sk];
- $son_data['show_value'] = $role['show_value'];
- $builder_three[] = $this->formTypeShine($son_data)[0];
- }
- }
- $formbuider = array_merge($formbuider, $this->createRadioForm($data, $builder, $builder_two, $builder_three));
- break;
- case 'textarea'://多行文本框
- $formbuider = array_merge($formbuider, $this->createTextareaForm($data));
- break;
- case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data,false));
- break;
- case 'checkbox'://多选框
- $formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
- break;
- case 'select'://多选框
- $formbuider = array_merge($formbuider, $this->createSelectForm($data));
- break;
- case 'switch'://开关
- $formbuider = array_merge($formbuider, $this->createSwitchForm($data));
- break;
- }
- }
- return $formbuider;
- }
- /**
- * 根据关联规则获取获取所有子配置
- * @return array|int[]|string[]
- * @author 吴汐
- * @email 442384644@qq.com
- * @date 2023/04/12
- */
- public function getSonConfig()
- {
- $sonConfig = [];
- $rolateRule = $this->relatedRule;
- if ($rolateRule) {
- foreach ($rolateRule as $key => $value) {
- $sonConfig = array_merge($sonConfig, array_keys($value['son_type']));
- foreach ($value['son_type'] as $k => $v) {
- if (isset($v['son_type'])) {
- $sonConfig = array_merge($sonConfig, array_keys($v['son_type']));
- }
- }
- }
- }
- return $sonConfig;
- }
- /**无组件绑定规则
- * @param array $list
- * @return array|bool
- * @throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function createNoCrontrolForm(array $list)
- {
- if (!$list) return false;
- $formbuider = [];
- foreach ($list as $key => $data) {
- switch ($data['type']) {
- case 'text'://文本框
- $formbuider = array_merge($formbuider, $this->createTextForm($data['input_type'], $data));
- break;
- case 'radio'://单选框
- $formbuider = array_merge($formbuider, $this->createRadioForm($data));
- break;
- case 'textarea'://多行文本框
- $formbuider = array_merge($formbuider, $this->createTextareaForm($data));
- break;
- case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data, true));
- break;
- case 'checkbox'://多选框
- $formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
- break;
- case 'select'://多选框
- $formbuider = array_merge($formbuider, $this->createSelectForm($data));
- break;
- case 'switch'://开关
- $formbuider = array_merge($formbuider, $this->createSwitchForm($data));
- break;
- }
- }
- return $formbuider;
- }
- /**
- * 有组件绑定规则
- * @param array $list
- * @param array $relatedRule
- * @return array|bool
- * @throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function createBindCrontrolForm(array $list, array $relatedRule)
- {
- if (!$list || !$relatedRule) return false;
- $formbuider = [];
- $new_data = array();
- foreach ($list as $dk => $dv) {
- $new_data[$dv['menu_name']] = $dv;
- }
- foreach ($relatedRule as $rk => $rv) {
- if (isset($rv['son_type'])) {
- $data = $new_data[$rk];
- switch ($data['type']) {
- case 'text'://文本框
- $formbuider = array_merge($formbuider, $this->createTextForm($data['input_type'], $data));
- break;
- case 'radio'://单选框
- $son_builder = array();
- foreach ($rv['son_type'] as $sk => $sv) {
- if (isset($sv['son_type'])) {
- foreach ($sv['son_type'] as $ssk => $ssv) {
- $son_data = $new_data[$sk];
- $son_data['show_value'] = $sv['show_value'];
- $son_builder[] = $this->formTypeShine($son_data, $this->formTypeShine($new_data[$ssk])[0])[0];
- }
- } else {
- $son_data = $new_data[$sk];
- $son_data['show_value'] = $rv['show_value'];
- $son_builder[] = $this->formTypeShine($son_data)[0];
- }
- }
- $formbuider = array_merge($formbuider, $this->createRadioForm($data, $son_builder));
- break;
- case 'textarea'://多行文本框
- $formbuider = array_merge($formbuider, $this->createTextareaForm($data));
- break;
- case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data, false));
- break;
- case 'checkbox'://多选框
- $formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
- break;
- case 'select'://多选框
- $formbuider = array_merge($formbuider, $this->createSelectForm($data));
- break;
- case 'switch'://开关
- $formbuider = array_merge($formbuider, $this->createSwitchForm($data));
- break;
- }
- }
- }
- return $formbuider;
- }
- /**
- * 根据tabid获取系统配置form表单创建
- * @param $url
- * @param int $tabId
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function getConfigForm($url, int $tabId)
- {
- /** @var SystemConfigTabServices $service */
- $service = app()->make(SystemConfigTabServices::class);
- $title = $service->value(['id' => $tabId], 'title');
- $list = $this->dao->getConfigTabAllList($tabId);
- $formbuider = $this->createForm($list);
- $name = 'setting';
- if ($url) {
- $name = explode('/', $url)[2] ?? $name;
- }
- $postUrl = $this->postUrl[$name]['url'] ?? '/setting/config/save_basics';
- return create_form($title, $formbuider, $this->url($postUrl), 'POST');
- }
- /**
- * 新增路由增加设置项验证
- * @param $url
- * @param $post
- * @return bool
- */
- public function checkParam($url, $post)
- {
- $name = '';
- if ($url) {
- $name = explode('/', $url)[2] ?? $name;
- }
- $auth = $this->postUrl[$name]['auth'] ?? false;
- if ($auth === false) {
- throw new AdminException('请求不被允许');
- }
- if ($auth) {
- /** @var SystemConfigTabServices $systemConfigTabServices */
- $systemConfigTabServices = app()->make(SystemConfigTabServices::class);
- foreach ($post as $key => $value) {
- $tab_ids = $systemConfigTabServices->getColumn([['eng_title', 'IN', $auth]], 'id');
- if (!$tab_ids || !in_array($key, $this->dao->getColumn([['config_tab_id', 'IN', $tab_ids]], 'menu_name'))) {
- throw new AdminException('设置类目不被允许');
- }
- }
- }
- return true;
- }
-
- /**
- * 添加配置字段
- * @param int $type
- * @param int $tab_id
- * @retuarr@throws \FormBuilder\Exception\FormBuilderException
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function addFieldForm(int $type, int $tab_id): array
- {
- /** @var SystemConfigTabServices $service */
- $service = app()->make(SystemConfigTabServices::class);
- $formbuider = [];
- $form_type = '';
- $info_type = [];
- $parameter = [];
- switch ($type) {
- case 0://文本框
- $form_type = 'text';
- $parameter[] = $this->createTextInputTypeForm(['input_type' => 'input']);
- break;
- case 1://多行文本框
- $form_type = 'textarea';
- $parameter[] = $this->builder->textarea('value', '默认值');
- $parameter[] = $this->builder->number('width', '文本框宽', 100);
- $parameter[] = $this->builder->number('high', '多行文本框高', 5);
- break;
- case 2://单选框
- $form_type = 'radio';
- $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>男\n2=>女\n3=>保密")->rows(3)->placeholder("参数方式例如:\n1=>男\n2=>女\n3=>保密")->required('配置参数不能为空')->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:<br>1=>男<br>2=>女<br>3=>保密']
- ]);
- $parameter[] = $this->builder->input('value', '默认值');
- break;
- case 3://文件上传
- $form_type = 'upload';
- $parameter = array_merge($parameter, $this->createUploadForm(1, ['menu_name' => 'value', 'info' => '默认值', 'value' => ''], true));
- break;
- case 4://多选框
- $form_type = 'checkbox';
- $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>白色\n2=>红色\n3=>黑色")->rows(3)->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色")->required('配置参数不能为空')->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:<br>1=>白色<br>2=>红色<br>3=>黑色']
- ]);
- break;
- case 5://下拉框
- $form_type = 'select';
- $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>分类一\n2=>分类二\n3=>分类三")->rows(3)->placeholder("参数方式例如:\n1=>分类一\n2=>分类二\n3=>分类三")->required('配置参数不能为空')->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:<br>1=>分类一<br>2=>分类二<br>3=>分类三']
- ]);
- break;
- case 6://开关
- $form_type = 'switch';
- $parameter[] = $this->builder->switches('value', '默认');
- break;
- }
- if ($form_type) {
- $formbuider[] = $this->builder->hidden('type', $form_type);
- [$configTabList, $data] = $service->getConfigTabListForm((int)($tab_id ?? 0));
- $linkData = $this->linkData($tab_id);
- $formbuider[] = $this->builder->radio('level', '联动显示', 0)->options([['value' => 0, 'label' => '否'], ['value' => 1, 'label' => '是']])->requiredNum()->appendRule('suffix', [
- 'type' => 'div',
- 'class' => 'tips-info',
- 'domProps' => ['innerHTML' => '否:默认正常展示此配置;是:此配置默认隐藏,当选中下方对应配置的值时,此配置才会显示']
- ])->appendControl(1, [
- $this->builder->cascader('link_data', '关联配置/值')->options($linkData)->props(['props' => ['multiple' => false, 'checkStrictly' => false, 'emitPath' => true]])->style(['width' => '100%']),
- ]);
- $formbuider[] = $this->builder->cascader('config_tab_id', '分类', $data)->options($configTabList)->filterable(true)->props(['props' => ['multiple' => false, 'checkStrictly' => true, 'emitPath' => false]])->style(['width' => '100%']);
- if ($info_type) {
- $formbuider[] = $info_type;
- }
- $formbuider[] = $this->builder->input('info', '配置名称')->required('配置名称不能为空')->autofocus(1);
- $formbuider[] = $this->builder->input('menu_name', '字段变量')->required('字段变量不能为空')->placeholder('例如:site_url');
- $formbuider[] = $this->builder->input('desc', '配置简介');
- $formbuider = array_merge($formbuider, $parameter);
- // 是否必填
- if ($form_type != 'switch') {
- $formbuider[] = $this->builder->radio('required', '是否必填', 0)->options([
- ['value' => 0, 'label' => '否'],
- ['value' => 1, 'label' => '是'],
- ])->requiredNum();
- }
- $formbuider[] = $this->builder->number('sort', '排序', 0);
- $formbuider[] = $this->builder->radio('status', '状态', 1)->options([['value' => 1, 'label' => '显示'], ['value' => 0, 'label' => '隐藏']])->requiredNum();
- }
- return create_form('添加字段', $formbuider, $this->url('/setting/config'), 'POST');
- }
- /**
- * 联动选择关联配置/值
- * 根据指定的标签ID,链接数据并以特定格式返回。
- * @param $tab_id
- * @return array
- * @author wuhaotian
- * @email 442384644@qq.com
- * @date 2024/5/30
- */
- public function linkData($tab_id)
- {
- $linkData = $this->selectList(['config_tab_id' => $tab_id, 'type' => 'radio', 'level' => 0], 'info as label,id as value,parameter,sort', 0, 0, 'sort DESC')->toArray();
- foreach ($linkData as &$item) {
- $parameter = [];
- $parameter = explode("\n", $item['parameter']);
- foreach ($parameter as $pv) {
- $pvArr = explode('=>', $pv, 2);
- if (count($pvArr) < 2) {
- continue;
- }
- $item['children'][] = [
- 'label' => trim($pvArr[1]),
- 'value' => $this->normalizeOptionValue($pvArr[0])
- ];
- }
- }
- return $linkData;
- }
- /**
- * radio 和 checkbox规则的判断
- * @param $data
- * @return bool
- */
- public function valiDateRadioAndCheckbox($data)
- {
- $option = [];
- $option_new = [];
- $data['parameter'] = str_replace("\r\n", "\n", $data['parameter']);//防止不兼容
- $parameter = explode("\n", $data['parameter']);
- if (count($parameter) < 2) {
- throw new AdminException('请输入正确格式的配置参数');
- }
- foreach ($parameter as $k => $v) {
- if (isset($v) && !empty($v)) {
- $option[$k] = explode('=>', $v);
- }
- }
- if (count($option) < 2) {
- throw new AdminException('请输入正确格式的配置参数');
- }
- $bool = 1;
- foreach ($option as $k => $v) {
- $option_new[$k] = $option[$k][0];
- foreach ($v as $kk => $vv) {
- $vv_num = strlen($vv);
- if (!$vv_num) {
- $bool = 0;
- }
- }
- }
- if (!$bool) {
- throw new AdminException('请输入正确格式的配置参数');
- }
- $num1 = count($option_new);//提取该数组的数目
- $arr2 = array_unique($option_new);//合并相同的元素
- $num2 = count($arr2);//提取合并后数组个数
- if ($num1 > $num2) {
- throw new AdminException('请输入正确格式的配置参数');
- }
- return true;
- }
- /**
- * 验证参数
- * @param $data
- * @return bool
- */
- public function valiDateValue($data)
- {
-
- // 检查数据和验证规则是否存在
- if (!$data || !isset($data['required']) || !$data['required']) {
- return true;
- }
-
- $name = $data['info'] ?? '';
- $value = $data['value'] ?? '';
-
- // 支持JSON格式的验证规则
- $requiredData = json_decode($data['required'], true);
- if ($requiredData) {
- // JSON格式
- if (isset($requiredData['required']) && $requiredData['required']) {
- if ($value === '' || $value === null) {
- throw new AdminException($name . '不能为空');
- }
- }
- if (isset($requiredData['regex']) && $requiredData['regex']) {
- if ($value && !preg_match($requiredData['regex'], $value)) {
- throw new AdminException($name . '请输入正确的格式');
- }
- }
- if (isset($requiredData['min']) && $value !== '' && $value !== null) {
- if ((float)$value < $requiredData['min']) {
- throw new AdminException($name . '不能小于' . $requiredData['min']);
- }
- }
- if (isset($requiredData['max']) && $value !== '' && $value !== null) {
- if ((float)$value > $requiredData['max']) {
- throw new AdminException($name . '不能大于' . $requiredData['max']);
- }
- }
- } else {
- // 兼容旧格式:逗号分隔的字符串
- $valids = explode(',', $data['required']);
- foreach ($valids as $valid) {
- $valid = explode(':', $valid);
- if (isset($valid[0]) && isset($valid[1])) {
- $k = strtolower(trim($valid[0]));
- $v = strtolower(trim($valid[1]));
-
- if ($v != 'true') {
- continue;
- }
-
- switch ($k) {
- case 'required':
- if ($value === '' || $value === null) {
- throw new AdminException($name . '不能为空');
- }
- break;
-
- case 'regex':
- if ($value && !preg_match($data['regex'], $value)) {
- throw new AdminException($name . '请输入正确的格式');
- }
- break;
- }
- }
- }
- }
-
- return true;
- }
- /**
- * 保存平台电子面单打印信息
- * @param array $data
- * @return bool
- */
- public function saveExpressInfo(array $data)
- {
- if (!is_array($data) || !$data) return false;
- // config_export_id 快递公司id
- // config_export_temp_id 快递公司模板id
- // config_export_com 快递公司编码
- // config_export_to_name 发货人姓名
- // config_export_to_tel 发货人电话
- // config_export_to_address 发货人详细地址
- // config_export_siid 电子面单打印机编号
- foreach ($data as $key => $value) {
- $this->dao->update(['menu_name' => 'config_export_' . $key], ['value' => json_encode($value)]);
- }
- CacheService::clear();
- return true;
- }
- /**
- * 获取分享海报 兼容方法
- */
- public function getSpreadBanner()
- {
- //配置
- $banner = sys_config('spread_banner', []);
- if (!$banner) {
- //组合数据
- $banner = sys_data('routine_spread_banner');
- if ($banner) {
- $banner = array_column($banner, 'pic');
- $this->dao->update(['menu_name' => 'spread_banner'], ['value' => json_encode($banner)]);
- CacheService::clear();
- }
- }
- return $banner;
- }
- /**
- * 保存wss配置
- * @param int $wssOpen
- * @param string $wssLocalpk
- * @param string $wssLocalCert
- */
- public function saveSslFilePath(int $wssOpen, string $wssLocalpk, string $wssLocalCert)
- {
- $wssFile = root_path() . '.wss';
- $content = <<<WSS
- wssOpen = $wssOpen
- wssLocalpk = $wssLocalpk
- wssLocalCert = $wssLocalCert
- WSS;
- try {
- file_put_contents($wssFile, $content);
- } catch (\Throwable $e) {
- throw new AdminException('保存wss证书失败');
- }
- }
- /**
- * 获取wss配置
- * @param string $key
- * @return array|false|mixed
- */
- public function getSslFilePath(string $key = '')
- {
- $wssFile = root_path() . '.wss';
- try {
- $content = parse_ini_file($wssFile);
- } catch (\Throwable $e) {
- $content = [];
- }
- return $content[$key] ?? $content;
- }
- /**
- * 检测缩略图水印配置是否更改
- * @param array $post
- * @return bool
- */
- public function checkThumbParam(array $post)
- {
- unset($post['upload_type'], $post['image_watermark_status']);
- /** @var SystemConfigTabServices $systemConfigTabServices */
- $systemConfigTabServices = app()->make(SystemConfigTabServices::class);
- //上传配置->基础配置
- $tab_id = $systemConfigTabServices->getColumn(['eng_title' => 'base_config'], 'id');
- if ($tab_id) {
- $all = $this->dao->getColumn(['config_tab_id' => $tab_id], 'value', 'menu_name');
- if (array_intersect(array_keys($all), array_keys($post))) {
- foreach ($post as $key => $item) {
- //配置更改删除原来生成的缩略图
- if (isset($all[$key]) && $item != json_decode($all[$key], true)) {
- try {
- FileService::delDir(public_path('uploads/thumb_water'));
- break;
- } catch (\Throwable $e) {
- }
- }
- }
- }
- }
- return true;
- }
- /**
- * 变更分销绑定关系模式
- * @param array $post
- * @return bool
- */
- public function checkBrokerageBinding(array $post)
- {
- try {
- $config_data = $post['store_brokerage_binding_status'];
- $config_one = $this->dao->getOne(['menu_name' => 'store_brokerage_binding_status']);
- $config_old = json_decode($config_one['value'], true);
- if ($config_old != 2 && $config_data == 2) {
- //自动解绑上级绑定
- /** @var AgentManageServices $agentManage */
- $agentManage = app()->make(AgentManageServices::class);
- $agentManage->resetSpreadTime();
- }
- } catch (\Throwable $e) {
- Log::error('变更分销绑定模式重置绑定时间失败,失败原因:' . $e->getMessage());
- return false;
- }
- return true;
- }
- /** 停用
- * 根据系统配置分类自动生成form表单页面
- * @param int $tabId
- * @param array $formData
- * @param array $relatedRule
- * @return array|bool
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- */
- public function createConfigForm(int $tabId, array $relatedRule)
- {
- $list = $this->dao->getConfigTabAllList($tabId);
- if (!$relatedRule) {
- $formbuider = $this->createNoCrontrolForm($list);
- } else {
- $formbuider = $this->createBindCrontrolForm($list, $relatedRule);
- }
- return $formbuider;
- }
- /** 停用
- * 绑定表单数据
- * @param $data
- * @param $relatedRule
- * @return array
- */
- private function bindBuilderData($data, $relatedRule)
- {
- if (!$data) return false;
- $p_list = array();
- foreach ($relatedRule as $rk => $rv) {
- $p_list[$rk] = $data[$rk];
- if (isset($rv['son_type']) && is_array($rv['son_type'])) {
- foreach ($rv['son_type'] as $sk => $sv) {
- if (is_array($sv) && isset($sv['son_type'])) {
- foreach ($sv['son_type'] as $ssk => $ssv) {
- $tmp = $data[$sk];
- $tmp['console'] = $data[$ssk];
- $p_list[$rk]['console'][] = $tmp;
- }
- } else {
- $p_list[$rk]['console'][] = $data[$sk];
- }
- }
- }
- }
- return array_values($p_list);
- }
- }
|