FastAdmin 工程师
活用表单(编辑/添加)【HTML】
初始化控制器
// 关联查询
protected $relationSearch = true;
// 快速查询,搜索指定的哪些字段
protected $searchFields = 'id,nickname,source.name,source.id,admin.id';
/**
* 当前控制器下的一个模型属性
*/
protected $model = null;
// 领取模型
protected $ReceiveModel = null;
// 客户来源模型
protected $SourceModel = null;
// 地区模型
protected $RegionModel = null;
// 开启数据限制
protected $dataLimit = true;
// 限制数据字段
protected $dataLimitField = 'adminid';
// 初始化
public function _initialize()
{
// 手动继承父级的初始化方法
parent::_initialize();
// 加载模型
$this->model = model('Business.Business');
$this->ReceiveModel = model('Business.Receive');
$this->SourceModel = model('Business.Source');
// 地区选择
$this->RegionModel = model('Region');
$SourceData = $this->SourceModel->column('id,name');
$SexList = [0 => '保密', 1 => '男', 2 => '女'];
$DealList = [0 => '未成交', 1 => '已成交'];
$this->view->assign([
'SourceData' => $SourceData,
'SexList' => $SexList,
'DealList' => $DealList
]);
}
昵称/姓名
<div class="form-group">
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Bnickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="nickname" name="row[nickname]" data-rule="required;nickname"
placeholder="{:__('Bnickname')}" value="{$row.nickname}" />
</div>
</div>
电话
<div class="form-group">
<label for="mobile" class="control-label col-xs-12 col-sm-2">{:__('mobile')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="mobile" name="row[mobile]" data-rule="required;mobile"
placeholder="{:__('mobile')}" value="{$row.mobile}" />
</div>
</div>
邮箱
<div class="form-group">
<label for="email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="email" name="row[email]" data-rule="required;email"
placeholder="{:__('Email')}" value="{$row.email}" />
</div>
</div>
性别
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('BsexText')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-gender" data-rule="required" class="form-control selectpicker" name="row[gender]">
{foreach name="$SexList" item="vo"}
<option value="{$key}" {in name="key" value="$row.gender" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
</div>
地区
处理地区回显
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">地区选择:</label>
<div class="col-xs-12 col-sm-10 region_city">
<input id="region" readonly type="text" data-toggle="city-picker" value="{$row['regionCode']}">
<!-- 用于提交数据把选中的地区传给后端处理 -->
<input type="hidden" name="row[code]" id="region-code">
</div>
</div>
// 处理地区数据回显
$row['regionCode'] = $row['district'] ?: ($row['city'] ?: $row['province']);
认证
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('AuthStatus')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-status" class="form-control selectpicker" name="row[auth]">
<option value="0" {$row.auth==0 ? 'selected' : '' }>未认证</option>
<option value="1" {$row.auth==1 ? 'selected' : '' }>已认证</option>
</select>
</div>
</div>
金额
<div class="form-group">
<label for="money" class="control-label col-xs-12 col-sm-2">{:__('Bmoney')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="number" min="0" class="form-control" id="c-money" name="row[money]" data-rule="required"
placeholder="{:__('money')}" value="{$row.money}" />
</div>
</div>
来源(适用于外键字段 int)
build_select 参数介绍,参数1 是 select 的 name,参数2 是后台传过来的数组 ($this->assign),参数3 设置默认选中,参数4 中的第一个class 是否多选,required 是否为必选
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('sourceId')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('row[sourceid]', $SourceData, $row.sourceid, ['class'=>'selectpicker', 'required'=>''])}
</div>
</div>
是否成交(适用于状态型字段 enum)
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('BdealText')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-deal" data-rule="required" class="form-control selectpicker" name="row[deal]">
{foreach name="$DealList" item="vo"}
<option value="{$key}" {in name="key" value="$row.deal" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
</div>
图片回显|上传
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Thumbs')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-thumbs" class="form-control" size="50" name="row[thumbs]" type="textarea" value="{$row.thumbs|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="faupload-thumbs" class="btn btn-danger faupload" data-input-id="c-thumbs" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="true" data-preview-id="p-thumbs"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-thumbs" class="btn btn-primary fachoose" data-input-id="c-thumbs" data-mimetype="image/*" data-multiple="true"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-thumbs"></span>
</div>
<ul class="row list-inline faupload-preview" id="p-thumbs"></ul>
</div>
</div>
模型代码
地区模型(数据库要有地区表)
application\common\model\Region.php
<?php
namespace app\common\model;
use think\Model;
class Region extends Model
{
// 地区表
protected $name = "region";
}
Controller 编辑方法
// 编辑
public function edit($ids = null)
{
$row = $this->model->find($ids);
if (!$row) {
$this->error(__('未找到当前用户'));
}
if ($this->request->isPost()) {
$params = $this->request->param("row/a");
$data = [
'id' => $ids,
'nickname' => $params['nickname'],
'mobile' => $params['mobile'],
'email' => $params['email'],
'gender' => $params['gender'],
'sourceid' => $params['sourceid'],
'deal' => $params['deal'],
'auth' => $params['auth'],
'money' => $params['money']
];
if($params['email'] != $row['email'])
{
$data['auth'] = 0;
}
// 修改密码
if (!empty($params['password'])) {
$salt = randstr();
$data['salt'] = $salt;
$data['password'] = md5($params['password'] . $salt);
}
// 修改省市区
if (!empty($params['code'])) {
$parentpath = $this->RegionModel->where('code',$params['code'])->value('parentpath');
if(!$parentpath)
{
$this->error('所选地区不存在,请重新输入');
}
$path = explode(',', $parentpath);
$province = $path[0] ?? null;
$city = $path[1] ?? null;
$district = $path[2] ?? null;
$data['province'] = $province;
$data['city'] = $city;
$data['district'] = $district;
}
$result = $this->model->validate("common/Business/Business.profile")->isUpdate(true)->save($data);
if ($result === false) {
$this->error($this->model->getError());
}
$this->success();
}
// 处理地区数据回显
$row['regionCode'] = $row['district'] ?: ($row['city'] ?: $row['province']);
$this->assign([
"row" => $row
]);
return $this->view->fetch();
}
公共方法
application\common.php
if (!function_exists('randstr')) {
/**
* 获得随机字符串
* @param $len 需要的长度
* @param $special 是否需要特殊符号
* @return string 返回随机字符串
*/
function randstr($len = 8, $special = false)
{
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
if ($special) {
$chars = array_merge($chars, array(
"!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
"%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
"}", "<", ">", "~", "+", "=", ",", "."
));
}
$charsLen = count($chars) - 1;
shuffle($chars); //打乱数组顺序
$str = '';
for ($i = 0; $i < $len; $i++) {
$str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
}
return $str;
}
}
if (!function_exists('build_randstr')) {
/**
* 获得随机字符串
* @param $len 需要的长度
* @param $special 是否需要特殊符号
* @return string 返回随机字符串
*/
function build_randstr($len = 8, $special = false)
{
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
if ($special) {
// array_merge — 合并一个或多个数组
$chars = array_merge($chars, array(
"!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
"%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
"}", "<", ">", "~", "+", "=", ",", "."
));
}
// count: 数组中的长度
$charsLen = count($chars) - 1;
//shuffle — 打乱数组
shuffle($chars);
$str = null;
for ($i = 0; $i < $len; $i++) {
// 随机取出一位 mt_rand:返回随机整数
$str .= $chars[mt_rand(0, $charsLen)];
}
return $str;
}
}
if (!function_exists('build_code')) {
/**
* 生成唯一订单号
* @param String $prefix 指定的订单前缀
* @return String 返回字符串
*/
function build_code($prefix = "")
{
@date_default_timezone_set("PRC");
$order_id_main = date('YmdHis') . rand(10000, 99999);
//订单号码主体长度
$order_id_len = strlen($order_id_main);
$order_id_sum = 0;
for ($i = 0; $i < $order_id_len; $i++) {
$order_id_sum += (int) (substr($order_id_main, $i, 1));
}
//唯一订单号码(YYYYMMDDHHIISSNNNNNNNNCC)
$osn = $prefix . $order_id_main . str_pad((100 - $order_id_sum % 100) % 100, 2, '0', STR_PAD_LEFT); //生成唯一订单号
return $osn;
}
}
if (!function_exists('httpRequest')) {
function httpRequest($url, $data = null)
{
if (function_exists('curl_init')) {
$curl = curl_init();
// 设置请求地址
curl_setopt($curl, CURLOPT_URL, $url);
// 设置http某些配置
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
// 判断传进来的参数是否不为空
if (!empty($data)) {
// 设置该请求为POST
curl_setopt($curl, CURLOPT_POST, 1);
// 把参数带入请求
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
} else {
return false;
}
}
}
完整 HTML 代码(参考)
<style>
.region_city .city-picker-span {
width: 80% !important;
position: relative;
}
</style>
<form id="add-form" class="form-horizontal form-ajax" role="form" data-toggle="validator" method="POST">
<div class="form-group">
<label for="nickname" class="control-label col-xs-12 col-sm-2">{:__('Bnickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="nickname" name="row[nickname]" data-rule="required;nickname"
placeholder="{:__('Bnickname')}" value="{$row.nickname}" />
</div>
</div>
<div class="form-group">
<label for="email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="email" name="row[email]" data-rule="required;email"
placeholder="{:__('Email')}" value="{$row.email}" />
</div>
</div>
<div class="form-group">
<label for="mobile" class="control-label col-xs-12 col-sm-2">{:__('mobile')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="text" class="form-control" id="mobile" name="row[mobile]" data-rule="required;mobile"
placeholder="{:__('mobile')}" value="{$row.mobile}" />
</div>
</div>
<div class="form-group">
<label for="mobile" class="control-label col-xs-12 col-sm-2">重置密码:</label>
<div class="col-xs-12 col-sm-8">
<input type="password" class="form-control" id="password" name="row[password]" placeholder="请输入密码" />
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('BsexText')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-gender" data-rule="required" class="form-control selectpicker" name="row[gender]">
{foreach name="$SexList" item="vo"}
<option value="{$key}" {in name="key" value="$row.gender" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('AuthStatus')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-status" class="form-control selectpicker" name="row[auth]">
<option value="0" {$row.auth==0 ? 'selected' : '' }>未认证</option>
<option value="1" {$row.auth==1 ? 'selected' : '' }>已认证</option>
</select>
</div>
</div>
<div class="form-group">
<label for="money" class="control-label col-xs-12 col-sm-2">{:__('Bmoney')}:</label>
<div class="col-xs-12 col-sm-8">
<input type="number" min="0" class="form-control" id="c-money" name="row[money]" data-rule="required"
placeholder="{:__('money')}" value="{$row.money}" />
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('SName')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('row[sourceid]', $SourceData, $row.sourceid, ['class'=>'selectpicker', 'required'=>''])}
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('BdealText')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-deal" data-rule="required" class="form-control selectpicker" name="row[deal]">
{foreach name="$DealList" item="vo"}
<option value="{$key}" {in name="key" value="$row.deal" }selected{/in}>{$vo}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">地区选择:</label>
<div class="col-xs-12 col-sm-10 region_city">
<input id="region" readonly type="text" data-toggle="city-picker" value="{$row['regionCode']}">
<!-- 用于提交数据把选中的地区传给后端处理 -->
<input type="hidden" name="row[code]" id="region-code">
</div>
</div>
<div class="form-group hidden layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>
初始化表格(index/del)【JS 基础解析】
以图片方式显示
{field: 'thumb', title: __('Thumb'), operate: 'LIKE',events:Table.api.events.image,formatter: Table.api.formatter.image}
JS 代码
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
// 经常改变的地方url 控制器 controller 地址; extend
extend: {
index_url: 'test/index',
add_url: 'test/add',
edit_url: 'test/edit',
del_url: 'test/del',
multi_url: 'test/multi',
// 绑定对应的 table,名字要一致
table: 'table',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'weigh',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'admin_id', title: __('Admin_id')},
{field: 'category.name', title: __('分类名称'), formatter:Table.api.formatter.search},
{field: 'category_id', title: __('Category_id'), visible: false},
{field: 'flag', title: __('Flag'), searchList: {"hot": __('Flag hot'), "index": __('Flag index'), "recommend": __('Flag recommend')}, operate: 'FIND_IN_SET', formatter: Table.api.formatter.label},
{field: 'genderdata', title: __('Genderdata'), searchList: {"male": __('Genderdata male'), "female": __('Genderdata female')}, formatter: Table.api.formatter.normal},
{field: 'title', title: __('Title')},
{field: 'image', title: __('Image'), formatter: Table.api.formatter.image},
{field: 'images', title: __('Images'), formatter: Table.api.formatter.images},
{field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime, visible: false},
{field: 'weigh', title: __('Weigh'), operate: false, visible: false},
{field: 'switch', title: __('Switch'), searchList: {"1": __('Yes'), "0": __('No')}, formatter: Table.api.formatter.toggle},
{field: 'status', title: __('Status'), searchList: {"normal": __('Normal'), "hidden": __('Hidden')}, formatter: Table.api.formatter.status},
{
field: 'buttons',
width: "120px",
title: __('按钮组'),
table: table,
events: Table.api.events.operate,
buttons: [
{
name: 'detail',
text: __('弹出窗口打开'),
title: __('弹出窗口打开'),
classname: 'btn btn-xs btn-primary btn-dialog',
icon: 'fa fa-list',
url: 'example/bootstraptable/detail',
callback: function (data) {
Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
},
visible: function (row) {
//返回true时按钮显示,返回false隐藏
return true;
}
},
{
name: 'ajax',
text: __('发送Ajax'),
title: __('发送Ajax'),
classname: 'btn btn-xs btn-success btn-magic btn-ajax',
icon: 'fa fa-magic',
url: 'example/bootstraptable/detail',
confirm: '确认发送',
success: function (data, ret) {
Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data));
//如果需要阻止成功提示,则必须使用return false;
//return false;
},
error: function (data, ret) {
console.log(data, ret);
Layer.alert(ret.msg);
return false;
}
},
{
name: 'addtabs',
text: __('新选项卡中打开'),
title: __('新选项卡中打开'),
classname: 'btn btn-xs btn-warning btn-addtabs',
icon: 'fa fa-folder-o',
url: 'example/bootstraptable/detail'
}
],
formatter: Table.api.formatter.buttons
},
{
field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate,
buttons: [
{
name: 'detail',
title: __('详情'),
classname: 'btn btn-xs btn-primary btn-dialog',
icon: 'fa fa-list',
url: 'test/detail',
callback: function (data) {
Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"});
}
}],
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
// 发货
deliver:function()
{
Controller.api.bindevent();
},
// 退货审核
refund:function(){
$('#c-refund').change(function(){
let val = $(this).val();
if(val == 1)
{
$('#examinereason').hide();
$('#c-examinereason').val('');
}else{
$('#examinereason').show();
}
});
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});
自定义表格