在使用element ui做项目的时候,需要用到tree组件进行回显来进行权限控制:

在回显过程中使用回显函数setCheckedNodes,setCheckedKeys,setChecked等函数会报报undefined,

这时只需要给该函数包裹一层nextTick方法就行了,


permissArr.forEach((v) => {
  this.$nextTick(() => {
     this.$refs.tree.setChecked(v, true, false)
  })
})

在回显过程中我们有可能使用半选,这时用setchecked就行了

Vue-Element-Admin 如何取消模拟 Mock 的数据,改为真实 API 的后台接口调用?网上很多教程是低版本,已无法使用。

经多方尝试,2步即可,以下方式可用,版本为 4.2.1-i18n,修改方式适用与本地开发环境的跨域,线上环境跨域可使用 Nginx 反向代理进行跨域。

第一步,修改根目录下的 .env.development:
此文件为开发环境配置文件,这里修改为空是重点,否则无法跨域。

VUE_APP_BASE_API = '/dev-api'</p><h1>修改为空</h1><p>VUE_APP_BASE_API = ''

第二步,修改根目录下的 vue.config.js:
新版本中没有 proxy 这个参数,而是直接 before mock,因此需要新增 proxy 代理参数(无需安装 http-proxy-middleware,框架已内置),同时删除掉 before mock 参数。


devServer: {
  port: port,
  open: true,
  overlay: { 
    warnings: false, 
    errors: true 
  }, 
  before: require('./mock/mock-server.js') }

修改为以下


devServer: { 
  port: port, 
  open: true, 
  overlay: { 
    warnings: false, 
    errors: true
  }, 
  proxy: { 
    [process.env.VUE_APP_BASE_API]: { 
      target: `http://后台接口地址`, 
      changeOrigin: true, 
      pathRewrite: { 
        ['^' + process.env.VUE_APP_BASE_API]: '' 
      }
    }
  }

1.html页面

[code lang="html"]
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('选择文章')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-artlist" class="form-control" size="50" name="row[related_artlist]" type="text" value=""/>
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="related_artlist" class="btn btn-primary" data-input-id="c-artlist_id"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
</div>
</div>
</div>
[/code]

2.需要复制一个类似选择图片页面的html select.html
[code lang="html"]
<div class="panel panel-default panel-intro">
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">

<a class="btn btn-danger btn-choose-multi"><i class="fa fa-check"></i> {:__('Choose')}</a>

</div>
<table id="table" class="table table-bordered table-hover" width="100%">

</table>
</div>
</div>

</div>
</div>
</div>
[/code]

3.控制器方法

[code lang="js"]
public function select()
{
if ($this->request->isAjax()) {

return $this->index();
}
return $this->view->fetch();
}
[/code]

4.js脚本
[code lang="js"]
index: function () {
//此处略
},
select: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'cms/archives/select',
}
});
var urlArr = [];

var table = $("#table");

table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function (e, row) {
if (e.type == 'check' || e.type == 'uncheck') {
row = [row];
} else {
urlArr = [];
}
$.each(row, function (i, j) {
if (e.type.indexOf("uncheck") > -1) {
var index = urlArr.indexOf(j.url);
if (index > -1) {
urlArr.splice(index, 1);
}
} else {
urlArr.indexOf(j.url) == -1 && urlArr.push(j.url);
}
});
});

// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
sortName: 'id',
showToggle: false,
showExport: false,
searchFormVisible: true,
columns: [
[
{field: 'state', checkbox: true},
{field: 'id', title: __('Id'),operate:false},
{field: 'title', title: __('Title'), formatter: Table.api.formatter.search},

{field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: false, addclass: 'datetimerange', sortable: true},
{
field: 'operate', title: __('Operate'), events: {
'click .btn-chooseone': function (e, value, row, index) {
url=row.id+'-'+row.title;

Fast.api.close({url:url,multiple: false});
},
}, formatter: function () {
return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Choose') + '</a>';
}
}
]
]
});

// 选中多个
$(document).on("click", ".btn-choose-multi", function () {
var urlArr = [];
$.each(table.bootstrapTable("getAllSelections"), function (i, j) {
urlArr.push(j.id+'-'+j.title);
});
var multiple = Backend.api.query('multiple');
Fast.api.close({url: urlArr.join(","), multiple: true});
});

// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
$('#related_artlist').click(function () {
var values = $.trim($('#c-artlist').val());
Fast.api.open('cms/archives/select',__('选择文章'),{
callback:function(value){
//在回调函数里可以调用你的业务代码实现前端的各种逻辑和效果
console.log(value);
/*if(value.multiple==true){
$('#c-artlist').val(value.url);
}else{
$('#c-artlist').val(value.id+'-'+value.goodsname);
}*/
$('#c-artlist').val(value.url);

var urlArr = [];
if(values!==''){
urlArr.push(values);
}

urlArr.push(value.url);

var result = urlArr.join(",");
console.log(urlArr);
$('#c-artlist').val(result).trigger("change").trigger("validate");;

},
});
});

Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
[/code]

准备事项:

一、2个表

1、PortalTagModel:插入秒杀成功用户的信息。 字段:id,status

2、SetModel:记录开放名额的信息。字段:id,ic。

二、设置产品。

SetModel表,添加数据。id=1,ic=3(3个名额)。

三、代码(采用事物处理)
$portalTagModel = new PortalTagModel();
        $setsum= new SetModel();
        Db::startTrans();
        try{
            $set=SetModel::get(1);
            if($set->ic<=0){
                die();
            }else{
                $data=['status'=>1];
                $w=[];$w['id']=1;$w['ic']=['gt',0];
                $portalTagModel->insert($data);
                $state=$setsum->where($w)->setDec('ic',1);
                if($state==0){Db::rollback();}
                Db::commit();
                print_r("完成");
                die();
            }
        } catch (\Exception $e) {
            Db::rollback();
        }
        die();

四、使用并发工具测试。

设置50人同时并发访问页面,进数据库查看入库情况,仅3条成功入库。

五、完毕。

ThinkPHP5有关联模型的操作,但有部分初学者对数据表中常见的几种表与表的关系还存在着问题,所以使用不好关联查询。

这里将hasOne、hasMany、belongsTo进行一个详细举例说明。

首先,这3个的大致中文意思:

hasOne:有一个,加上主谓语应该是 ,A 有一个 B
hasMany:有很多,A 有很多 B
belongsTo:属于, A 属于 B

这里我们准备3张表来理解他们的关系:
user_group 用户分组表:id、title
user 用户表:id、user_group_id、username、password
profile 用户信息表:id、user_id、nickname、sex

1、user表需要关联user_group表,表示每一个 用户 需要知道该用户是 哪个用户分组的;
2、profile表 需要关联 用户表,表示该用户信息数据 是哪个用户的信息;

我们知道一个用户组下面可以有很多用户,所以:user_group hasMany user;
一个用户 属于 一个用户组,所以:user belongsTo user_group;

同样是user_group和user表,但我们出发点不同,关系也就不一样了。

每个用户都应该有唯一一条用户信息数据,所以:user hasOne profile;
一条用户信息 属于 一个用户,所以:profile belongsTo user

综上:

在User模型中,我们可以定义关联:
function user_group(){
    return $this->belongsTo('UserGroup');
}
 
function profile(){
   return $this->hasOne('Profile');
}

我们在查询中:

$user = model('User')->find();
$user = $user->user_group; //这样user中就可以包含当前数据对应的user_group数据了
$user = $user->profile; //这样user中就可以包含当前数据对应的profile数据了

在UserGroup模型中,我们可以定义关联:
function user(){
   return $this->hasMany('User');
}

在Profile模型中,我们可以定义关联:

function user(){
    return $this->belongsTo('User');
}

注:定义关联function的方法名可以随意定义,一般为表名或模型名;我们定义的时候是function,但获取时理解为获取属性,所以不加();

很多人理解是我定义了一个profile的方法,所以应该$user->profile(),这里要特别注意下。

这样我们在查询时,就方便了,不需要使用大量的join。