diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md
index 2fc4b4778..7518db8f9 100644
--- a/.trae/rules/project_rules.md
+++ b/.trae/rules/project_rules.md
@@ -1,3 +1,7 @@
+---
+alwaysApply: false
+description:
+---
# CRMEB 项目专属 Chat 规则
## 1. 项目概述
diff --git a/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php b/crmeb/app/adminapi/controller/v1/setting/SystemConfig.php
index 3ff3916f9..e0bfe7031 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', ''],
@@ -109,10 +114,7 @@ class SystemConfig extends AuthController
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];
@@ -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) {
@@ -526,7 +588,7 @@ class SystemConfig extends AuthController
*/
public function get_config_list($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/services/system/config/SystemConfigServices.php b/crmeb/app/services/system/config/SystemConfigServices.php
index d5a6b2197..5ac811f67 100644
--- a/crmeb/app/services/system/config/SystemConfigServices.php
+++ b/crmeb/app/services/system/config/SystemConfigServices.php
@@ -34,6 +34,12 @@ use think\facade\Log;
*/
class SystemConfigServices extends BaseServices
{
+ /**
+ * 系统配置数据访问层
+ * @var SystemConfigDao
+ */
+ protected $dao;
+
/**
* form表单句柄
* @var FormBuilder
@@ -51,22 +57,27 @@ class SystemConfigServices extends BaseServices
* @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'],
@@ -74,7 +85,7 @@ class SystemConfigServices extends BaseServices
];
/**
- * 子集控制规则
+ * 子集控制规则联动控制,新版单个配置可以配置联动,此配置为兼容旧版数据配置,不建议使用
* @var array[]
*/
protected $relatedRule = [
@@ -232,28 +243,7 @@ class SystemConfigServices extends BaseServices
$this->builder = $builder;
}
- /**
- * @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;
- }
+
/**
* 获取单个系统配置
@@ -282,7 +272,7 @@ class SystemConfigServices extends BaseServices
}
/**
- * 获取配置并分页
+ * 获取配置列表搜索并分页
* @param array $where
* @return array
* @throws \think\db\exception\DataNotFoundException
@@ -305,13 +295,18 @@ class SystemConfigServices extends BaseServices
if ($item['upload_type'] == 1 || $item['upload_type'] == 3) {
$item['value'] = [set_file_url($item['value'])];
} elseif ($item['upload_type'] == 2) {
- $item['value'] = set_file_url($item['value']);
+ $tempValue = set_file_url($item['value']);
+ $item['value'] = is_array($tempValue) ? $tempValue : [];
}
- foreach ($item['value'] as $key => $value) {
- $tidy_srr[$key]['filepath'] = $value;
- $tidy_srr[$key]['filename'] = basename($value);
+ 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'] = [];
}
- $item['value'] = $tidy_srr;
}
if ($item['level'] == 1) {
$item['link_data'] = $this->getLinkData($item['link_id'], $item['link_value']);
@@ -322,7 +317,7 @@ class SystemConfigServices extends BaseServices
}
/**
- * 获取关联的值
+ * 配置列表页获取关联的值,展示:关联配置名称/关联值
* @param $id
* @param $value
* @return string
@@ -333,7 +328,7 @@ class SystemConfigServices extends BaseServices
* @email 442384644@qq.com
* @date 2024/5/31
*/
- public function getLinkData($id, $value)
+ private function getLinkData($id, $value)
{
$info = $this->dao->get($id);
if (!$info) return '';
@@ -343,11 +338,11 @@ class SystemConfigServices extends BaseServices
$parts = explode('=>', $item);
$result[$parts[0]] = $parts[1];
}
- return $info['info'] . '/' . $result[$value];
+ return $info['info'] . ':' . $result[$value].'(显示)';
}
/**
- * 获取单选按钮或者多选按钮的显示值
+ * 配置列表页获取单选按钮或者多选按钮的显示值
* @param $menu_name
* @param $value
* @return string
@@ -355,7 +350,7 @@ class SystemConfigServices extends BaseServices
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
- public function getRadioOrCheckboxValueInfo(string $menu_name, $value): string
+ private function getRadioOrCheckboxValueInfo(string $menu_name, $value): string
{
$option = [];
$config_one = $this->dao->getOne(['menu_name' => $menu_name]);
@@ -381,7 +376,7 @@ class SystemConfigServices extends BaseServices
}
/**
- * 获取系统配置信息
+ * 根据配置tab id获取系统配置信息
* @param int $tabId
* @return array
* @throws \think\db\exception\DataNotFoundException
@@ -401,6 +396,189 @@ class SystemConfigServices extends BaseServices
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,}$/
手机号:/^1[3-9]\d{9}$/
URL:/^https?:\/\/.+/i
电话:/^1[3-9]\d{9}$|^0\d{2,3}-\d{7,8}$|^400-\d{3}-\d{3}$/
长度:/^.{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
@@ -410,17 +588,46 @@ class SystemConfigServices extends BaseServices
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;
- $formbuider[] = $this->builder->number($data['menu_name'], $data['info'], (float)$data['value'])->controls(false)->appendRule('suffix', [
+ // 最小值和最大值提示(有值才显示)
+ $minMaxTip = '';
+ if (isset($data['min']) && $data['min'] !== null) {
+ $minMaxTip = '
最小值:' . $data['min'];
+ }
+ if (isset($data['max']) && $data['max'] !== null) {
+ $minMaxTip .= ($minMaxTip ? ',' : '
') . '最大值:' . $data['max'];
+ }
+ $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']]
- ]);
+ 'domProps' => ['innerHTML' => $data['desc'] . $minMaxTip]
+ ])->col($data['width'] ?? 13);
break;
case 'dateTime':
- $formbuider[] = $this->builder->dateTime($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ $inputRule = $this->builder->dateTime($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
@@ -428,7 +635,7 @@ class SystemConfigServices extends BaseServices
break;
case 'date':
$data['value'] = json_decode($data['value'], true) ?: '';
- $formbuider[] = $this->builder->date($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ $inputRule = $this->builder->date($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
@@ -436,7 +643,7 @@ class SystemConfigServices extends BaseServices
break;
case 'time':
$data['value'] = json_decode($data['value'], true) ?: '';
- $formbuider[] = $this->builder->time($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ $inputRule = $this->builder->time($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
@@ -444,7 +651,7 @@ class SystemConfigServices extends BaseServices
break;
case 'color':
$data['value'] = isset($data['value']) ? json_decode($data['value'], true) : '';
- $formbuider[] = $this->builder->color($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ $inputRule = $this->builder->color($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
@@ -452,49 +659,63 @@ class SystemConfigServices extends BaseServices
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') {
- $formbuider[] = $this->builder->input($data['menu_name'], $data['info'], strpos($data['value'], 'http') === false ? sys_config('site_url') . $data['value'] : $data['value'])->appendRule('suffix', [
+ $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(13)->readonly(true);
+ ])->col($data['width'] ?? 13)->readonly(true);
} else {
- $formbuider[] = $this->builder->input($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ // 宽宽度设置
+ $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(13);
+ ])->col($col)->placeholder('请输入'.$data['info']);
}
break;
}
+ // 是否必填项
+ $this->isRequired($data['required']) && $inputRule = $inputRule->required($data['info'].'不能为空');
+ $formbuider[] = $inputRule;
return $formbuider;
}
-
+
/**
* 创建多行文本框
* @param array $data
* @return mixed
*/
- public function createTextareaForm(array $data)
+ 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']);
- $formbuider[] = $this->builder->textarea($data['menu_name'], $data['info'], $data['value'])->placeholder($data['desc'])->appendRule('suffix', [
+ // 宽度设置
+ $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(6)->col(13);
+ ])->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
*/
- public function createRadioForm(array $data, $control = [], $control_two = [], $control_three = [])
+ private function createRadioForm(array $data, $control = [], $control_two = [], $control_three = [])
{
$formbuider = [];
$data['value'] = json_decode($data['value'], true) ?: '0';
@@ -513,7 +734,7 @@ class SystemConfigServices extends BaseServices
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
- ])->col(13);
+ ])->requiredNum()->col(13);
if ($control) {
$radio->appendControl($data['show_value'] ?? 1, is_array($control) ? $control : [$control]);
}
@@ -531,47 +752,95 @@ class SystemConfigServices extends BaseServices
* 创建上传组件表单
* @param int $type
* @param array $data
+ * @param bool $showTypeSelect 是否显示上传类型选择器
* @return array
*/
- public function createUploadForm(int $type, array $data)
+ private function createUploadForm(int $type, array $data, bool $showTypeSelect = false)
{
$formbuider = [];
- switch ($type) {
- case 1:
- $data['value'] = json_decode($data['value'], true) ?: '';
- if ($data['value'] != '') $data['value'] = set_file_url($data['value']);
- $formbuider[] = $this->builder->frameImage($data['menu_name'], $data['info'], $this->url(config('app.admin_prefix', 'admin') . '/widget.images/index', ['fodder' => $data['menu_name']], true), $data['value'])
- ->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);
- break;
- case 2:
- $data['value'] = json_decode($data['value'], true) ?: [];
- if ($data['value'])
- $data['value'] = set_file_url($data['value']);
- $formbuider[] = $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), $data['value'])
- ->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);
- break;
- case 3:
- $data['value'] = json_decode($data['value'], true) ?: '';
- if ($data['value'] != '') $data['value'] = set_file_url($data['value']);
- $formbuider[] = $this->builder->uploadFile($data['menu_name'], $data['info'], $this->url('/adminapi/file/upload/1', ['type' => 1], false, true), $data['value'])
- ->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'),
- ]);
- break;
+ // 单图控件
+ 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;
}
@@ -581,9 +850,10 @@ class SystemConfigServices extends BaseServices
* @return array
* @throws \FormBuilder\Exception\FormBuilderException
*/
- public function createCheckboxForm(array $data)
+ private function createCheckboxForm(array $data)
{
$formbuider = [];
+ $checkboxRule = null;
$data['value'] = json_decode($data['value'], true) ?: [];
$parameter = explode("\n", $data['parameter']);
$options = [];
@@ -594,12 +864,18 @@ class SystemConfigServices extends BaseServices
$options[] = ['label' => $pdata[1], 'value' => $pdata[0]];
}
}
- $formbuider[] = $this->builder->checkbox($data['menu_name'], $data['info'], $data['value'])->options($options)->appendRule('suffix', [
+ $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;
}
@@ -609,9 +885,10 @@ class SystemConfigServices extends BaseServices
* @return array
* @throws \FormBuilder\Exception\FormBuilderException
*/
- public function createSelectForm(array $data)
+ private function createSelectForm(array $data)
{
$formbuider = [];
+ $selectRule = null;
$data['value'] = json_decode($data['value'], true) ?: [];
$parameter = explode("\n", $data['parameter']);
$options = [];
@@ -622,12 +899,15 @@ class SystemConfigServices extends BaseServices
$options[] = ['label' => $pdata[1], 'value' => $pdata[0]];
}
}
- $formbuider[] = $this->builder->select($data['menu_name'], $data['info'], $data['value'])->options($options)->appendRule('suffix', [
+ $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;
}
@@ -639,14 +919,17 @@ class SystemConfigServices extends BaseServices
* @email: 442384644@qq.com
* @date: 2023/9/6
*/
- public function createSwitchForm($data)
+ private function createSwitchForm($data)
{
+ $formbuider = [];
+ $switchRule = null;
$data['value'] = json_decode($data['value'], true) ?: '';
- $formbuider[] = $this->builder->switches($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
+ $switchRule = $this->builder->switches($data['menu_name'], $data['info'], $data['value'])->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => $data['desc']]
- ])->col(13);
+ ])->required($data['info'].'必选项')->col(13);
+ $formbuider[] = $switchRule;
return $formbuider;
}
@@ -655,7 +938,7 @@ class SystemConfigServices extends BaseServices
* @param array $data
* @return mixed
*/
- public function createColorForm(array $data)
+ 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', [
@@ -665,30 +948,34 @@ class SystemConfigServices extends BaseServices
])->col(13);
return $formbuider;
}
-
- public function bindBuilderData($data, $relatedRule)
+ /**
+ * 上传类型
+ * @return array
+ */
+ private function uploadType(): array
{
- 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);
+ 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;
+ }
+
/**
* 获取系统配置表单
@@ -709,40 +996,22 @@ class SystemConfigServices extends BaseServices
case 'textarea'://多行文本框
return $this->createTextareaForm($data);
case 'upload'://文件上传
- return $this->createUploadForm((int)$data['upload_type'], $data);
+ 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 'color':
+ // return $this->createColorForm($data);
case 'switch'://开关
return $this->createSwitchForm($data);
}
}
- /**
- * @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;
- }
+
/**
- * 创建
+ * 根据系统多个配置自动生成form表单页面
* @param array $list
* @return array
* @throws \FormBuilder\Exception\FormBuilderException
@@ -750,7 +1019,7 @@ class SystemConfigServices extends BaseServices
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
- public function createForm(array $list)
+ private function createForm(array $list)
{
if (!$list) return [];
$list = array_combine(array_column($list, 'menu_name'), $list);
@@ -879,7 +1148,7 @@ class SystemConfigServices extends BaseServices
$formbuider = array_merge($formbuider, $this->createTextareaForm($data));
break;
case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data));
+ $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data,false));
break;
case 'checkbox'://多选框
$formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
@@ -894,7 +1163,29 @@ class SystemConfigServices extends BaseServices
}
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
@@ -920,7 +1211,7 @@ class SystemConfigServices extends BaseServices
$formbuider = array_merge($formbuider, $this->createTextareaForm($data));
break;
case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data));
+ $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data, true));
break;
case 'checkbox'://多选框
$formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
@@ -983,7 +1274,7 @@ class SystemConfigServices extends BaseServices
$formbuider = array_merge($formbuider, $this->createTextareaForm($data));
break;
case 'upload'://文件上传
- $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data));
+ $formbuider = array_merge($formbuider, $this->createUploadForm((int)$data['upload_type'], $data, false));
break;
case 'checkbox'://多选框
$formbuider = array_merge($formbuider, $this->createCheckboxForm($data));
@@ -1001,7 +1292,7 @@ class SystemConfigServices extends BaseServices
}
/**
- * 系统配置form表单创建
+ * 根据tabid获取系统配置form表单创建
* @param $url
* @param int $tabId
* @return array
@@ -1054,146 +1345,17 @@ class SystemConfigServices extends BaseServices
return true;
}
+
/**
- * 修改配置获取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 editConfigForm(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%']),
- ]);
- $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'])->autofocus(1);
- $formbuider[] = $this->builder->input('desc', '配置简介', $menu['desc']);
- switch ($menu['type']) {
- case 'text':
- $menu['value'] = json_decode($menu['value'], true);
- $formbuider[] = $this->builder->select('input_type', '类型', $menu['input_type'])->setOptions([
- ['value' => 'input', 'label' => '文本框']
- , ['value' => 'dateTime', 'label' => '日期时间']
- , ['value' => 'date', 'label' => '日期']
- , ['value' => 'time', 'label' => '时间']
- , ['value' => 'color', 'label' => '颜色']
- , ['value' => 'number', 'label' => '数字']
- ]);
- //输入框验证规则
- $formbuider[] = $this->builder->input('value', '默认值', $menu['value']);
- if (!empty($menu['required'])) {
- $formbuider[] = $this->builder->number('width', '文本框宽', (int)$menu['width']);
- $formbuider[] = $this->builder->input('required', '验证规则', $menu['required'])->placeholder('多个请用,隔开例如:required:true,url:true');
- }
- break;
- case 'textarea':
- $menu['value'] = json_decode($menu['value'], true);
- //多行文本
- if (!empty($menu['high'])) {
- $formbuider[] = $this->builder->textarea('value', '默认值', $menu['value'])->rows(5);
- $formbuider[] = $this->builder->number('width', '文本框宽', (int)$menu['width']);
- $formbuider[] = $this->builder->number('high', '多行文本框高', (int)$menu['high']);
- } else {
- $formbuider[] = $this->builder->input('value', '默认值', $menu['value']);
- }
- break;
- case 'radio':
- $formbuider = array_merge($formbuider, $this->createRadioForm($menu));
- //单选和多选参数配置
- if (!empty($menu['parameter'])) {
- $formbuider[] = $this->builder->textarea('parameter', '配置参数', $menu['parameter'])->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
- }
- break;
- case 'checkbox':
- $formbuider = array_merge($formbuider, $this->createCheckboxForm($menu));
- //单选和多选参数配置
- if (!empty($menu['parameter'])) {
- $formbuider[] = $this->builder->textarea('parameter', '配置参数', $menu['parameter'])->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
- }
- break;
- case 'upload':
- $formbuider = array_merge($formbuider, $this->createUploadForm(($menu['upload_type']), $menu));
- //上传类型选择
- if (!empty($menu['upload_type'])) {
- $formbuider[] = $this->builder->radio('upload_type', '上传类型', $menu['upload_type'])->options([['value' => 1, 'label' => '单图'], ['value' => 2, 'label' => '多图'], ['value' => 3, 'label' => '文件']]);
- }
- break;
- case 'switch':
- $formbuider = array_merge($formbuider, $this->createSwitchForm($menu));
- break;
- }
- $formbuider[] = $this->builder->number('sort', '排序', (int)$menu['sort']);
- $formbuider[] = $this->builder->radio('status', '状态', $menu['status'])->options([['value' => 1, 'label' => '显示'], ['value' => 0, 'label' => '隐藏']]);
- return create_form('编辑字段', $formbuider, $this->url('/setting/config/' . $id), 'PUT');
- }
-
- /**
- * 字段状态
- * @return array
- */
- public function formStatus(): array
- {
- return [['value' => 1, 'label' => '显示'], ['value' => 0, 'label' => '隐藏']];
- }
-
- /**
- * 选择文文件类型
- * @return array
- */
- public function uploadType(): array
- {
- return [
- ['value' => 1, 'label' => '单图']
- , ['value' => 2, 'label' => '多图']
- , ['value' => 3, 'label' => '文件']
- ];
- }
-
- /**
- * 选择文本框类型
- * @return array
- */
- public function textType(): array
- {
- return [
- ['value' => 'input', 'label' => '文本框']
- , ['value' => 'dateTime', 'label' => '日期时间']
- , ['value' => 'date', 'label' => '日期']
- , ['value' => 'time', 'label' => '时间']
- , ['value' => 'color', 'label' => '颜色']
- , ['value' => 'number', 'label' => '数字']
- ];
- }
-
- /**
- * 获取创建配置规格表单
+ * 添加配置字段
* @param int $type
* @param int $tab_id
- * @return array
- * @throws \FormBuilder\Exception\FormBuilderException
+ * @retuarr@throws \FormBuilder\Exception\FormBuilderException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
- public function createFormRule(int $type, int $tab_id): array
+ public function addFieldForm(int $type, int $tab_id): array
{
/** @var SystemConfigTabServices $service */
$service = app()->make(SystemConfigTabServices::class);
@@ -1204,10 +1366,7 @@ class SystemConfigServices extends BaseServices
switch ($type) {
case 0://文本框
$form_type = 'text';
- $info_type = $this->builder->select('input_type', '类型')->setOptions($this->textType());
- $parameter[] = $this->builder->input('value', '默认值');
- $parameter[] = $this->builder->number('width', '文本框宽', 100);
- $parameter[] = $this->builder->input('required', '验证规则')->placeholder('多个请用,隔开例如:required:true,url:true');
+ $parameter[] = $this->createTextInputTypeForm(['input_type' => 'input']);
break;
case 1://多行文本框
$form_type = 'textarea';
@@ -1217,20 +1376,32 @@ class SystemConfigServices extends BaseServices
break;
case 2://单选框
$form_type = 'radio';
- $parameter[] = $this->builder->textarea('parameter', '配置参数')->placeholder("参数方式例如:\n1=>男\n2=>女\n3=>保密");
+ $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>男\n2=>女\n3=>保密")->rows(3)->placeholder("参数方式例如:\n1=>男\n2=>女\n3=>保密")->required('配置参数不能为空')->appendRule('suffix', [
+ 'type' => 'div',
+ 'class' => 'tips-info',
+ 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:
1=>男
2=>女
3=>保密']
+ ]);
$parameter[] = $this->builder->input('value', '默认值');
break;
case 3://文件上传
$form_type = 'upload';
- $parameter[] = $this->builder->radio('upload_type', '上传类型', 1)->options($this->uploadType());
+ $parameter = array_merge($parameter, $this->createUploadForm(1, ['menu_name' => 'value', 'info' => '默认值', 'value' => ''], true));
break;
case 4://多选框
$form_type = 'checkbox';
- $parameter[] = $this->builder->textarea('parameter', '配置参数')->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
+ $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>白色\n2=>红色\n3=>黑色")->rows(3)->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色")->required('配置参数不能为空')->appendRule('suffix', [
+ 'type' => 'div',
+ 'class' => 'tips-info',
+ 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:
1=>白色
2=>红色
3=>黑色']
+ ]);
break;
case 5://下拉框
$form_type = 'select';
- $parameter[] = $this->builder->textarea('parameter', '配置参数')->placeholder("参数方式例如:\n1=>白色\n2=>红色\n3=>黑色");
+ $parameter[] = $this->builder->textarea('parameter', '配置参数', "1=>分类一\n2=>分类二\n3=>分类三")->rows(3)->placeholder("参数方式例如:\n1=>分类一\n2=>分类二\n3=>分类三")->required('配置参数不能为空')->appendRule('suffix', [
+ 'type' => 'div',
+ 'class' => 'tips-info',
+ 'domProps' => ['innerHTML' => '参数说明:=>前面是参数值,后面是参数名称,每行一个参数,=>分割符不能换,例如:
1=>分类一
2=>分类二
3=>分类三']
+ ]);
break;
case 6://开关
$form_type = 'switch';
@@ -1241,7 +1412,7 @@ class SystemConfigServices extends BaseServices
$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' => '是']])->appendRule('suffix', [
+ $formbuider[] = $this->builder->radio('level', '联动显示', 0)->options([['value' => 0, 'label' => '否'], ['value' => 1, 'label' => '是']])->requiredNum()->appendRule('suffix', [
'type' => 'div',
'class' => 'tips-info',
'domProps' => ['innerHTML' => '否:默认正常展示此配置;是:此配置默认隐藏,当选中下方对应配置的值时,此配置才会显示']
@@ -1252,18 +1423,26 @@ class SystemConfigServices extends BaseServices
if ($info_type) {
$formbuider[] = $info_type;
}
- $formbuider[] = $this->builder->input('info', '配置名称')->autofocus(1);
- $formbuider[] = $this->builder->input('menu_name', '字段变量')->placeholder('例如:site_url');
- $formbuider[] = $this->builder->input('desc', '表单说明');
+ $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($this->formStatus());
+ $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
@@ -1273,7 +1452,7 @@ class SystemConfigServices extends BaseServices
*/
public function linkData($tab_id)
{
- $linkData = $this->selectList(['config_tab_id' => $tab_id, 'type' => 'radio', 'level' => 0], 'info as label,id as value,parameter')->toArray();
+ $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']);
@@ -1339,29 +1518,70 @@ class SystemConfigServices extends BaseServices
*/
public function valiDateValue($data)
{
+
+ // 检查数据和验证规则是否存在
if (!$data || !isset($data['required']) || !$data['required']) {
return true;
}
- $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]));
- switch ($k) {
- case 'required':
- if ($v == 'true' && $data['value'] === '') {
- throw new AdminException('{:name}请输入默认值', ['name' => $data['info'] ?? '']);
- }
- break;
- case 'url':
- if ($v == 'true' && !check_link($data['value'])) {
- throw new AdminException('{:name}请输入正确url', ['name' => $data['info'] ?? '']);
- }
- break;
+
+ $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;
}
/**
@@ -1497,4 +1717,53 @@ WSS;
}
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);
+ }
}