表单细节优化

feat/task1-c-wallet
gongfuxiang 2025-09-26 21:03:41 +08:00
parent e8e3a66e95
commit 639d05521e
35 changed files with 4786 additions and 2177 deletions

View File

@ -47,6 +47,7 @@ class FormInputData extends Base
*/
public function Detail()
{
//print_r($this->data_detail);die;
return MyView();
}

View File

@ -48,21 +48,18 @@ class FormInput extends Common
*/
public function Index()
{
if(!empty($this->data_request['id']))
$params = $this->data_request;
$params['user'] = $this->user;
$form_input_data = FormInputService::FormInputData($params);
if(!empty($form_input_data))
{
// 获取diy数据
$data = FormInputService::FormInputData($this->data_request);
// 访问统计
FormInputService::FormInputAccessCountInc(['forminput_id'=>$form_input_data['id']]);
// 返回数据
$result = SystemBaseService::DataReturn([
'data' => $data
'data' => $form_input_data
]);
// 访问统计
if(!empty($result['data']) && !empty($result['data']['data']))
{
FormInputService::FormInputAccessCountInc(['forminput_id'=>$result['data']['data']['id']]);
}
return ApiService::ApiDataReturn($result);
}
return ApiService::ApiDataReturn(DataReturn(MyLang('no_data'), -1));
@ -94,7 +91,7 @@ class FormInput extends Common
$params = [
'width' => 100,
'height' => 28,
'key_prefix' => input('type', 'forminput'),
'key_prefix' => 'forminput',
'expire_time' => MyC('common_verify_expire_time'),
];
$verify = new \base\Verify($params);

View File

@ -33,9 +33,6 @@ class Ueditor extends Common
{
// 调用父类前置方法
parent::__construct();
// 是否登录
$this->IsLogin();
}
/**

View File

@ -48,22 +48,19 @@ class FormInput extends Common
*/
public function Index()
{
$data = [];
if(!empty($this->data_request['id']))
$params = $this->data_request;
$params['user'] = $this->user;
$form_input_data = FormInputService::FormInputData($params);
if(!empty($form_input_data))
{
// 获取diy数据
$data = FormInputService::FormInputData($this->data_request);
// 访问统计
if(!empty($data))
{
FormInputService::FormInputAccessCountInc(['forminput_id'=>$data['id']]);
}
FormInputService::FormInputAccessCountInc(['forminput_id'=>$form_input_data['id']]);
}
MyViewAssign([
'form_input_data' => $data,
'is_header' => 0,
'is_footer' => 0,
'form_input_data' => $form_input_data,
'editor_path_type' => empty($form_input_data) ? '' : 'forminputdata-'.$form_input_data['id'],
'is_header' => 0,
'is_footer' => 0,
]);
return MyView();
}
@ -94,7 +91,7 @@ class FormInput extends Common
$params = [
'width' => 100,
'height' => 28,
'key_prefix' => input('type', 'forminput'),
'key_prefix' => 'forminput',
'expire_time' => MyC('common_verify_expire_time'),
];
$verify = new \base\Verify($params);

View File

@ -3,6 +3,10 @@
<i class="am-icon-eye"></i>
<span>{{:MyLang('detail_title')}}</span>
</button>
<!-- <a class="am-btn am-btn-secondary am-btn-xs am-radius am-btn-block" href="{{:MyUrl('index/forminput/index', ['id'=>$module_data['forminput_id'], 'did'=>$module_data['id']])}}" target="_blank">
<i class="am-icon-edit"></i>
<span>{{:MyLang('edit_title')}}</span>
</a> -->
<button type="button" class="am-btn am-btn-danger am-btn-xs am-radius am-btn-block submit-delete" data-url="{{:MyUrl('index/forminputdata/delete')}}" data-id="{{$module_data.id}}" data-key="ids">
<i class="iconfont icon-delete"></i>
<span>{{:MyLang('delete_title')}}</span>

View File

@ -22,11 +22,11 @@
</div>
<div class="am-form-group am-form-group-refreshing am-margin-top-main am-form-input-material">
<input type="password" name="pwd" class="am-radius am-form-field input-padding-right-max" pattern="{{:MyConst('common_regex_pwd')}}" data-validation-message="{{:MyLang('user.form_item_password_message')}}" autocomplete="new-password" data-is-clearout="0" required />
<span class="am-input-group-btn">
<button class="am-btn am-btn-default am-radius am-icon-eye eye-submit" type="button"></button>
</span>
<span class="am-material-bar"></span>
<input type="password" name="pwd" class="am-radius am-form-field input-padding-right-max" pattern="{{:MyConst('common_regex_pwd')}}" data-validation-message="{{:MyLang('user.form_item_password_message')}}" autocomplete="new-password" data-is-clearout="0" required />
<span class="am-input-group-btn">
<button class="am-btn am-btn-default am-radius am-icon-eye eye-submit" type="button"></button>
</span>
<span class="am-material-bar"></span>
<label class="am-material-label">{{:MyLang('user.form_item_password')}}</label>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,10 @@
<!-- conntent start -->
<div class="am-g inside create">
<form class="am-form am-form-horizontal form-validation" method="post" action="{{:MyUrl('install/index/confirm')}}" request-type="ajax-fun" request-value="FormBackConfirm" timeout="60000">
<!-- 温馨提示 -->
<div class="am-alert am-radius" data-am-alert>
<button type="button" class="am-close">&times;</button>
<p class="am-text-sm">
<strong>温馨提示</strong>
</p>
<p class="am-text-sm"><strong>温馨提示</strong></p>
<div class="am-padding-left-sm am-text-xs am-margin-top-xs">
<p>建议采用utf8mb4编码、MySQL版本5.6或5.7</p>
{{if !empty($charset_type_list)}}
@ -22,70 +21,133 @@
</div>
</div>
<div class="am-panel am-panel-default am-radius">
<div class="am-panel-hd">
<!-- 数据库配置 -->
<div class="am-panel am-panel-default am-radius config-section">
<div class="am-panel-hd section-header">
<div class="header-icon">
<div class="icon-glow"></div>
<i class="am-icon-database"></i>
</div>
<h2 class="am-margin-0">数据库配置信息</h2>
<p class="header-subtitle">Database Configuration</p>
</div>
<div class="am-panel-bd">
<div class="am-form-group row">
<div class="am-panel-bd config-grid">
<div class="am-form-group row form-group">
<label>数据库类型<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_TYPE" placeholder="数据库类型" value="mysql" class="am-radius am-input-sm" readonly data-validation-message="请选择数据库类型" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-tag"></i>
</div>
<input type="text" name="DB_TYPE" placeholder="数据库类型" value="mysql" class="am-radius am-input-sm form-input" readonly data-validation-message="请选择数据库类型" data-is-clearout="0" required />
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库编码<span class="am-form-group-label-tips-must">*</span></label>
<select class="am-input-sm am-radius chosen-select" name="DB_CHARSET" data-validation-message="请选择数据编码" required>
{{if !empty($charset_type_list)}}
{{foreach $charset_type_list as $v}}
<option value="{{$v.charset}}">{{$v.charset}} - {{$v.collate}} mysql版本>={{$v.version}}</option>
{{/foreach}}
{{/if}}
</select>
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-font"></i>
</div>
<select class="am-input-sm am-radius form-input" name="DB_CHARSET" data-validation-message="请选择数据编码" data-is-clearout="0" required>
{{if !empty($charset_type_list)}}
{{foreach $charset_type_list as $v}}
<option value="{{$v.charset}}">{{$v.charset}} - {{$v.collate}} mysql版本>={{$v.version}}</option>
{{/foreach}}
{{/if}}
</select>
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库服务器<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_HOST" placeholder="数据库服务器" value="127.0.0.1" class="am-radius am-input-sm" data-validation-message="请填写数据库服务器地址" required />
<a href="javascript:;" class="am-icon-question-circle text-copy-submit" data-am-popover="{content: '如果连接不通,可以尝试使用 localhost 试试!', trigger: 'hover focus', theme: 'sm'}" data-value="localhost"></a>
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-server"></i>
</div>
<input type="text" name="DB_HOST" placeholder="数据库服务器" value="127.0.0.1" class="am-radius am-input-sm form-input" data-validation-message="请填写数据库服务器地址" data-is-clearout="0" required />
<a href="javascript:;" class="am-icon-question-circle text-copy-submit input-help" data-am-popover="{content: '如果连接不通,可以尝试使用 localhost 试试!', trigger: 'hover focus', theme: 'sm'}" data-value="localhost"></a>
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库端口<span class="am-form-group-label-tips-must">*</span></label>
<input type="number" name="DB_PORT" placeholder="数据库端口" value="3306" class="am-radius am-input-sm" data-validation-message="请填写数据库端口" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-plug"></i>
</div>
<input type="number" name="DB_PORT" placeholder="数据库端口" value="3306" class="am-radius am-input-sm form-input" data-validation-message="请填写数据库端口" data-is-clearout="0" required />
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库名<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_NAME" placeholder="数据库名" value="" class="am-radius am-input-sm" data-validation-message="请填写数据库名" required />
<a href="javascript:;" class="am-icon-question-circle" data-am-popover="{content: '请先创建好数据库,编码和选择的保持一致!', trigger: 'hover focus', theme: 'sm'}"></a>
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-folder-open"></i>
</div>
<input type="text" name="DB_NAME" placeholder="数据库名" value="" class="am-radius am-input-sm form-input" data-validation-message="请填写数据库名" data-is-clearout="0" required />
<a href="javascript:;" class="am-icon-question-circle input-help" data-am-popover="{content: '请先创建好数据库,编码和选择的保持一致!', trigger: 'hover focus', theme: 'sm'}"></a>
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库用户名<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_USER" placeholder="数据库用户名" value="" class="am-radius am-input-sm" data-validation-message="请填写数据库用户名" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-user"></i>
</div>
<input type="text" name="DB_USER" placeholder="数据库用户名" value="" class="am-radius am-input-sm form-input" data-validation-message="请填写数据库用户名" data-is-clearout="0" required />
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据库密码<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_PWD" placeholder="数据库密码" value="" class="am-radius am-input-sm" data-validation-message="请填写数据库密码" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-lock"></i>
</div>
<input type="password" name="DB_PWD" placeholder="数据库密码" value="" class="am-radius am-input-sm form-input" data-validation-message="请填写数据库密码" data-is-clearout="0" required />
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>数据表前缀<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="DB_PREFIX" placeholder="数据表前缀" value="sxo_" class="am-radius am-input-sm" data-validation-message="请填写数据表前缀、格式最多6个字符" maxlength="6" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-code-fork"></i>
</div>
<input type="text" name="DB_PREFIX" placeholder="数据表前缀" value="sxo_" class="am-radius am-input-sm form-input" data-validation-message="请填写数据表前缀、格式最多6个字符" maxlength="6" data-is-clearout="0" required />
</div>
</div>
</div>
</div>
<div class="am-panel am-panel-default am-radius">
<div class="am-panel-hd">
<!-- 管理员账号 -->
<div class="am-panel am-panel-default am-radius config-section">
<div class="am-panel-hd section-header">
<div class="header-icon">
<div class="icon-glow"></div>
<i class="am-icon-user-secret"></i>
</div>
<h2 class="am-margin-0">管理员账号信息</h2>
<p class="header-subtitle">Administrator Account</p>
</div>
<div class="am-panel-bd">
<div class="am-form-group row">
<div class="am-panel-bd config-grid">
<div class="am-form-group row form-group">
<label>管理员账号<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="ADMIN_USERNAME" placeholder="账号格式2~18个字符之间" value="admin" minlength="2" maxlength="18" class="am-radius am-input-sm" data-validation-message="请填写管理员账号、格式2~18个字符之间" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-user"></i>
</div>
<input type="text" name="ADMIN_USERNAME" placeholder="账号格式2~18个字符之间" value="admin" minlength="2" maxlength="18" class="am-radius am-input-sm form-input" data-validation-message="请填写管理员账号、格式2~18个字符之间" data-is-clearout="0" required />
</div>
</div>
<div class="am-form-group row">
<div class="am-form-group row form-group">
<label>管理员密码<span class="am-form-group-label-tips-must">*</span></label>
<input type="text" name="ADMIN_PWD" placeholder="密码格式6~18个字符之间" value="" minlength="6" maxlength="18" class="am-radius am-input-sm" data-validation-message="请填写管理员密码、格式6~18个字符之间" required />
<div class="form-input-wrapper">
<div class="input-icon">
<i class="am-icon-key"></i>
</div>
<input type="password" name="ADMIN_PWD" placeholder="密码格式6~18个字符之间" value="" minlength="6" maxlength="18" class="am-radius am-input-sm form-input" data-validation-message="请填写管理员密码、格式6~18个字符之间" data-is-clearout="0" required />
</div>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="agree ongoing-button">
<a href="{{:MyUrl('install/index/check')}}" class="am-btn am-btn-secondary am-radius am-btn-xs">
<i class="am-icon-arrow-left"></i>
@ -98,7 +160,7 @@
</div>
</form>
</div>
<!-- conntent end -->
<!-- conntent end -->
{{:ModuleInclude('public/footer')}}
<script type="text/javascript">

View File

@ -4,29 +4,91 @@
{{:ModuleInclude('public/header_nav')}}
<!-- conntent start -->
<div class="am-g inside agreement">
<h2>安装协议</h2>
<ul>
<li class="title">ShopXO遵循MIT开源协议发布</li>
<li>MIT许可证之名源自麻省理工学院Massachusetts Institute of Technology, MIT又称「X条款」X License或「X11条款」X11 License</li>
<li>MIT内容与三条款BSD许可证3-clause BSD license内容颇为近似但是赋予软体被授权人更大的权利与更少的限制。</li>
<li class="title">协议条款</li>
<li>1. 被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软体及软体的副本。</li>
<li>2. 被授权人可根据程式的需要修改授权条款为适当的内容。</li>
<li>3. 在软件和软件的所有副本中都必须包含版权声明和许可声明。</li>
<li class="am-margin-top-xl">协议地址:<a href="https://license.shopxo.net/" target="_blank">https://license.shopxo.net/</a></li>
<li>英文原文:<a href="https://opensource.org/licenses/mit-license.php" target="_blank">https://opensource.org/licenses/mit-license.php</a></li>
</ul>
<div class="tech-container">
<div class="agreement-section">
<div class="section-header">
<div class="header-icon">
<div class="icon-glow"></div>
<i class="am-icon-shield"></i>
</div>
<h2>安装协议</h2>
<p class="header-subtitle">ShopXO Installation License Agreement</p>
</div>
<div class="agreement-content">
<div class="license-card">
<div class="card-header">
<h3><i class="am-icon-bookmark"></i> 开源协议</h3>
</div>
<div class="card-body">
<div class="protocol-item">
<div class="protocol-title">
<span class="badge">MIT</span>
<h4>ShopXO遵循MIT开源协议发布</h4>
</div>
<p>MIT许可证之名源自麻省理工学院Massachusetts Institute of Technology, MIT又称「X条款」X License或「X11条款」X11 License</p>
<p>MIT内容与三条款BSD许可证3-clause BSD license内容颇为近似但是赋予软体被授权人更大的权利与更少的限制。</p>
</div>
</div>
</div>
<div class="agree ongoing-button">
<button type="submit" class="am-btn am-btn-danger am-radius am-btn-xs window-close-event">
<i class="am-icon-remove"></i>
<span>拒绝并关闭</span>
</button>
<a href="{{:MyUrl('install/index/check')}}" class="am-btn am-btn-success am-radius am-btn-xs">
<i class="am-icon-arrow-right"></i>
<span>同意并安装</span>
</a>
<div class="license-card">
<div class="card-header">
<h3><i class="am-icon-list-ol"></i> 协议条款</h3>
</div>
<div class="card-body">
<div class="terms-list">
<div class="term-item">
<div class="term-number">1</div>
<div class="term-content">
<h5>使用权限</h5>
<p>被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软体及软体的副本。</p>
</div>
</div>
<div class="term-item">
<div class="term-number">2</div>
<div class="term-content">
<h5>条款修改</h5>
<p>被授权人可根据程式的需要修改授权条款为适当的内容。</p>
</div>
</div>
<div class="term-item">
<div class="term-number">3</div>
<div class="term-content">
<h5>版权声明</h5>
<p>在软件和软件的所有副本中都必须包含版权声明和许可声明。</p>
</div>
</div>
</div>
</div>
</div>
<div class="license-links">
<div class="link-item">
<div class="link-content">
<span>协议地址:</span>
<a href="https://license.shopxo.net/" target="_blank">https://license.shopxo.net/</a>
</div>
</div>
<div class="link-item">
<div class="link-content">
<span>英文原文:</span>
<a href="https://opensource.org/licenses/mit-license.php" target="_blank">https://opensource.org/licenses/mit-license.php</a>
</div>
</div>
</div>
</div>
<div class="section-actions">
<button type="submit" class="tech-btn tech-btn-reject window-close-event">
<i class="am-icon-remove"></i>
<span>拒绝并关闭</span>
</button>
<a href="{{:MyUrl('install/index/check')}}" class="tech-btn tech-btn-accept">
<i class="am-icon-arrow-right"></i>
<span>同意并安装</span>
</a>
</div>
</div>
</div>
<!-- conntent end -->

View File

@ -4,26 +4,112 @@
{{:ModuleInclude('public/header_nav')}}
<!-- conntent start -->
<div class="am-g inside success">
<i class="am-icon-btn am-success am-icon-sm am-icon-check"></i>
<h2>恭喜您安装成功</h2>
<div class="box">
{{if !empty($admin_run)}}
<a href="{{$admin_run}}" target="_blank">点击访问后台管理 >></a><br />
<p class="am-margin-vertical-sm">
<span class="text-copy-submit" data-value="{{$admin_run}}">
<span>后台管理地址: </span>
<strong>{{$admin_run}}</strong>
<i class="am-icon-copy"></i>
</span>
</p>
{{/if}}
<p class="tips-sweet am-radius">默认后台地址入口文件在站点根目录和public目录下默认以 admin 开头 .php 结尾的文件名称。</p>
<br /><br />
<a href="{{$Think.__MY_URL__}}" target="_blank">点击访问首页 >></a>
<p class="tips-sweet am-radius">请尽快修改管理员密码,以防被非法入侵。<br />并删除 ./app 目录下的 install 目录。</p>
<div class="tech-container">
<div class="success-section">
<div class="success-animation">
<div class="success-icon">
<div class="icon-ring"></div>
<div class="icon-check">
<i class="am-icon-check"></i>
</div>
<div class="icon-particles">
<div class="particle"></div>
<div class="particle"></div>
<div class="particle"></div>
<div class="particle"></div>
<div class="particle"></div>
<div class="particle"></div>
</div>
</div>
</div>
<div class="success-content">
<h1>恭喜您安装成功</h1>
<p class="success-subtitle">ShopXO has been successfully installed!</p>
<div class="success-cards">
{{if !empty($admin_run)}}
<div class="success-card">
<div class="card-content">
<h3><i class="am-icon-cog"></i> 管理后台</h3>
<p class="admin-link">
<a href="{{$admin_run}}" target="_blank" class="tech-btn tech-btn-primary">
<i class="am-icon-external-link"></i>
<span>点击访问后台管理</span>
</a>
</p>
<div class="address-info">
<span class="text-copy-submit" data-value="{{$admin_run}}">
<span class="label">后台地址:</span>
<strong>{{$admin_run}}</strong>
<i class="am-icon-copy copy-icon"></i>
</span>
</div>
</div>
</div>
{{/if}}
<div class="success-card">
<div class="card-content">
<h3><i class="am-icon-home"></i> 网站首页</h3>
<p class="home-link">
<a href="{{$Think.__MY_URL__}}" target="_blank" class="tech-btn tech-btn-success">
<i class="am-icon-external-link"></i>
<span>点击访问首页</span>
</a>
</p>
<div class="address-info">
<span class="text-copy-submit" data-value="{{$Think.__MY_URL__}}">
<span class="label">首页地址:</span>
<strong>{{$Think.__MY_URL__}}</strong>
<i class="am-icon-copy copy-icon"></i>
</span>
</div>
</div>
</div>
</div>
<div class="security-tips">
<div class="tips-header">
<div class="tips-icon">
<i class="am-icon-shield"></i>
</div>
<h3>安全提示</h3>
</div>
<div class="tips-content">
<div class="tip-item">
<div class="tip-number">1</div>
<div class="tip-text">
<strong>修改密码</strong>
<p>请尽快修改管理员密码,以防被非法入侵</p>
</div>
</div>
<div class="tip-item">
<div class="tip-number">2</div>
<div class="tip-text">
<strong>删除安装目录</strong>
<p>请删除 ./app 目录下的 install 目录以提高安全性</p>
</div>
</div>
<div class="tip-item">
<div class="tip-number">3</div>
<div class="tip-text">
<strong>定期备份</strong>
<p>建议定期备份数据库和文件,确保数据安全</p>
</div>
</div>
</div>
</div>
<div class="completion-info">
<div class="info-item">
<i class="am-icon-info-circle"></i>
<span>默认后台地址入口文件在站点根目录和public目录下默认以 admin 开头 .php 结尾的文件名称</span>
</div>
</div>
</div>
</div>
</div>
<!-- conntent end -->
<!-- conntent end -->
{{:ModuleInclude('public/footer')}}

View File

@ -1,8 +1,5 @@
{{:ModuleInclude('public/header')}}
<!-- header nav -->
{{:ModuleInclude('public/header_nav')}}
<!-- conntent start -->
<div class="am-g">
<div class="am-text-center am-margin-xl am-padding-xl">

View File

@ -1,30 +1,67 @@
<div class="body-content-formal-container">
<div class="header-nav" data-am-sticky="{animation: 'slide-top'}">
<div class="inside">
<p class="logo-name">
<strong>Shop<em>XO</em></strong>
<span class="desc">安装向导 {{$Think.APPLICATION_VERSION}}</span>
</p>
<ul class="schedule {{if isset($action) && $action == 'index'}}active{{/if}}">
<li class="number">1</li>
<li class="word">使用协议</li>
</ul>
<ul class="schedule {{if isset($action) && $action == 'check'}}active{{/if}}">
<li class="number">2</li>
<li class="word">环境检测</li>
</ul>
<ul class="schedule {{if isset($action) && $action == 'create'}}active{{/if}}">
<li class="number">3</li>
<li class="word">创建数据</li>
</ul>
<ul class="schedule {{if isset($action) && $action == 'successful'}}active{{/if}}">
<li class="number">4</li>
<li class="word">安装完成</li>
</ul>
<div class="tech-header-nav" data-am-sticky="{animation: 'slide-top'}">
<div class="nav-container">
<div class="brand-section">
<div class="brand-text">
<h1 class="brand-name">
Shop<em>XO</em>
</h1>
<span class="brand-version">安装向导 {{$Think.APPLICATION_VERSION}}</span>
</div>
</div>
<div class="progress-tracker">
<div class="progress-line"></div>
<div class="step-item {{if isset($action) && $action == 'index'}}active{{/if}} {{if isset($action) && $action != 'index'}}completed{{/if}}">
<div class="step-indicator">
<div class="step-number">1</div>
<div class="step-icon">
<i class="am-icon-file-text-o"></i>
</div>
<div class="step-check">
<i class="am-icon-check"></i>
</div>
</div>
<div class="step-label">使用协议</div>
</div>
<div class="step-item {{if isset($action) && $action == 'check'}}active{{/if}} {{if isset($action) && ($action == 'create' || $action == 'successful')}}completed{{/if}}">
<div class="step-indicator">
<div class="step-number">2</div>
<div class="step-icon">
<i class="am-icon-desktop"></i>
</div>
<div class="step-check">
<i class="am-icon-check"></i>
</div>
</div>
<div class="step-label">环境检测</div>
</div>
<div class="step-item {{if isset($action) && $action == 'create'}}active{{/if}} {{if isset($action) && $action == 'successful'}}completed{{/if}}">
<div class="step-indicator">
<div class="step-number">3</div>
<div class="step-icon">
<i class="am-icon-database"></i>
</div>
<div class="step-check">
<i class="am-icon-check"></i>
</div>
</div>
<div class="step-label">创建数据</div>
</div>
<div class="step-item {{if isset($action) && $action == 'successful'}}active{{/if}}">
<div class="step-indicator">
<div class="step-number">4</div>
<div class="step-icon">
<i class="am-icon-check-circle-o"></i>
</div>
<div class="step-check">
<i class="am-icon-check"></i>
</div>
</div>
<div class="step-label">安装完成</div>
</div>
</div>
</div>
<!-- <div class="am-container am-text-center am-text-danger am-padding-top-lg am-padding-bottom-sm">
<span>v8.1版本由</span>
<a href="#" target="_blank"><strong>XXXXXX</strong></a>
<span>独家赞助发布!</span>
</div> -->
</div>

View File

@ -242,6 +242,11 @@ return [
'plugins_no_data_tips' => '無挿件數據',
'map_coordinate_error' => '座標有誤',
'no_config_data_tips' => '未配寘數據',
'not_upload_error' => '請上傳數據',
'not_choice_error' => '請選擇數據',
'not_fill_in_error' => '請填寫數據',
'data_length_min_tips' => '數據長度低於限制',
'data_length_max_tips' => '數據長度高於限制',
'config_empty_tips' => '配寘為空',
'config_error_tips' => '配寘有誤',
'data_empty_tips' => '數據為空',

View File

@ -242,6 +242,11 @@ return [
'plugins_no_data_tips' => 'No plugins data',
'map_coordinate_error' => 'Incorrect coordinates',
'no_config_data_tips' => 'No data configured',
'not_upload_error' => 'Please upload data',
'not_choice_error' => 'Please select data',
'not_fill_in_error' => 'Please fill in the data',
'data_length_min_tips' => 'The data length is below the limit',
'data_length_max_tips' => 'The data length exceeds the limit',
'config_empty_tips' => 'Configuration is empty',
'config_error_tips' => 'Incorrect configuration',
'data_empty_tips' => 'Data is empty',

View File

@ -242,6 +242,11 @@ return [
'plugins_no_data_tips' => 'Datos sin plug - in',
'map_coordinate_error' => 'Coordenadas incorrectas',
'no_config_data_tips' => 'Datos no configurados',
'not_upload_error' => 'Por favor, suba los datos',
'not_choice_error' => 'Por favor, seleccione los datos',
'not_fill_in_error' => 'Por favor, rellene los datos',
'data_length_min_tips' => 'La longitud de los datos está por debajo del límite',
'data_length_max_tips' => 'La longitud de los datos está por encima del límite',
'config_empty_tips' => 'Configuración vacía',
'config_error_tips' => 'Configuración incorrecta',
'data_empty_tips' => 'Los datos están vacíos',

View File

@ -242,6 +242,11 @@ return [
'plugins_no_data_tips' => '无插件数据',
'map_coordinate_error' => '坐标有误',
'no_config_data_tips' => '未配置数据',
'not_upload_error' => '请上传数据',
'not_choice_error' => '请选择数据',
'not_fill_in_error' => '请填写数据',
'data_length_min_tips' => '数据长度低于限制',
'data_length_max_tips' => '数据长度高于限制',
'config_empty_tips' => '配置为空',
'config_error_tips' => '配置有误',
'data_empty_tips' => '数据为空',

View File

@ -161,189 +161,349 @@ class FormInputModule
* @version 1.0.0
* @date 2025-07-30
* @desc description
* @param [array] $config [表单配置]
* @param [array] $data [保存的表单数据]
* @param [array] $config [表单配置]
* @param [array] $data [保存的表单数据]
* @param [string] $parent_name [父级表单名称]
*/
public static function FormInputDataWriteHandle($config, $data)
public static function FormInputDataWriteHandle($config, $data, $parent_name = '')
{
$result = [];
if(!empty($config) && !empty($config['diy_data']))
{
foreach($config['diy_data'] as $v)
{
$form_name = empty($v['form_name']) ? (empty($v['id']) ? '' : $v['id']) : $v['form_name'];
if(!empty($form_name))
// 是否启用
if(!isset($v['is_enable']) || $v['is_enable'] != 1)
{
$custom_option_list = empty($data[$form_name.'_custom_option_list']) ? [] : $data[$form_name.'_custom_option_list'];
switch($v['key'])
{
// 富文本
case 'rich-text' :
if(array_key_exists($form_name, $data))
{
$value = $data[$form_name];
if(!empty($value))
{
$value = ResourcesService::ContentStaticReplace(htmlspecialchars_decode($value), 'add');
}
$result[$form_name] = [
'name' => $v['name'],
'value' => $value,
'key' => $v['key'],
];
}
break;
continue;
}
// 附件
case 'upload-img' :
case 'upload-video' :
case 'upload-attachments' :
if(array_key_exists($form_name, $data))
// 是否存在表单名称
$form_name = empty($v['form_name']) ? (empty($v['id']) ? '' : $v['id']) : $v['form_name'];
if(empty($form_name))
{
continue;
}
// 配置和基础
if(empty($v['com_data']) || empty($v['key']))
{
continue;
}
// 非这些多数据格式的数据,是否需要填写
if(!in_array($v['key'], ['checkbox', 'select-multi', 'radio-btns', 'select', 'date-group', 'address']))
{
if(isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
{
if(in_array($v['key'], ['upload-img', 'upload-attachments', 'upload-video']))
{
// 上传
$msg = MyLang('not_upload_error');
} else if(in_array($v['key'], ['score']))
{
// 选择
$msg = MyLang('not_choice_error');
} else {
// 填写
$msg = MyLang('not_fill_in_error');
}
return DataReturn($msg.'('.$parent_name.$v['name'].')', -1);
}
}
// 自定义列
$custom_option_list = empty($data[$form_name.'_custom_option_list']) ? [] : (is_array($data[$form_name.'_custom_option_list']) ? $data[$form_name.'_custom_option_list'] : json_decode(base64_decode(urldecode($data[$form_name.'_custom_option_list'])), true));
$name = empty($v['com_data']['title']) ? $v['name'] : $v['com_data']['title'];
switch($v['key'])
{
// 子表单
case 'subform' :
$temp_item = [];
if(!empty($data[$form_name]))
{
foreach($data[$form_name] as $sbk=>$sbv)
{
$value = $data[$form_name];
$res = self::FormInputDataWriteHandle(['diy_data'=>$v['com_data']['children']], $sbv, $name.'-');
if($res['code'] != 0)
{
return $res;
}
$temp_item[] = $res['data'];
}
}
if(!empty($temp_item))
{
$result[$form_name] = [
'name' => $name,
'value' => $temp_item,
'key' => $v['key'],
];
}
break;
// 富文本
case 'rich-text' :
if(array_key_exists($form_name, $data))
{
$value = $data[$form_name];
if(!empty($value))
{
$value = ResourcesService::ContentStaticReplace(htmlspecialchars_decode($value), 'add');
}
$result[$form_name] = [
'name' => $name,
'value' => $value,
'key' => $v['key'],
];
}
break;
// 附件
case 'upload-img' :
case 'upload-video' :
case 'upload-attachments' :
if(array_key_exists($form_name, $data))
{
$value = $data[$form_name];
if(!empty($value))
{
$value = is_array($value) ? $value : json_decode(base64_decode(urldecode($value)), true);
if(!empty($value) && is_array($value))
{
$value = ResourcesService::AttachmentPathHandle($value, 'url');
}
$result[$form_name] = [
'name' => $v['name'],
'value' => $value,
'key' => $v['key'],
];
}
break;
// 复选
case 'checkbox' :
// 下拉多选
case 'select-multi' :
if(array_key_exists($form_name, $data))
{
$temp_value = [];
$value = $data[$form_name];
if(!empty($value) && is_array($value))
{
$option_arr = array_merge(empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'], $custom_option_list);
if(!empty($option_arr))
{
foreach($option_arr as $ov)
{
if(!empty($ov['value']) && in_array($ov['value'], $value))
{
$temp_value[] = $ov;
}
}
}
}
$result[$form_name] = [
'name' => $v['name'],
'value' => $temp_value,
'key' => $v['key'],
'value_text' => empty($temp_value) ? '' : implode(', ', array_column($temp_value, 'name')),
];
if(!empty($custom_option_list))
{
$result[$form_name]['custom_option_list'] = $custom_option_list;
} else {
$value = '';
}
}
break;
// 单选
case 'radio-btns' :
// 下拉单选
case 'select' :
if(array_key_exists($form_name, $data))
{
$value = $data[$form_name];
if($value !== '')
{
$option_arr = empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'];
if(!empty($option_arr))
{
foreach($option_arr as $ov)
{
if(!empty($ov['value']) && $ov['value'] == $value)
{
$value = $ov;
break;
}
}
}
}
$result[$form_name] = [
'name' => $v['name'],
'value' => $value,
'key' => $v['key'],
];
if(isset($data[$form_name.'_other_value']))
{
$result[$form_name]['other_value'] = $data[$form_name.'_other_value'];
}
$result[$form_name]['value_text'] = empty($value) ? '' : ((isset($value['is_other']) && $value['is_other'] == 1) ? (isset($result[$form_name]['other_value']) ? $result[$form_name]['other_value'] : '') : $value['name']);
}
break;
// 时间组
case 'date-group' :
$temp_value = [];
$start_key = $form_name.'_start';
$temp_value['start'] = array_key_exists($start_key, $data) ? $data[$start_key] : '';
$end_key = $form_name.'_end';
$temp_value['end'] = array_key_exists($end_key, $data) ? $data[$end_key] : '';
if(count(array_filter($temp_value)) > 0)
{
$result[$form_name] = [
'name' => $v['name'],
'value' => $temp_value,
'key' => $v['key'],
'value_text' => implode('~', $temp_value),
];
}
break;
// 地区地址
case 'address' :
$temp_value = [];
$arr = [
'province_id',
'city_id',
'county_id',
'province_name',
'city_name',
'county_name',
'address',
$result[$form_name] = [
'name' => $name,
'value' => $value,
'key' => $v['key'],
];
foreach($arr as $tv)
{
$ads_key = $form_name.'_'.$tv;
$temp_value[$tv] = array_key_exists($ads_key, $data) ? $data[$ads_key] : '';
}
if(count(array_filter($temp_value)) > 0)
{
$result[$form_name] = [
'name' => $v['name'],
'value' => $temp_value,
'key' => $v['key'],
'value_text' => $temp_value['province_name'].$temp_value['city_name'].$temp_value['county_name'].$temp_value['address'],
];
}
break;
}
break;
// 默认
default :
if(array_key_exists($form_name, $data))
// 复选
case 'checkbox' :
// 下拉多选
case 'select-multi' :
$temp_item = [];
if(array_key_exists($form_name, $data))
{
$temp_value = [];
$value = $data[$form_name];
if($value !== '')
{
$result[$form_name] = [
'name' => $v['name'],
'value' => $data[$form_name],
'key' => $v['key'],
];
if(!is_array($value))
{
$value = explode(',', $value);
}
$option_arr = array_merge(empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'], $custom_option_list);
if(!empty($option_arr))
{
foreach($option_arr as $ov)
{
if(!empty($ov['value']) && in_array($ov['value'], $value))
{
$temp_value[] = $ov;
}
}
}
}
break;
}
$temp_item = [
'name' => $name,
'value' => empty($temp_value) ? '' : array_column($temp_value, 'value'),
'key' => $v['key'],
'value_text' => empty($temp_value) ? '' : implode(', ', array_column($temp_value, 'name')),
];
if(!empty($custom_option_list))
{
$temp_item['custom_option_list'] = $custom_option_list;
}
}
if(!empty($temp_item))
{
$result[$form_name] = $temp_item;
} else {
if(isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
{
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
}
}
break;
// 单选
case 'radio-btns' :
// 下拉单选
case 'select' :
$temp_item = [];
if(array_key_exists($form_name, $data))
{
$temp_value_text = '';
$temp_value = '';
if($data[$form_name] !== '')
{
$option_arr = array_merge(empty($v['com_data']['option_list']) ? [] : $v['com_data']['option_list'], $custom_option_list);
if(!empty($option_arr))
{
foreach($option_arr as $ov)
{
if(!empty($ov['value']) && $ov['value'] == $data[$form_name])
{
$temp_value_text = $ov['name'];
$temp_value = $ov['value'];
break;
}
}
}
}
$temp_item = [
'name' => $name,
'value' => $temp_value,
'key' => $v['key'],
];
if(isset($data[$form_name.'_other_value']))
{
$temp_item['other_value'] = $data[$form_name.'_other_value'];
}
$temp_item['value_text'] = empty($temp_item['other_value']) ? $temp_value_text : $temp_item['other_value'];
}
if(!empty($temp_item))
{
$result[$form_name] = $temp_item;
} else {
if(isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
{
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
}
}
break;
// 时间组
case 'date-group' :
$temp_value = [];
$start_key = $form_name.'_start';
$temp_value['start'] = array_key_exists($start_key, $data) ? $data[$start_key] : '';
$end_key = $form_name.'_end';
$temp_value['end'] = array_key_exists($end_key, $data) ? $data[$end_key] : '';
if(count(array_filter($temp_value)) > 0)
{
$result[$form_name] = [
'name' => $name,
'value' => $temp_value,
'key' => $v['key'],
'value_text' => implode(' ~ ', $temp_value),
];
} else {
if(isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
{
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
}
}
break;
// 地区地址
case 'address' :
$temp_value = [];
$arr = [
'province_id',
'city_id',
'county_id',
'province_name',
'city_name',
'county_name',
'address',
];
foreach($arr as $tv)
{
$ads_key = $form_name.'_'.$tv;
$temp_value[$tv] = array_key_exists($ads_key, $data) ? $data[$ads_key] : '';
}
if(count(array_filter($temp_value)) > 0)
{
$result[$form_name] = [
'name' => $name,
'value' => $temp_value,
'key' => $v['key'],
'value_text' => $temp_value['province_name'].$temp_value['city_name'].$temp_value['county_name'].$temp_value['address'],
];
} else {
if(isset($v['com_data']['is_required']) && $v['com_data']['is_required'] == 1 && empty($data[$form_name]))
{
return DataReturn(MyLang('not_fill_in_error').'('.$parent_name.$name.')', -1);
}
}
break;
// 手机
case 'phone' :
// 是否需要短信验证码
if(!empty($data[$form_name]) && isset($v['com_data']['is_sms_verification']) && $v['com_data']['is_sms_verification'] == 1)
{
// 是否存在验证码
if(empty($data[$form_name.'_verify']))
{
return DataReturn(MyLang('verify_code_empty_tips').'('.$parent_name.$name.')', -1);
}
// 验证码校验
$verify_params = [
'key_prefix' => 'forminput_'.md5($data[$form_name]),
'expire_time' => MyC('common_verify_expire_time'),
];
$obj = new \base\Sms($verify_params);
// 是否已过期
if(!$obj->CheckExpire())
{
return DataReturn(MyLang('verify_code_expire_tips').'('.$parent_name.$name.')', -1);
}
// 是否正确
if(!$obj->CheckCorrect($data[$form_name.'_verify']))
{
return DataReturn(MyLang('verify_code_error_tips').'('.$parent_name.$name.')', -1);
}
}
if(!empty($data[$form_name]))
{
$result[$form_name] = [
'name' => $name,
'value' => $data[$form_name],
'key' => $v['key'],
];
}
break;
// 默认
default :
// 是否限制字数
if(isset($data[$form_name]) && isset($v['com_data']['is_limit_num']) && $v['com_data']['is_limit_num'] == 1)
{
// 当前数值长度
$len = strlen($data[$form_name]);
// 最小值
if(!empty($v['com_data']['min_num']) && $len < $v['com_data']['min_num'])
{
return DataReturn(MyLang('data_length_min_tips').'('.$len.'<'.$v['com_data']['min_num'].' '.$name.')', -1);
}
// 最大值
if(!empty($v['com_data']['max_num']) && $len > $v['com_data']['max_num'])
{
return DataReturn(MyLang('data_length_max_tips').'('.$v['com_data']['max_num'].'>'.$len.' '.$name.')', -1);
}
}
if(array_key_exists($form_name, $data))
{
$result[$form_name] = [
'name' => $name,
'value' => $data[$form_name],
'key' => $v['key'],
];
}
break;
}
}
}
return $result;
return DataReturn('success', 0, $result);
}
/**
@ -388,5 +548,69 @@ class FormInputModule
}
return $data;
}
public static function FormInputDataValueMerge($config, $data)
{
if(!empty($config['diy_data']) && !empty($data))
{
foreach($config['diy_data'] as &$v)
{
$form_name = empty($v['form_name']) ? (empty($v['id']) ? '' : $v['id']) : $v['form_name'];
if(!empty($v['key']) && isset($data[$form_name]))
{
// 数据
$temp = $data[$form_name];
// 覆盖默认值
$v['com_data']['form_value'] = isset($temp['value']) ? $temp['value'] : '';
// 根据类型处理数据
switch($v['key'])
{
// 子表单
case 'subform' :
if(!empty($v['com_data']['form_value']) && is_array($v['com_data']['form_value']))
{
foreach($v['com_data']['form_value'] as $sk=>$sv)
{
if(!empty($sv) && is_array($sv))
{
foreach($sv as $sks=>$svs)
{
$v['com_data']['form_value'][$sk][$sks] = isset($svs['value']) ? $svs['value'] : '';
}
}
}
}
break;
// 时间组
case 'date-group' :
if(!empty($v['com_data']['form_value']) && is_array($v['com_data']['form_value']))
{
$v['com_data']['form_value'] = array_values($v['com_data']['form_value']);
}
break;
}
// 其他值
if($v['com_data']['form_value'] == 'other')
{
$v['com_data']['other_value'] = isset($temp['other_value']) ? $temp['other_value'] : '';
}
// 自定义数据项
if(!empty($temp['custom_option_list']))
{
$v['com_data']['custom_option_list'] = $temp['custom_option_list'];
}
}
}
}
// print_r($config);
// print_r($data);
// die;
return $config;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -9,60 +9,7 @@
<strong>{{$v.name}}</strong>
</dt>
<dd>
{{switch $v.key}}
{{case upload-img}}
{{if !empty($v['value']) and is_array($v['value'])}}
<ul class="am-gallery am-avg-sm-2 am-avg-md-3 am-gallery-default am-padding-0 am-nbfc">
{{foreach $v.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<div class="am-gallery-item am-nbfc am-padding-right-sm am-padding-bottom-sm">
<img src="{{$vs.url}}" class="am-block am-radius common-annex-view-event" data-download-name="{{$vs.name}}" data-is-download="1" />
<p class="am-margin-top-xs">{{$vs.name}}</p>
</div>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case upload-video}}
{{if !empty($v['value']) and is_array($v['value'])}}
<ul class="am-avg-sm-2 am-avg-md-3 am-nbfc">
{{foreach $v.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<video src="{{$vs.url}}" class="am-block am-radius am-max-wh-auto common-annex-view-event" data-download-name="{{$vs.name}}" data-is-download="1" data-type="video"></video>
<p class="am-margin-top-xs">{{$vs.name}}</p>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case upload-attachments}}
{{if !empty($v['value']) and is_array($v['value'])}}
<ul class="am-avg-sm-2 am-avg-md-3 am-nbfc">
{{foreach $v.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<a href="javascript:;" data-value="{{$vs.url}}" data-name="{{$vs.name}}" class="am-block am-radius common-annex-download-event">{{$vs.name}}</a>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case rich-text}}
<div class="richtext">{{$v.value|raw}}</div>
{{/case}}
{{default /}}
{{if isset($v['value_text'])}}
{{$v.value_text}}
{{else /}}
{{$v.value|raw}}
{{/if}}
{{/switch}}
{{:ModuleInclude('../../../module/view/form_input/detail_value', $v)}}
</dd>
{{/if}}
{{/foreach}}

View File

@ -0,0 +1,84 @@
{{if !empty($module_data) and !empty($module_data['key'])}}
{{switch $module_data.key}}
{{case upload-img}}
{{if !empty($module_data['value']) and is_array($module_data['value'])}}
<ul class="am-gallery am-avg-sm-2 am-avg-md-4 am-gallery-default am-padding-0 am-nbfc">
{{foreach $module_data.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<div class="am-gallery-item am-nbfc am-padding-right-sm am-padding-bottom-sm">
<img src="{{$vs.url}}" class="am-block am-radius common-annex-view-event" data-download-name="{{$vs.name}}" data-is-download="1" />
<p class="am-margin-top-xs">{{$vs.name}}</p>
</div>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case upload-video}}
{{if !empty($module_data['value']) and is_array($module_data['value'])}}
<ul class="am-avg-sm-2 am-avg-md-4 am-nbfc">
{{foreach $module_data.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<video src="{{$vs.url}}" class="am-block am-radius am-max-wh-auto common-annex-view-event" data-download-name="{{$vs.name}}" data-is-download="1" data-type="video"></video>
<p class="am-margin-top-xs">{{$vs.name}}</p>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case upload-attachments}}
{{if !empty($module_data['value']) and is_array($module_data['value'])}}
<ul class="am-avg-sm-2 am-avg-md-4 am-nbfc">
{{foreach $module_data.value as $vs}}
{{if !empty($vs) and !empty($vs['url'])}}
<li class="am-padding-xs">
<a href="javascript:;" data-value="{{$vs.url}}" data-name="{{$vs.name}}" class="am-block am-radius common-annex-download-event">{{$vs.name}}</a>
</li>
{{/if}}
{{/foreach}}
</ul>
{{/if}}
{{/case}}
{{case rich-text}}
<div class="richtext">{{$module_data.value|raw}}</div>
{{/case}}
{{case subform}}
{{if !empty($module_data['value']) and is_array($module_data['value']) and count($module_data['value']) gt 0}}
<table class="am-table am-table-bordered am-table-radius am-text-left">
<thead>
<tr>
{{foreach $module_data['value'][0] as $subhv}}
<th>
<strong>{{$subhv.name}}</strong>
</th>
{{/foreach}}
</tr>
</thead>
<tbody>
{{foreach $module_data['value'] as $subvv}}
{{if !empty($subvv) and is_array($subvv)}}
<tr>
{{foreach $subvv as $subvvs}}
<td>
{{:ModuleInclude('../../../module/view/form_input/detail_value', $subvvs)}}
</td>
{{/foreach}}
</tr>
{{/if}}
{{/foreach}}
</tbody>
</table>
{{/if}}
{{/case}}
{{default /}}
{{if isset($module_data['value_text'])}}
{{$module_data.value_text}}
{{else /}}
{{$module_data.value|raw}}
{{/if}}
{{/switch}}
{{/if}}

View File

@ -10,7 +10,7 @@
</div>
<div class="forminput-data">
<!-- form start -->
<form class="forminput-data-form am-form form-validation am-form-full-screen {{if $form_input_data['config']['overall_config']['type_value'] neq 'free'}}forminput-h{{/if}}" action="{{:MyUrl('index/forminputdata/save')}}" method="POST" {{if !empty($params) and isset($params['is_debug']) and $params['is_debug'] eq 1}}request-type="ajax-view"{{else /}}request-type="ajax-url" request-value="{{:MyUrl('index/forminputdata/index')}}"{{/if}}>
<form class="forminput-data-form am-form form-validation am-form-full-screen" action="{{:MyUrl('index/forminputdata/save')}}" method="POST" {{if !empty($params) and isset($params['is_debug']) and $params['is_debug'] eq 1}}request-type="ajax-view"{{else /}}request-type="ajax-url" request-value="{{:MyUrl('index/forminputdata/index')}}"{{/if}}>
<div class="{{if $form_input_data.config.overall_config.is_show_submit == '1' or $form_input_data.config.overall_config.is_show_save_draft == '1'}}forminput-data-form-submit{{/if}}">
<div class="forminput-top-bg" style="background: {{$form_input_data.config.overall_config.style_settings.computer.heading_color}};">
{{if !empty($form_input_data.config.overall_config.style_settings.computer.heading_image) and !empty($form_input_data.config.overall_config.style_settings.computer.heading_image[0])}}
@ -54,7 +54,7 @@
<div class="am-popup-bd">
<form class="am-form am-form-popup-fixed form-validation">
<div class="upgrade-content">
<input type="text" name="option" required="required" autocomplete="off" data-validation-message="请输入选项名称" placeholder="请输入选项名称">
<input type="text" class="am-radius" required="required" autocomplete="off" data-validation-message="请输入选项名称" placeholder="请输入选项名称">
</div>
<div class="am-form-popup-submit">
<button type="button" class="am-btn am-btn-warning am-radius am-btn-xs am-margin-right-lg" data-am-modal-close>
@ -78,8 +78,8 @@
<div class="am-form-input-material">
<input type="text" minlength="4" maxlength="4" id="user-verify-win-img-value" data-validation-message="{{:MyLang('form_images_verify_message')}}" class="am-form-field am-radius input-padding-right-max" autocomplete="off" data-is-clearout="0" />
<div class="am-position-verify">
<img src="" class="am-cursor-pointer am-radius" id="user-verify-win-img" onClick="this.src='{{:MyUrl('index/user/userverifyentry', ['type'=>isset($module_data['type']) ? $module_data['type'] : ''])}}'+(({{$url_model}} == 0) ? '&t=' : '?t=')+Math.random();" />
<a href="javascript:;" class="form-verify-tips am-radius" onClick="document.getElementById('user-verify-win-img').src='{{:MyUrl('index/user/userverifyentry', ['type'=>isset($module_data['type']) ? $module_data['type'] : ''])}}{{if $url_model eq 0}}&t={{else /}}?t={{/if}}'+Math.random();">{{:MyLang('form_images_verify_button_text')}}</a>
<img src="" class="am-cursor-pointer am-radius" id="user-verify-win-img" onClick="this.src='{{:MyUrl('index/forminput/verifyentry', ['type'=>isset($module_data['type']) ? $module_data['type'] : ''])}}'+(({{$url_model}} == 0) ? '&t=' : '?t=')+Math.random();" />
<a href="javascript:;" class="form-verify-tips am-radius" onClick="document.getElementById('user-verify-win-img').src='{{:MyUrl('index/forminput/verifyentry', ['type'=>isset($module_data['type']) ? $module_data['type'] : ''])}}{{if $url_model eq 0}}&t={{else /}}?t={{/if}}'+Math.random();">{{:MyLang('form_images_verify_button_text')}}</a>
</div>
<span class="am-material-bar"></span>
<label class="am-material-label">{{:MyLang('form_verify_title')}}</label>

View File

@ -5,8 +5,8 @@
<link rel="shortcut icon" type="image/x-icon" href="{{$public_host}}favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{:MyLang('common_service.forminput.base_nav_title')}}</title>
<script type="module" crossorigin src="{{$public_host}}static/form_input/js/entry/index-757f3faa.js"></script>
<link rel="stylesheet" href="{{$public_host}}static/form_input/css/index-7fa81bbe.css">
<script type="module" crossorigin src="{{$public_host}}static/form_input/js/entry/index-6a5300c2.js"></script>
<link rel="stylesheet" href="{{$public_host}}static/form_input/css/index-3d483388.css">
</head>
<body>
<div id="app"></div>

View File

@ -149,11 +149,11 @@ class FormInputApiService
['key'=>'single-text', 'name' => '单行文本'],
['key'=>'multi-text', 'name' => '多行文本'],
['key'=>'number', 'name' => '数字'],
['key'=>'date', 'name' => '日期时间'],
['key'=>'radio-btns', 'name' => '单选按钮组'],
['key'=>'checkbox', 'name' => '复选框组'],
['key'=>'select', 'name' => '下拉框'],
['key'=>'select-multi', 'name' => '下拉复选框'],
['key'=>'date', 'name' => '日期时间'],
['key'=>'date-group', 'name' => '日期时间组'],
]
],
@ -161,16 +161,16 @@ class FormInputApiService
'name' => '高级',
'key' => 'hight-level',
'data' => [
['key' => 'upload-img', 'name' => '上传图片'],
['key' => 'position', 'name' => '定位'],
['key' => 'address', 'name' => '地址'],
['key' => 'subform', 'name' => '子表单'],
['key' => 'pwd', 'name' => '密码'],
['key' => 'phone', 'name' => '手机'],
['key' => 'score', 'name' => '评分'],
['key' => 'rich-text', 'name' => '富文本'],
['key' => 'upload-attachments', 'name' => '上传文件'],
['key' => 'subform', 'name' => '子表单'],
['key' => 'upload-img', 'name' => '上传图片'],
['key' => 'upload-video', 'name' => '上传视频'],
['key' => 'upload-attachments', 'name' => '上传文件'],
]
],
[

View File

@ -25,6 +25,12 @@ use app\service\FormInputService;
*/
class FormInputDataService
{
public static function FormInputDataDetail($did, $user_id)
{
$data = self::FormInputDataListHandle(Db::name('FormInputData')->where(['id'=>$did, 'user_id'=>$user_id])->select()->toArray());
return empty($data) || empty($data[0]) ? [] : $data[0];
}
/**
* 数据处理
* @author Devil
@ -107,6 +113,10 @@ class FormInputDataService
// 表单数据处理
$form_data = FormInputModule::FormInputDataWriteHandle($form_input['config'], $params);
if($form_data['code'] != 0)
{
return $form_data;
}
// 当前用户
$user_id = empty($params['user']) ? 0 : $params['user']['id'];
@ -118,7 +128,7 @@ class FormInputDataService
$data = [
'forminput_id' => $form_input['id'],
'user_id' => $user_id,
'form_data' => empty($form_data) ? '' : json_encode($form_data, JSON_UNESCAPED_UNICODE),
'form_data' => empty($form_data['data']) ? '' : json_encode($form_data['data'], JSON_UNESCAPED_UNICODE),
];
if(empty($info))
{

View File

@ -17,6 +17,7 @@ use app\service\AttachmentService;
use app\service\StoreService;
use app\service\AppMiniUserService;
use app\service\ConfigService;
use app\service\FormInputDataService;
/**
* form表单服务层
@ -55,7 +56,19 @@ class FormInputService
],
'is_config_handle' => 1,
]);
$data = (empty($ret['data']) || empty($ret['data'][0])) ? null : $ret['data'][0];
if(!empty($ret['data']) && !empty($ret['data'][0]))
{
$data = $ret['data'][0];
if(!empty($params['did']) && !empty($params['user']))
{
$detail = FormInputDataService::FormInputDataDetail($params['did'], $params['user']['id']);
if(!empty($detail) && !empty($detail['form_data']))
{
$data['forminput_data_id'] = $detail['id'];
$data['config'] = FormInputModule::FormInputDataValueMerge($data['config'], $detail['form_data']);
}
}
}
}
return $data;
}

View File

@ -1,5 +1,5 @@
+=========================================================+
ShopXO 6.7.0 Release 20250923 http://shopxo.net
ShopXO 6.7.0 Release 20250926 http://shopxo.net
+=========================================================+=
1.【新增】供应商插件
2.【新增】商品对比插件

View File

@ -922,7 +922,8 @@ form.am-form .am-form-group.am-form-icon {
width: calc(100% - 5rem);
font-size: 1.4rem;
display: -webkit-inline-box;
padding-left: 2rem;
padding: 0 0 0 2rem;
margin: 0;
}
/**

View File

@ -49,7 +49,7 @@
overflow: hidden;
}
.forminput-data-form-submit {
min-height: calc(100% - 7.6rem);
min-height: calc(100vh - 7.6rem);
}
/* 标题数据 */
.forminput-head-title {
@ -236,7 +236,7 @@
border: none;
margin: 0;
}
.item-img-empty {
.forminput .item-img-empty {
background: #f4fcff;
}
.forminput-data-item-content, .forminput-data-item-disabled {
@ -245,29 +245,29 @@
gap: 1rem;
padding: 0.5rem 1rem;
}
.forminput-data-item-disabled {
.forminput .forminput-data-item-disabled {
opacity: 0.4;
}
.forminput-textarea {
.forminput .forminput-textarea {
position: absolute;
bottom: 1rem;
right: 1rem;
z-index: 2;
background: #fff;
}
.forminput-input-text-center {
.forminput .forminput-input-text-center {
text-align: center;
}
.align-items-center {
.forminput .align-items-center {
align-items: center;
}
.justify-content-center {
.forminput .justify-content-center {
justify-content: center;
}
.forminput-cursor-p {
.forminput .forminput-cursor-p {
cursor: pointer;
}
.rect-or-round {
.forminput .rect-or-round {
width: 100%;
height: 100%;
padding: 0.3rem;
@ -320,7 +320,7 @@
.forminput-table-container .row-num {
font-size: 1.4rem;
}
.file-upload-view-list.file-upload-hidden {
.forminput .file-upload-view-list.file-upload-hidden {
display: none !important;
}
/* 表格头 */
@ -416,6 +416,8 @@
}
.forminput-table-body .table-row .operate-icon {
font-size: 1.4rem;
width: 1.4rem;
height: 1.4rem;
color: #2a94ff;
}
.forminput .shrink {
@ -435,7 +437,7 @@
.forminput-default-button.subform-button-hidden {
display: none !important;
}
.forminput-table-body .subform-num-checkbox, .subform-header-checkbox {
.forminput-table-body .subform-num-checkbox, .forminput .subform-header-checkbox {
display: none;
}
.forminput-table-checkbox .forminput-table-body .subform-num-checkbox, .forminput-table-checkbox .subform-header-checkbox {
@ -462,18 +464,18 @@
.forminput-subform-content-hidden div {
display: none !important;
}
.subform-cell.forminput-subform-hidden {
.forminput .subform-cell.forminput-subform-hidden {
display: none !important;
}
.subform-cell.forminput-subform-content-hidden div {
.forminput .subform-cell.forminput-subform-content-hidden div {
display: none !important;
}
/* 公共配置 */
.forminput-no-border {
.forminput .forminput-no-border {
border: none !important;
box-shadow: none !important;
}
.forminput-no-border.am-field-error:focus {
.forminput .forminput-no-border.am-field-error:focus {
box-shadow: none !important;
}
.forminput-w {
@ -503,7 +505,8 @@
.forminput-margin-right-10 {
margin-right: 1rem;
}
.am-checkbox-inline:not(:last-child), .am-radio-inline:not(:last-child) {
.forminput .am-checkbox-inline:not(:last-child),
.forminput .am-radio-inline:not(:last-child) {
margin-right: 2rem !important;
}
.forminput-gap-10 {
@ -684,6 +687,7 @@
visibility: hidden;
height: 0 !important;
width: 0 !important;
border: 0 !important;
}
.forminput .forminput-score-icon {
font-size: 1.6rem;
@ -752,4 +756,12 @@
word-wrap: break-word !important;
overflow-wrap:break-word !important;
word-wrap:break-word !important;
}
.forminput .add-option-max-width {
max-width: 10rem;
}
.forminput .add-option-icon {
font-size: 1.4rem;
line-height: 1.6rem;
}

View File

@ -2646,6 +2646,19 @@ function FromTableCheckedValues (form, tag) {
return values;
}
/**
* 判断对象数组等是否为空
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2025-09-24
* @desc description
* @param {[mixed]} value [需要验证的数据]
*/
function IsEmpty(value) {
return value === null || value === undefined || value === '' || (typeof value === 'number' && isNaN(value)) || (Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0);
}
/**
* 判断变量是否为数组
* @author Devil

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
import{d as a,c as e,u as s,a as r,o as t}from"../entry/index-757f3faa.js";const n=a({__name:"index",setup(a){const n=s(),p=r(),{params:o,query:u}=n,{path:d}=o;return p.replace({path:"/"+d,query:u}),(a,s)=>(t(),e("div"))}});export{n as default};

View File

@ -0,0 +1 @@
import{d as a,c as e,u as s,a as r,o as t}from"../entry/index-6a5300c2.js";const n=a({__name:"index",setup(a){const n=s(),p=r(),{params:o,query:u}=n,{path:d}=o;return p.replace({path:"/"+d,query:u}),(a,s)=>(t(),e("div"))}});export{n as default};

File diff suppressed because it is too large Load Diff