From a203bfee3741882f9f22ccbc899b7df8cbe613dd Mon Sep 17 00:00:00 2001 From: evoxwht <442384644@qq.com> Date: Fri, 10 Jul 2026 10:19:34 +0800 Subject: [PATCH] update v6.0.0 --- .../controller/v1/setting/SystemConfig.php | 107 ++++++++++++++---- crmeb/app/common.php | 28 +++-- 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php b/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php index 3ff3916f9..3184ec3ad 100644 --- a/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php +++ b/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php @@ -26,16 +26,18 @@ use think\facade\App; */ class SystemConfig extends AuthController { + /** @var SystemConfigServices */ + protected $services; /** * SystemConfig constructor. * @param App $app - * @param SystemConfigServices $services + * @param SystemConfigServices $configServices */ - public function __construct(App $app, SystemConfigServices $services) + public function __construct(App $app, SystemConfigServices $configServices) { parent::__construct($app); - $this->services = $services; + $this->services = $configServices; } /** @@ -75,7 +77,7 @@ class SystemConfig extends AuthController [['type', 'd'], ''], [['tab_id', 'd'], 1] ], true); - return app('json')->success($this->services->createFormRule($type, $tabId)); + return app('json')->success($this->services->addFieldForm($type, $tabId)); } /** @@ -91,7 +93,10 @@ class SystemConfig extends AuthController ['config_tab_id', 0], ['parameter', ''], ['upload_type', 1], - ['required', ''], + ['required', 0], + ['rule', ''], // 输入框验证 + ['min', null], // 数字最小值 + ['max', null], // 数字最大值 ['width', 0], ['high', 0], ['value', ''], @@ -105,14 +110,11 @@ class SystemConfig extends AuthController if (is_array($data['config_tab_id'])) $data['config_tab_id'] = end($data['config_tab_id']); if (!$data['info']) return app('json')->fail('请输入配置名称'); if (!$data['menu_name']) return app('json')->fail('请输入字段名称'); - if (!$data['desc']) return app('json')->fail('请输入配置简介'); + // if (!$data['desc']) return app('json')->fail('请输入配置简介'); if ($data['sort'] < 0) { $data['sort'] = 0; } - if ($data['type'] == 'text') { - if (!$data['width']) return app('json')->fail('请输入文本框的宽度'); - if ($data['width'] <= 0) return app('json')->fail('请输入正确的文本框的宽度'); - } + if ($data['type'] == 'textarea') { if (!$data['width']) return app('json')->fail('请输入多行文本框的宽度'); if (!$data['high']) return app('json')->fail('请输入多行文本框的高度'); @@ -123,11 +125,36 @@ class SystemConfig extends AuthController if (!$data['parameter']) return app('json')->fail('请输入配置参数'); $this->services->valiDateRadioAndCheckbox($data); } + // 关联顶级选项 if ($data['level'] == 1) { if (!$data['link_data']) return app('json')->fail('请选择关联顶级选项'); $data['link_id'] = $data['link_data'][0]; $data['link_value'] = $data['link_data'][1]; } + // 合并必填、格式规则和数字范围为 JSON 格式 + $requiredRules = []; + if ($data['required']) { + $requiredRules['required'] = true; + } else { + $requiredRules['required'] = false; + } + if ($data['rule']) { + $requiredRules['regex'] = $data['rule']; + } + if ($data['type'] == 'text' && $data['input_type'] == 'number') { + if ($data['min'] !== null) { + $requiredRules['min'] = (int)$data['min']; + } + if ($data['max'] !== null) { + $requiredRules['max'] = (int)$data['max']; + } + } + // min不能大于max + if ($data['min'] !== null && $data['max'] !== null && $data['min'] > $data['max']) { + return app('json')->fail('最小值不能大于最大值'); + } + $data['required'] = json_encode($requiredRules); + unset($data['rule'], $data['min'], $data['max']); $data['value'] = json_encode($data['value']); $config = $this->services->getOne(['menu_name' => $data['menu_name']]); if ($config) { @@ -162,7 +189,10 @@ class SystemConfig extends AuthController */ public function edit($id) { - return app('json')->success($this->services->editConfigForm((int)$id)); + if (!$id) { + return app('json')->fail('参数错误'); + } + return app('json')->success($this->services->editFieldForm((int)$id)); } /** @@ -187,7 +217,10 @@ class SystemConfig extends AuthController ['config_tab_id', 0], ['parameter', ''], ['upload_type', 1], - ['required', ''], + ['required', 0], + ['regex', ''], // 输入框验证 + ['min', ''], // 数字最小值 + ['max', ''], // 数字最大值 ['width', 0], ['high', 0], ['value', $value], @@ -202,6 +235,33 @@ class SystemConfig extends AuthController if (!$this->services->get($id)) { return app('json')->fail('数据不存在'); } + // 合并必填、格式规则和数字范围为 JSON 格式 + $requiredRules = []; + if ($data['required']) { + $requiredRules['required'] = true; + } else { + $requiredRules['required'] = false; + } + // 正则表达式验证 + if ($data['regex']) { + $requiredRules['regex'] = $data['regex']; + } + // 数字类型额外保存 min 和 max + if ($data['type'] == 'text' && $data['input_type'] == 'number') { + if ($data['min'] !== '') { + $requiredRules['min'] = (int)$data['min']; + } + if ($data['max'] !== '') { + $requiredRules['max'] = (int)$data['max']; + } + } + // min不能大于max + if ($data['min'] !== '' && $data['max'] !== '' && $data['min'] > $data['max']) { + return app('json')->fail('最小值不能大于最大值'); + } + $data['required'] = json_encode($requiredRules); + unset($data['regex'], $data['min'], $data['max']); + // 关联选项 if ($data['level'] == 1) { if (!$data['link_data']) return app('json')->fail('请选择关联顶级选项'); $data['link_id'] = $data['link_data'][0]; @@ -234,7 +294,7 @@ class SystemConfig extends AuthController * @param $status * @return mixed */ - public function set_status($id, $status) + public function setStatus($id, $status) { if ($status == '' || $id == 0) { return app('json')->fail('参数错误'); @@ -247,7 +307,7 @@ class SystemConfig extends AuthController /** * 基础配置 * */ - public function edit_basics(Request $request) + public function editBasics(Request $request) { $tabId = $this->request->param('tab_id', 1); if (!$tabId) { @@ -260,7 +320,7 @@ class SystemConfig extends AuthController /** * 保存数据 true * */ - public function save_basics(Request $request) + public function saveBasics(Request $request) { $post = $this->request->post(); foreach ($post as $k => $v) { @@ -282,9 +342,11 @@ class SystemConfig extends AuthController if (isset($post['extract_type']) && !count($post['extract_type'])) { return app('json')->fail('提现方式最少选一种'); } + // 检查佣金绑定状态 if (isset($post['store_brokerage_binding_status'])) { $this->services->checkBrokerageBinding($post); } + // 检查一级返佣比例和二级返佣比例是否大于100% if (isset($post['store_brokerage_ratio']) && isset($post['store_brokerage_two'])) { $num = $post['store_brokerage_ratio'] + $post['store_brokerage_two']; if ($num > 100) { @@ -399,6 +461,13 @@ class SystemConfig extends AuthController return app('json')->success('修改成功'); } if (isset($post['param_filter_data'])) { + $rules = preg_split('/\r\n|\r|\n/', $post['param_filter_data'], -1, PREG_SPLIT_NO_EMPTY); + foreach ($rules as $rule) { + $rule = trim($rule); + if ($rule !== '' && @preg_match($rule, '') === false) { + return app('json')->fail('WAF配置规则格式错误:' . $rule); + } + } $post['param_filter_data'] = base64_encode($post['param_filter_data']); } if (isset($post['product_type_config'])) { @@ -493,7 +562,7 @@ class SystemConfig extends AuthController * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public function header_basics(SystemConfigTabServices $services) + public function headerBasics(SystemConfigTabServices $services) { [$type, $pid] = $this->request->getMore([ [['type', 'd'], 0], @@ -513,7 +582,7 @@ class SystemConfig extends AuthController * @param $name * @return mixed */ - public function get_system($name) + public function getSystem($name) { $value = sys_config($name); return app('json')->success(compact('value')); @@ -524,9 +593,9 @@ class SystemConfig extends AuthController * @param $tabId * @return mixed */ - public function get_config_list($tabId) + public function getConfigList($tabId) { - $list = $this->services->getConfigTabAllList($tabId); + $list = $this->services->getReadList($tabId); $data = []; foreach ($list as $item) { $data[$item['menu_name']] = json_decode($item['value']); diff --git a/crmeb/app/common.php b/crmeb/app/common.php index 3d499ad28..62f8976a7 100644 --- a/crmeb/app/common.php +++ b/crmeb/app/common.php @@ -670,9 +670,23 @@ if (!function_exists('filter_str')) { */ function filter_str($str) { - $param_filter_type = sys_config('param_filter_type'); + $param_filter_type = (int)sys_config('param_filter_type'); if ($param_filter_type != 0) { - $rules = preg_split('/\r\n|\r|\n/', base64_decode(sys_config('param_filter_data'))); + $ruleData = base64_decode((string)sys_config('param_filter_data'), true); + $rules = preg_split('/\r\n|\r|\n/', $ruleData === false ? '' : $ruleData, -1, PREG_SPLIT_NO_EMPTY); + $rules = array_values(array_filter(array_map('trim', $rules), function ($rule) { + return $rule !== '' && @preg_match($rule, '') !== false; + })); + if (!$rules) return $str; + + $str = (string)$str; + if (preg_match('/^\s*([a-z][a-z0-9+.-]*):/i', $str, $matches)) { + $dangerSchemes = ['gopher', 'doc', 'php', 'glob', 'file', 'phar', 'zlib', 'zlib_filter', 'ftp', 'ldap', 'dict', 'ogg', 'data', 'javascript', 'vbscript']; + if (in_array(strtolower($matches[1]), $dangerSchemes, true)) { + throw new \Exception('接口请求失败:非法操作!'); + } + } + if ($param_filter_type == 1) { foreach ($rules as $item) { if (preg_match($item, $str)) { @@ -680,14 +694,8 @@ if (!function_exists('filter_str')) { } } } - if (filter_var($str, FILTER_VALIDATE_URL)) { - $url = parse_url($str); - if (!isset($url['scheme'])) return $str; - $host = $url['scheme'] . '://' . $url['host']; - $str = $host . preg_replace($rules, '', str_replace($host, '', $str)); - } else { - $str = preg_replace($rules, '', $str); - } + $filterStr = preg_replace($rules, '', $str); + $str = $filterStr === null ? $str : $filterStr; } return $str; }