安装

运行环境要求PHP=>8.0

域名解析到public目录,用“域名+public”来访问,会导致页面错乱

设置thinkphp伪静态

1
2
3
4
5
6
7
8
location ~* (runtime|application)/{
return 403;
}
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}

php需要添加 fileinfo 扩展

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
www  WEB部署目录(或者子目录)
├─application 应用目录
│ ├─common 公共模块目录(可以更改)
│ ├─module_name 模块目录
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ │
│ ├─command.php 命令行定义文件
│ ├─common.php 公共函数文件
│ └─tags.php 应用行为扩展定义文件

├─config 应用配置目录
│ ├─module_name 模块配置目录
│ │ ├─database.php 数据库配置
│ │ ├─cache 缓存配置
│ │ └─ ...
│ │
│ ├─app.php 应用配置
│ ├─cache.php 缓存配置
│ ├─cookie.php Cookie配置
│ ├─database.php 数据库配置
│ ├─log.php 日志配置
│ ├─session.php Session配置
│ ├─template.php 模板引擎配置
│ └─trace.php Trace配置

├─route 路由定义目录
│ ├─route.php 路由定义
│ └─... 更多

├─public WEB目录(对外访问目录)
│ ├─index.php 入口文件
│ ├─static 静态资源文件目录
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写

├─thinkphp 框架系统目录
│ ├─lang 语言文件目录
│ ├─library 框架类库目录
│ │ ├─think Think类库包目录
│ │ └─traits 系统Trait目录
│ │
│ ├─tpl 系统模板目录
│ ├─base.php 基础定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 框架惯例配置文件
│ ├─helper.php 助手函数文件
│ ├─phpunit.xml phpunit配置文件
│ └─start.php 框架入口文件

├─extend 扩展类库目录
├─runtime 应用的运行时目录(可写,可定制)
├─vendor 第三方类库目录(Composer依赖库)
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件

User会员模块

user控制器

Base.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
// +----------------------------------------------------------------------
// | CLTPHP.Pro [基础控制器]
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2029 https://www.cltphp.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://www.cltphp.com/detail-140.html )
// +----------------------------------------------------------------------
// | Author: chichu <1109305987@qq.com>
// +----------------------------------------------------------------------
namespace app\user\controller;

use think\facade\Db;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use think\facade\View;
use think\facade\Request;
use app\common\model\System;
/**
* 控制器基础类
*/
abstract class Base{
protected $system; //系统信息
protected $userInfo; //系统信息
/**
* Request实例
* @var \think\Request
*/
protected $request;

/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;

/**
* 控制器中间件
* @var array
*/
protected $middleware = [];

/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{

$this->app = $app;
$this->request = $this->app->request;

// 控制器初始化
$this->initialize();
}

// 初始化
protected function initialize()
{
//查找所有系统设置表数据
$system = System::getListField()->toArray();
//格式化设置字段
$system = sysgem_setup($system);
$systemArr = [];
foreach ($system as $k => $v) {
$systemArr[$v['field']] = $v['value'];
}
$system = $systemArr;
View::assign(['config'=>$system]);

$this->system = $system;
if(session('user')){
//用户信息
$this->userInfo =Db::name('users')->alias('u')
->join('user_level ul','u.level_id = ul.id','left')
->field('u.*,ul.level_name as level')
->where('u.id',session('user.id'))
->find();
}else{
redirect(url('user/login/index'));
}
View::assign(['userInfo'=>$this->userInfo]);
$action = request()->action();
$controller = request()->controller();

View::assign(['action'=>$action]);
View::assign(['controller'=>$controller]);

$linkList = Db::name('link')->where('open',1)->order('sort asc')->select();
View::assign(['linkList'=>$linkList]);
}

/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
list($validate, $scene) = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}

$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}

$result = $v->failException(false)->check($data);
if (true !== $result) {
return $v->getError();
} else {
return $result;
}
}


}

Index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
namespace app\user\controller;
use think\facade\Db;
use think\facade\View;

class Index extends Base{
public function index(){
//获取当前用户
$list = Db::name('message')->where('user_id',session('user.id'))->select();
$view= [
'list'=>$list
];
if($this->userInfo['password']==''){
return redirect(url('user/login/info'));
}
return view('',$view);
}
public function download($id=''){
$map['id'] = $id;
$files = Db::name('download')->where($map)->find();
return download(root_path().'public'.$files['files'], $files['title']);
}
public function loginout(){
session('user',null);
redirect((string)url('user/login/index'));
}
}

Login.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<?php
namespace app\user\controller;
use app\common\model\System;
use app\common\model\Users as M;

use think\db\exception\DbException;
use think\exception\HttpResponseException;
use think\facade\Db;
use think\facade\View;
use think\captcha\facade\Captcha;
use think\facade\Request;
use mailer\tp6\Mailer;
use think\facade\Config;
use think\Response;

class Login
{
private $system;
public function __construct(){
$system = System::getListField()->toArray();
//格式化设置字段
$system = sysgem_setup($system);
$systemArr = [];
foreach ($system as $k => $v) {
$systemArr[$v['field']] = $v['value'];
}
$this->system = $systemArr;
View::assign(['config'=>$this->system]);

//第三方登录
$social = Db::name('plugin')->where(['type'=>'login','status'=>1])->select()->toArray();
View::assign(['social'=>$social]);

$linkList = Db::name('link')->where('open',1)->order('sort asc')->select();
View::assign(['linkList'=>$linkList]);
}

public function index(){
if(Request::isPost()){
$data = input('post.');
if($this->system['message_code']==1){
if (!captcha_check($data['vercode'])) {
return ['code' => 0, 'msg' => '验证码错误'];
}
}
$user=Db::name('users')->where('username',$data['username'])->find();
if($user){
if($user['password'] == md5($user['token'].$data['password'])){
session('user',$user);
return ['code' => 1, 'msg' => '登录成功','url' => (string)url('user/index/index')]; //信息正确
}else{
return ['code' => 0, 'msg' =>'登录失败']; //密码错误
}
}else{
return ['code' => 0, 'msg' =>'用户名不存在']; //账号不存在
}
}

$view =[
'title'=>'用户登录'
];
return view('',$view);
}
//注册页面
public function reg(){
if(Request::isPost()){
$data = input('post.');
if (!captcha_check($data['vercode'])) {
return ['code' => 1, 'msg' => '验证码错误'];
}
if(trim($data['username'])==''){
return ['code' => 0, 'msg' =>'请重新设置用户名'];
}
if(strlen($data['password']) < 6){
return ['code' => 0, 'msg' =>'密码不能低于6位字符'];
}
$data['token'] = rand_string();
if(Db::name('users')->where('email',$data['email'])->find()){
return ['code' => 0, 'msg' =>'该email已被使用'];
}
if(Db::name('users')->where('username',$data['username'])->find()){
return ['code' => 0, 'msg' =>'该用户名已被使用'];
}

$data['create_time'] = time();
if($data['repass'] == $data['password']){
$data['password'] = md5($data['token'].$data['password']);
unset($data['repass']);
}else{
return ['status'=>0,'code' => 0, 'msg' =>'两次输入密码不一致'];
}
$data['avatar'] = '/static/user/images/avatar/default.png';
unset($data['vercode']);
$id = Db::name('users')->insertGetId($data);
if($id){
$session = rand_string(20);
Db::name('users')->where('id',$id)->update(['session'=>$session]);
$user = Db::name('users')->where('id',$id)->find();
session('user',$user);
return ['code' => 1, 'msg' =>'注册成功!','url'=>(string)url('user/index/index')];
}else{
return ['code' => 0, 'msg' =>'注册失败!'];
}
}
$view =[
'title'=>'用户注册'
];
return view('',$view);
}
/**
* 忘记密码
*/
public function forget(){
if(request()->isPost()) {
$sender = input('email');
$code =input('code');
$inValid = true; //验证码失效
if(!$code){
return ['status'=>0,'code' => 0, 'msg' =>'请输入邮件验证码!'];
}
$data = session('validate_code');
$timeOut = $data['time'];
if($data['code'] != $code || $data['sender']!=$sender){
$inValid = false;
}
$password = input('password');
$password2 = input('password2');
if(strlen($password) < 6){
return ['status'=>0,'code' => 0, 'msg' =>'密码不能低于6位字符!'];
}
if($password != $password2){
return ['status'=>0,'code' => 0, 'msg' =>'两次输入密码不一致!'];
}
if(empty($data)){
return ['status'=>0,'code' => 0, 'msg' =>'请先获取验证码!'];
}elseif($timeOut < time()){
return ['status'=>0,'code' => 0, 'msg' =>'验证码已超时失效!'];
}elseif(!$inValid) {
return ['status'=>0,'code' => 0, 'msg' =>'验证失败,验证码有误!'];
}else{
$data['is_check'] = 1; //标示验证通过
session('user.token',$data);
$token = Db::name('users')->where('email',$sender)->value('token');
Db::name('users')->where('email',$sender)->update(['password'=>md5($token.$password)]);
return ['status'=>0,'code' => 1, 'msg' =>'密码找回成功!','url'=>(string)url('user/login/index')];
}
}else {
$view =[
'title'=>'找回密码'
];
return view('',$view);
}
}
public function info(){
if(!session('user.id')){
return redirect(url('user/login/index'));
}
if(request()->isPost()) {
$data = input('post.');
if(trim($data['username'])==''){
return json(['code' => 0, 'msg' =>'请重新设置用户名']);
}

if(M::where([['username','=',$data['username']],['id','<>',session('user.id')]])->find()){
return json(['code' => 0, 'msg' =>'该用户名已被使用']);
}

if(strlen($data['password']) < 6){
return json(['code' => 0, 'msg' =>'密码不能低于6位字符']);
}

if($data['repass'] == $data['password']){
$token = session('user.token');
$data['password'] = md5($token.$data['password']);
unset($data['repass']);
}else{
return json(['status'=>0,'code' => 0, 'msg' =>'两次输入密码不一致']);
}
$data['id'] = session('user.id');
$result = M::editSave($data);
if($result['code']==0){
return json(['status'=>0,'code' => 1, 'msg' =>'设置成功!','url'=>(string)url('user/index/index')]);
}else{
return json(['status'=>0,'code' => 0, 'msg' =>'设置失败!']);
}
}else{
$user_id = session('user.id');
$info = M::edit($user_id);
$view = [
'info' => $info,
];
return view('info', $view);
}
}
public function sendEmail(){
if(request()->isPost()) {
$sender = input('email');
$sms_time_out = $this->system['time_out'];
//获取上一次的发送时间
$send = session('validate_code');
if (!empty($send) && $send['time'] > time() && $send['sender'] == $sender) {
//在有效期范围内 相同号码不再发送
return json(['code' => -1, 'msg' => '规定时间内,不要重复发送验证码']);
}
$code = mt_rand(1000, 9999);
//检查是否邮箱格式
if (!is_email($sender)) {
return json(['code' => -1, 'msg' => '邮箱码格式有误']);
}
Config::set(
[
'driver'=>'smtp',
'host' => $this->system['smtp_server'],
'port' => $this->system['smtp_port'],
'addr'=> $this->system['smtp_email'],
'pass'=> $this->system['smtp_pwd'],
'name'=> $this->system['smtp_user'],
],
'mail'
);
$mailer = Mailer::instance();
$sendStatus = $mailer->from($this->system['smtp_email'], $this->system['smtp_user'])
->to($sender)
->subject('验证码')
->text( '您好,你的验证码是:' . $code)
->send();
if ($sendStatus) {
$info['code'] = $code;
$info['sender'] = $sender;
$info['is_check'] = 0;
$info['time'] = time() + $sms_time_out; //有效验证时间
session('validate_code', $info);
return json(['code' => 1, 'msg' => '验证码已发送,请注意查收']);
}else{
return json(['code' => -1, 'msg' => '验证码发送失败,请联系管理员']);
}
}else{
return json(['code' => -1, 'msg' => '非法请求']);
}

}
//验证码
public function captcha(){
return Captcha::create();
}
public function unbind(){
try {
Db::name('user_oauth')->where("uid", session('user.id'))->delete();
success('解绑成功!');
} catch (DbException $e) {
error($e->getMessage());
}

}

}

Message.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
namespace app\user\controller;
use think\facade\Db;
use think\facade\View;
class Message extends Base{
public function initialize(){
parent::initialize();
}
public function index(){
$userId = session('user.id');
//未结留言
$nocount = Db::name('message')->where(['user_id'=>$userId,'status'=>0])->count();
$list = Db::name('message')->where(['user_id'=>$userId,'status'=>0])->order('update_time desc')->select();

$yescount = Db::name('message')->where(['user_id'=>$userId,'status'=>1])->count();
$yeslist = Db::name('message')->where(['user_id'=>$userId,'status'=>1])->order('update_time desc')->select();

View::assign([
'nocount'=>$nocount,
'list'=>$list,
'yescount'=>$yescount,
'yeslist'=>$yeslist,
'title'=>'我的消息',
]);
return view();
}
public function info($id=''){
$info = Db::name('message')->where('id',$id)->find();
$list = Db::name('message_reply')->where('mid',$id)->select();
View::assign([
'info'=>$info,
'list'=>$list,
'title'=>'消息回复',
]);
return view();
}
public function reply(){
$data = input('post.');
$data['create_time'] = time();
$data['is_self'] = 0;
Db::name('message_reply')->insert($data);
Db::name('message')->where('id',$data['mid'])->update(['reply'=>0]);
return ['code' => 1, 'msg' => '留言成功!','url'=>(string)url('user/message/index')];
}
public function status($id){
Db::name('message')->where('id',$id)->update(['status'=>1]);
return json(['code' => 1, 'msg' => '操作成功!','url'=>(string)url('user/message/index')]);

}
}

Oauth.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
namespace app\user\controller;
use think\facade\Db;
use wycto\login;
class Oauth
{
/**
* 登录
*/
function login()
{
$type = input('param.type');
// 登录
$config_value = Db::name('plugin')->where(['type'=>'login','code'=>$type])->value('config_value');
$config = json_decode($config_value,true);
$config['framework'] = 'tp';
$login = login\Login::getApp($type,$config);
$login->login();
}

/**
* QQ登录回调
*/
function callback()
{
$type = input('param.type');
$config_value = Db::name('plugin')->where(['type'=>'login','code'=>$type])->value('config_value');
$config = json_decode($config_value,true);
$config['framework'] = 'tp';
$login = login\Login::getApp($type,$config);
// 获取用户信息
$userinfo = $login->getUserInfo();
if (! isset($userinfo['openid']) || empty($userinfo['openid'])) {
error('获取信息失败',url("user/index/index"));
}
// 查询是否存在
$auth = Db::name('user_oauth')->where(array('openid' => $userinfo['openid'],'type'=>$type))->find();
if ($auth) {
// 账号存在
if(session('user.id')){
success('绑定成功',url("user/set/index"));
}else{
$data = Db::name('users')->withoutField('password')->where('id',$auth['uid'])->find();
session('user',$data);
success('登录成功',url("user/index/index"));
}
} else {
// 账号不存在
if(session('user.id')){
//已登录,去绑定
$oauth_data['type'] = $type;
$oauth_data['openid'] = $userinfo['openid'];
$oauth_data['uid'] = session('user.id');
Db::name('user_oauth')->insert($oauth_data);
success('绑定成功',url("user/set/index"));
}else{
$data['username'] = $userinfo['nickname'];
$data['token'] = rand_string(6);
$data['avatar'] = $userinfo['avatar'];
$data['gender'] = $userinfo['gender'];
$data['signature'] = isset($userinfo['description'])?$userinfo['description']:'';
$data['create_time'] = time();
$data['update_time'] = time();
$oauth_data['type'] = $type;
$oauth_data['openid'] = $userinfo['openid'];
$data['id'] = $oauth_data['uid'] = Db::name('users')->insertGetId($data);
Db::name('user_oauth')->insert($oauth_data);
session('user',$data);
success('登录成功',url("user/index/index"));
}
}
}
}

Set.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
namespace app\user\controller;
use think\facade\Db;
use think\facade\Request;
use think\facade\View;
use think\facade\Filesystem;
class Set extends Base{
public function initialize(){
parent::initialize();
}
public function index(){
//设置
$province = Db::name('Region')->where ('pid',1)->select ();
$city = Db::name('Region')->where ( 'pid',$this->userInfo['province'])->select ();
$area = Db::name('Region')->where ('pid',$this->userInfo['city'])->select ();
//第三方登录
$social = Db::name('plugin')->where(['type'=>'login','status'=>1])->select()->toArray();
$type = Db::name('user_oauth')->where('uid',session('user.id'))->column('type');
foreach ($social as $k=>$v){
if($type && in_array($v['code'],$type)){
$social[$k]['status'] = 1;
}else{
$social[$k]['status'] = 0;
}
}
View::assign([
'province'=>$province,
'city'=>$city,
'area'=>$area,
'social'=>$social,
'title'=>'用户设置',
]);
return view();
}
public function getRegion(){
$list=Db::name("region")->where('pid',input("pid"))->select();
return $list;
}
public function userinfo(){
$data = Request::only(['username','email','province','mobile','city','area','sex','signature']);
if(trim($data['username'])==''){
return ['code' => 0, 'status' =>0, 'msg' => '请重新设置用户名!'];
}

if(Db::name('users')->where([['id','<>',session('user.id')],['username','=',$data['username']]])->find()){
return ['code' => 0, 'status' =>0, 'msg' => '该用户名已注册!'];
}
if(Db::name('users')->where([['id','<>',session('user.id')],['email','=',$data['email']]])->find()){
return ['code' => 0, 'status' => 0, 'msg' => '该邮箱已注册!'];
}
Db::name('users')->where('id',session('user.id'))->update($data);
$user = Db::name('users')->where('id',session('user.id'))->find();
session('user',$user);
return ['code' => 1, 'status' => 0, 'msg' => '修改成功!'];
}
public function upload()
{
// 获取表单上传文件
$fileKey = array_keys(request()->file());
// 获取表单上传文件
$file = request()->file($fileKey['0']);
try {
validate(['image'=>'fileSize:10240|fileExt:jpg|image:200,200,jpg'])
->check(object2array($file));
$savename = Filesystem::putFile( 'users', $file);
$result['code'] = 0;
$result['msg'] = '图片上传成功!';
$path=str_replace('\\','/',$savename);
$result['url'] = '/uploads/'. $path;
$image = public_path().$result['url'];
$hexStatus = checkHex($image);
if($hexStatus==1){
unlink($image);
$result['code'] =1;
$result['msg'] = '请上传合法图片';
$result['url'] = '';
return $result;
}
Db::name('users')->where('id',session('user.id'))->update(['avatar'=>$result['url']]);
session('user.avatar',$result['url']);
return $result;
} catch (\think\exception\ValidateException $e) {
$result['code'] =1;
$result['msg'] = $e->getMessage();
$result['url'] = '';
return $result;
}
}

public function saveuserpassword(){
$old_password = input('post.old_password');
$password = input('post.password');
$repass = input('post.repass');

if(strlen($password) < 6){
return ['code' => 0, 'msg' => '密码不能低于6位字符!'];
}
if($password != $repass){
return ['code' => 0, 'msg' => '两次密码输入不一致!'];
}

//验证原密码
$user = Db::name('users')->where('id',session('user.id'))->find();

if(($user['password'] != md5($user['token'].$old_password) )){
return ['code' => 0, 'status' => 0, 'msg' => '密码验证失败!'];
}
if( Db::name('users')->where("id", session('user.id'))->update(['password'=>md5($user['token'].$password)])!==false){
return ['code' => 1, 'status' => 0, 'msg' => '修改成功!'];
}else{
return ['code' => 0, 'status' => 0, 'msg' => '修改失败!'];
}
}
}

user视图

common

error.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CLTPHP论坛</title>
</head>
<script src="/static/user/js/sweetalert.min.js"></script>
<body>

<script>
swal({
title: "<?php echo(strip_tags($msg));?>",
text: "点击确认进行跳转",
icon: "error",
timer: '<?php echo($wait*1000);?>',
button: "确认",
}).then((value) => {
window.location.href=escape2Html("{$url}")
});

/**
* 字符转义
* @param str
*/
function escape2Html(str) {
var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"'};
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){return arrEntities[t];});
}
</script>
</body>
</html>

footer.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div class="fly-footer">
<p>
<a href="{$config.url}" target="_blank">CLTPHP.Pro</a>
{$config.copyright} &copy;
<a href="http://www.miitbeian.gov.cn/" target="_blank">{$config.icp}</a>
<a href="http://www.cltphp.com/" target="_blank">CLTPHP 出品</a>
</p>
<p>
{volist name="linkList" id="vo"}
<a href="{$vo.url}" target="_blank">{$vo.title}</a>
{/volist}
</p>
</div>
<script src="__LAYUI__/layui.js"></script>
<script>
layui.cache.page = 'user';
layui.cache.user = {
username: '{:session("user.username")}'?'{:session("user.username")}':'游客'
,uid: -1
,avatar: '{:session("user.avatar")}'?'{:session("user.avatar")}':'__HOME__/images/avatar/00.jpg'
,experience: '{:session("user.id")}'?'{:session("user.id")}':''
,sex: '{:session("user.sex")}'?'{:session("user.sex")}':'男'
};
</script>

head.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{$title ? $title : $config.title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="{$config.key}">
<meta name="description" content="{$config.des}">
<link rel="stylesheet" href="__LAYUI__/css/layui.css">
<link rel="stylesheet" href="__HOME__/css/global.css">
</head>
<body>
<div class="fly-header layui-bg-black">
<div class="layui-container">
<a class="fly-logo" href="{$config.url}">
<img src="{$config.logo}" alt="layui">
</a>
<ul class="layui-nav fly-nav-user">
<!-- 登入后的状态 -->
<li class="layui-nav-item">
<a class="fly-nav-avatar" href="{:url('user/index/index')}">
<cite class="layui-hide-xs">{$userInfo['username']}</cite>
<i class="layui-badge fly-badge-vip layui-hide-xs">{$userInfo['level']}</i>
<img src="{:session('user.avatar')}">
</a>
<dl class="layui-nav-child">
<dd><a href="{:url('user/index/index')}"><i class="layui-icon" style="margin-left: 2px; font-size: 22px;">&#xe68e;</i>我的主页</a></dd>
<dd><a href="{:url('user/set/index')}"><i class="layui-icon">&#xe620;</i>基本设置</a></dd>
<dd><a href="{:url('user/message/index')}"><i class="iconfont icon-tongzhi" style="top: 4px;"></i>我的消息</a></dd>
<hr style="margin: 5px 0;">
<dd><a href="{:url('user/index/loginout')}" style="text-align: center;">退出</a></dd>
</dl>
</li>
</ul>
</div>

</div>

loginFooter.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<div class="fly-footer">
<p>
<a href="{$config.url}" target="_blank">CLTPHP.Pro</a>
{$config.copyright} &copy;
<a href="http://www.miitbeian.gov.cn/" target="_blank">{$config.icp}</a>
<a href="http://www.cltphp.com/" target="_blank">CLTPHP 出品</a>
</p>
<p>
{volist name="linkList" id="vo"}
<a href="{$vo.url}" target="_blank">{$vo.title}</a>
{/volist}
</p>
</div>
<script src="__LAYUI__/layui.js?v={:time()}"></script>
<script>
layui.cache.page = 'user';
layui.cache.user = {
username: '{:session("user.username")}'?'{:session("user.username")}':'游客'
,uid: -1
,avatar: '{:session("user.avatar")}'?'{:session("user.avatar")}':'__HOME__/images/avatar/00.jpg'
,experience: '{:session("user.id")}'?'{:session("user.id")}':''
,sex: '{:session("user.sex")}'?'{:session("user.sex")}':'男'
};
layui.config({
version: "3.0.0"
,base: '__USER__/mods/'
}).extend({
fly: 'index'
}).use(['fly', 'user']);
</script>
</body>
</html>

loginHead.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{$title ? $title : $config.title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="{$config.key}">
<meta name="description" content="{$config.des}">
<link rel="stylesheet" href="__LAYUI__/css/layui.css">
<link rel="stylesheet" href="__HOME__/css/global.css">
<style>
#vercode{height: 38px;cursor: pointer;box-sizing: border-box; border: 1px solid #e2e2e2;}
</style>
</head>
<body>
<div class="fly-header layui-bg-black">
<div class="layui-container">
<a class="fly-logo" href="{$config.url}">
<img src="{$config.logo}" alt="layui">
</a>
</div>
</div>

success.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>CLTPHP论坛</title>
</head>
<script src="/static/user/js/sweetalert.min.js"></script>
<body>
<script>
swal({
title: '<?php echo(strip_tags($msg));?>',
text: "点击确认进行跳转",
icon: "success",
timer: '<?php echo($wait*1000);?>',
button: "确认"
}).then((value) => {
window.location.href="{$url}"
});
</script>
</body>
</html>

index

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{include file="common/head"/}
<div class="layui-container fly-marginTop fly-user-main">
<ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user">
<li class="layui-nav-item layui-this">
<a href="{:url('user/index/index')}">
<i class="layui-icon">&#xe609;</i>
我的主页
</a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/set/index')}">
<i class="layui-icon">&#xe620;</i>
基本设置
</a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/message/index')}">
<i class="layui-icon">&#xe611;</i>
我的消息
</a>
</li>
</ul>
<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>
<div class="fly-panel fly-panel-user" pad20>
<div class="fly-home fly-panel">
<img src="{$userInfo.avatar}" alt="{$userInfo.username}">
<!--<i class="iconfont icon-renzheng" title="Fly社区认证"></i>-->
<h1>
{$userInfo.username}
<i class="iconfont icon-nan"></i>
<i class="layui-badge fly-badge-vip">{$userInfo.level}</i>
</h1>
<p class="fly-home-info">
<i class="iconfont icon-shijian"></i><span>{:toDate($userInfo.create_time)} 加入</span>
{if $userInfo.province}
<i class="iconfont icon-chengshi"></i><span>来自 {:getRegion($userInfo.province)} {:getRegion($userInfo.city)}</span>
{/if}
</p>

{if $userInfo.signature}<p class="fly-home-sign">({$userInfo.signature})</p>{/if}
</div>
<div class="layui-row layui-col-space15">
<div class="layui-col-md12 fly-home-jie">
<div class="fly-panel">
<h3 class="fly-panel-title">您最近的留言</h3>
<ul class="jie-row">
{if $list}
{volist name="list" id="vo"}
<li>
<a href="{:url('user/message/info',['id'=>$vo.id])}" class="jie-title"> {$vo.title}</a>
<em class="layui-hide-xs">{:toDate($vo.create_time)}</em>
</li>
{/volist}
{else/}
<div class="fly-none" style="min-height: 50px; padding:30px 0; height:auto;"><i style="font-size:14px;">您没有留下任何足迹</i></div>
{/if}
</ul>
</div>
</div>
</div>
</div>
</div>
{include file="common/footer"/}
<script>
layui.config({
version: "3.0.0"
,base: '__USER__/mods/'
}).extend({
fly: 'index'
}).use('fly');
</script>
</body>
</html>

login

forget.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{include file="common/loginHead"/}

<div class="layui-container fly-marginTop">
<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title">
<li><a href="{:url('user/login/index')}">登入</a></li>
<li class="layui-this">找回密码<!--重置密码--></li>
</ul>
<div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<div class="layui-form layui-form-pane">
<form method="post">
<div class="layui-form-item">
<label for="L_email" class="layui-form-label">邮箱</label>
<div class="layui-input-inline">
<input type="text" id="L_email" name="email" required lay-verify="required" placeholder="请输入邮箱帐号" autocomplete="off" class="layui-input">
</div>
<button type="button" class="layui-btn layui-btn-normal" lay-filter="sentEmail" id="sentEmail">发送</button>
</div>
<div class="layui-form-item">
<label for="L_vercode" class="layui-form-label">验证码</label>
<div class="layui-input-inline">
<input type="text" id="L_vercode" name="code" lay-verify="required" placeholder="请输入您收到的验证码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="L_pass" class="layui-form-label">密  码</label>
<div class="layui-input-inline">
<input type="password" id="L_pass" name="password" lay-verify="required" placeholder="6到16个字符" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="L_repass" class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" id="L_repass" name="password2" lay-verify="required" placeholder="请输入确认密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" alert="1" lay-filter="login" lay-submit>提交</button>
</div>
</form>
</div>

</div>
</div>
</div>
</div>
</div>
{include file="common/loginFooter"/}

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{include file="common/loginHead"/}
<div class="layui-container fly-marginTop">
<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title">
<li class="layui-this">登入</li>
<li><a href="{:url('user/login/reg')}">注册</a></li>
</ul>
<div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<div class="layui-form layui-form-pane">
<form method="post" >
<div class="layui-form-item">
<label for="username" class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" id="username" name="username" value="chichu" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="L_pass" class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" id="L_pass" name="password" value="123456" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
{if $config.message_code==1}
<div class="layui-form-item">
<label for="L_vercode" class="layui-form-label">验证码</label>
<div class="layui-input-inline">
<input type="text" id="L_vercode" name="vercode" required lay-verify="required" placeholder="请输入验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid" style="padding: 0!important;">
<img src="{:url('captcha')}" data-url="{:url('captcha')}" class="vercode" id="vercode">
</div>
</div>
{/if}
<div class="layui-form-item">
<button class="layui-btn" lay-filter="login" lay-submit>立即登录</button>
<span style="padding-left:20px;">
<a href="forget.html">忘记密码?</a>
</span>
</div>
{if $social}
<div class="layui-form-item fly-form-app">
<div>或者使用社交账号登入</div>
<div style="padding: 15px;">
{volist name="social" id="vo"}
<a href="{:url('Oauth/login',['type'=>$vo.code])}"><img src="{$vo.icon}" style="width: 30px;"></a>
{/volist}
</div>
</div>
{/if}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{include file="common/loginFooter"/}

info.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{include file="common/loginHead"/}
<div class="layui-container fly-marginTop">
<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title">
<li class="layui-this">完善账号</li>
</ul>
<div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<div class="layui-form layui-form-pane">
<form method="post" >
<div class="layui-form-item">
<label for="username" class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" id="username" name="username" value="{$info.username}" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="pass" class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" id="pass" name="password" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">6到16个字符</div>
</div>
<div class="layui-form-item">
<label for="repass" class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" id="repass" name="repass" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<button type="button" class="layui-btn" lay-filter="info" lay-submit>提交</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{include file="common/loginFooter"/}

reg.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{include file="common/loginHead"/}
<div class="layui-container fly-marginTop">
<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title">
<li><a href="{:url('user/login/index')}">登入</a></li>
<li class="layui-this">注册</li>
</ul>
<div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<div class="layui-form layui-form-pane">
<form method="post">
<div class="layui-form-item">
<label for="username" class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" id="username" name="username" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">将会成为您唯一的登入名</div>
</div>
<div class="layui-form-item">
<label for="email" class="layui-form-label">邮箱</label>
<div class="layui-input-inline">
<input type="text" id="email" name="email" required lay-verify="email" autocomplete="off" class="layui-input">
</div>
</div>

<div class="layui-form-item">
<label for="pass" class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" id="pass" name="password" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">6到16个字符</div>
</div>
<div class="layui-form-item">
<label for="repass" class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" id="repass" name="repass" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="L_vercode" class="layui-form-label">验证码</label>
<div class="layui-input-inline">
<input type="text" id="L_vercode" name="vercode" required lay-verify="required" placeholder="请输入验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid" style="padding: 0!important;">
<img src="{:url('captcha')}" data-url="{:url('captcha')}" class="vercode" id="vercode">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" lay-filter="login" lay-submit>立即注册</button>
</div>
{if $social}
<div class="layui-form-item fly-form-app">
<div>或者使用社交账号登入</div>
<div style="padding: 15px;">
{volist name="social" id="vo"}
<a href="{:url('Oauth/login',['type'=>$vo.code])}"><img src="{$vo.icon}" style="width: 30px;"></a>
{/volist}
</div>
</div>
{/if}
</form>
</div>
</div>
</div>
</div>
</div>

</div>
{include file="common/loginFooter"/}

message

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{include file="common/head"/}
<div class="layui-container fly-marginTop fly-user-main">
<ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user">
<li class="layui-nav-item">
<a href="{:url('user/index/index')}">
<i class="layui-icon">&#xe609;</i>
我的主页
</a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/set/index')}">
<i class="layui-icon">&#xe620;</i>
基本设置
</a>
</li>
<li class="layui-nav-item layui-this">
<a href="{:url('user/message/index')}">
<i class="layui-icon">&#xe611;</i>
我的消息
</a>
</li>
</ul>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>


<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title" id="LAY_mine">
<li data-type="mine-jie" lay-id="index" class="layui-this">未结(<span>{$nocount}</span></li>
<li data-type="collection" data-url="/collection/find/" lay-id="collection">已结(<span>{$yescount}</span></li>
</ul>
<div class="layui-tab-content" style="padding: 20px 0;">
<div class="layui-tab-item layui-show">
<ul class="mine-view jie-row">
{volist name="list" id="vo"}
<li>
<a class="jie-title" href="{:url('user/message/info',['id'=>$vo.id])}">{$vo.title}</a>
<i>{:toDate($vo.create_time)}</i>
{if $vo.reply eq 1}
<a class="mine-edit" href="{:url('user/message/info',['id'=>$vo.id])}">查看</a>
{/if}
</li>
{/volist}
</ul>
<div id="LAY_page"></div>
</div>
<div class="layui-tab-item">
<ul class="mine-view jie-row">
{volist name="yeslist" id="vo"}
<li>
<a class="jie-title" href="{:url('user/message/info',['id'=>$vo.id])}">{$vo.title}</a>
<i>{:toDate($vo.create_time)}</i>
</li>
{/volist}
</ul>
<div id="LAY_page1"></div>
</div>
</div>
</div>
</div>
</div>
{include file="common/footer"/}
<script>
layui.config({
version: "3.0.0"
,base: '__USER__/mods/'
}).extend({
fly: 'index'
}).use('fly');
</script>

</body>
</html>

info.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
{include file="common/head"/}

<div class="layui-container fly-marginTop fly-user-main">
<ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user">
<li class="layui-nav-item">
<a href="{:url('user/index/index')}">
<i class="layui-icon">&#xe609;</i>
我的主页
</a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/set/index')}">
<i class="layui-icon">&#xe620;</i>
基本设置
</a>
</li>
<li class="layui-nav-item layui-this">
<a href="{:url('user/message/index')}">
<i class="layui-icon">&#xe611;</i>
我的消息
</a>
</li>
</ul>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>


<div class="fly-panel fly-panel-user" pad20>
<fieldset class="layui-elem-field" style="margin-top: 30px;">
<legend>{$info.title}</legend>
<div class="layui-field-box">
{$info.content}
</div>
</fieldset>
<ul class="layui-timeline">
{volist name="list" id="vo"}
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h3 class="layui-timeline-title">{if $vo.is_self eq 1}后台:{else/}自己:{/if}({:toDate($vo.create_time)})</h3>
<p>
{$vo.content}
</p>
</div>
</li>
{/volist}
</ul>
{if $info.status eq 0}
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend>继续讨论</legend>
</fieldset>
<form class="layui-form layui-form-pane" action="{:url('user/message/reply')}">
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">文本域</label>
<div class="layui-input-block">
<textarea placeholder="请输入内容" name="content" lay-verify="required" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<input type="hidden" value="{$info.id}" name="mid">
<button class="layui-btn" key="set-mine" lay-filter="*" lay-submit>提交</button>
<button type="button" data-id="{$info.id}" class="layui-btn layui-btn-danger" id="close">结帖</button>
</div>
</form>
{/if}
</div>

</div>

{include file="common/footer"/}
<script>
layui.config({
version: "3.0.0"
, base: '__USER__/mods/'
}).extend({
fly: 'index'
}).use('fly',function(){
var $ = layui.$;
$('#close').click(function(){
var id = $(this).data('id');
$.post("{:url('user/message/status')}",{'id':id},function(res){
if(res.code>0){
layer.msg(res.msg, {time: 1000, icon: 1},function(){
window.location.href = res.url;
});
}

})
})
});
</script>

</body>
</html>

set

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
{include file="common/head"/}
<div class="layui-container fly-marginTop fly-user-main">
<ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user">
<li class="layui-nav-item">
<a href="{:url('user/index/index')}">
<i class="layui-icon">&#xe609;</i>
我的主页
</a>
</li>
<li class="layui-nav-item layui-this">
<a href="{:url('user/set/index')}">
<i class="layui-icon">&#xe620;</i>
基本设置
</a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/message/index')}">
<i class="layui-icon">&#xe611;</i>
我的消息
</a>
</li>
</ul>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>

<div class="site-tree-mobile layui-hide">
<i class="layui-icon">&#xe602;</i>
</div>
<div class="site-mobile-shade"></div>


<div class="fly-panel fly-panel-user" pad20>
<div class="layui-tab layui-tab-brief" lay-filter="user">
<ul class="layui-tab-title" id="LAY_mine">
<li class="layui-this" lay-id="info">我的资料</li>
<li lay-id="avatar">头像</li>
<li lay-id="pass">密码</li>
<li lay-id="bind">帐号绑定</li>
</ul>
<div class="layui-tab-content" style="padding: 20px 0;">
<div class="layui-form layui-form-pane layui-tab-item layui-show">
<form method="post" action="{:url('user/set/userinfo')}">
<div class="layui-form-item">
<label for="username" class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" id="username" name="username" required lay-verify="required" autocomplete="off" value="{$userInfo.username}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="email" class="layui-form-label">邮箱</label>
<div class="layui-input-inline">
<input type="text" id="email" name="email" required lay-verify="email" autocomplete="off" value="{$userInfo.email|default=''}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="email" class="layui-form-label">电话</label>
<div class="layui-input-inline">
<input type="text" id="mobile" name="mobile" required lay-verify="phone" autocomplete="off" value="{$userInfo.mobile|default=''}" class="layui-input">
</div>
<div class="layui-inline">
<div class="layui-input-inline">
<input type="radio" name="gender" value="1" {if $userInfo.gender == '男'}checked{/if} title="男">
<input type="radio" name="gender" value="0" {if $userInfo.gender == '女'}checked{/if} title="女">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">地址</label>
<div class="layui-input-inline">
<select name="province" lay-filter="province" class="layui-hide">
<option value="">请选择省</option>
{volist name="province" id="vo"}
<option value="{$vo.id}" {if $userInfo.province == $vo.id}selected{/if}>{$vo.name}</option>
{/volist}
</select>
</div>
<div class="layui-input-inline">
<select name="city" lay-filter="city" id="city" class="layui-hide">
<option value="">请选择市</option>
{volist name="city" id="vo"}
<option value="{$vo.id}" {if condition="$userInfo['city'] eq $vo['id']" }selected{/if}>{$vo.name}</option>
{/volist}
</select>
</div>
<div class="layui-input-inline">
<select name="area" id="area" class="layui-hide">
<option value="">请选择县/区</option>
{volist name="area" id="vo"}
<option value="{$vo.id}" {if condition="$userInfo['area'] eq $vo['id']" }selected{/if}>{$vo.name}</option>
{/volist}
</select>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label for="signature" class="layui-form-label">签名</label>
<div class="layui-input-block">
<textarea placeholder="随便写些什么刷下存在感" id="signature" name="signature" autocomplete="off" class="layui-textarea" style="height: 80px;">{$userInfo.signature}</textarea>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" key="set-mine" lay-filter="*" lay-submit>确认修改</button>
</div>
</form>
</div>

<div class="layui-form layui-form-pane layui-tab-item">
<div class="layui-form-item">
<div class="avatar-add">
<p>建议尺寸168*168,支持jpg、png、gif,最大不能超过50KB</p>
<button type="button" class="layui-btn upload-img">
<i class="layui-icon">&#xe67c;</i>上传头像
</button>
<img src="{$userInfo.avatar}">
<span class="loading"></span>
</div>
</div>
</div>

<div class="layui-form layui-form-pane layui-tab-item">
<form action="{:url('user/set/saveUserPassword')}" method="post">
<div class="layui-form-item">
<label for="L_nowpass" class="layui-form-label">当前密码</label>
<div class="layui-input-inline">
<input type="password" id="L_nowpass" name="old_password" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label for="L_pass" class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" id="L_pass" name="password" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">6到16个字符</div>
</div>
<div class="layui-form-item">
<label for="L_repass" class="layui-form-label">确认密码</label>
<div class="layui-input-inline">
<input type="password" id="L_repass" name="repass" required lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" key="set-mine" lay-filter="*" lay-submit>确认修改</button>
</div>
</form>
</div>

<div class="layui-form layui-form-pane layui-tab-item">
<ul class="app-bind">
{volist name="social" id="vo"}
{if $vo.status ==1}
<li class="fly-msg app-havebind">
<span>已成功绑定{$vo.name},您可以使用{$vo.name}帐号直接登录社区,当然,您也可以</span>
<a href="{:url('user/login/unbind',['id'=>$userInfo.id,'type'=>$vo.code])}" type="qq_id">解除绑定</a>
</li>
{else }

<li class="fly-msg">
绑定{$vo.name}账号:<a href="{:url('user/oauth/login',['type'=>$vo.code])}" onclick="layer.msg('正在绑定{$vo.name}', {icon:16, shade: 0.1, time:0})" class="acc-bind" type="qq_id">立即绑定</a>
<span>,即可使用{$vo.name}帐号登录社区</span>
</li>
{/if}
{/volist}

</ul>
</div>
</div>
</div>
</div>
</div>

{include file="common/footer"/}
<script>
layui.config({
version: "2.0.0"
,base: '__USER__/mods/'
}).extend({
fly: 'index'
}).use('fly');
</script>
</body>
</html>

模板开发

站点全局参数

1
2
3
{$config.name}	//网站名称
{$config.copyright}
{$config.icp}

二级导航

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//导航状态
{tp:nav name='nav' limit='10'}
<li class="layui-nav-item {if $cate and $nav['id'] == $cate['topid']}layui-this{/if}">
{if $nav.sub}
<a href="javascript:;">{$nav.catname}</a>
<dl class="layui-nav-child">
{volist name="$nav.sub" id="v"}
<dd><a href="{$v.url}" {if $v.type eq 1} target="_blank"{/if}>{$v.catname}</a></dd>
{/volist}
</dl>
{else/}
<a href="{$nav.url}" {if $nav.type eq 1} target="_blank"{/if}>{$nav.catname}</a>
{/if}
</li>
{/tp:nav}
//导航检测是否登录
{if $userInfo}
<li class="layui-nav-item">
<a class="fly-nav-avatar" href="{:url('user/index/index')}">
<cite class="layui-hide-xs">{$userInfo['username']}</cite>
<i class="layui-badge fly-badge-vip layui-hide-xs">{$userInfo['level']}</i>
<img src="{:session('user.avatar')}">
</a>
<dl class="layui-nav-child">
<dd><a href="{:url('user/index/index')}"><i class="layui-icon" style="margin-left: 2px; font-size: 22px;">&#xe68e;</i>我的主页</a></dd>
<dd><a href="{:url('user/set/index')}"><i class="layui-icon">&#xe620;</i>基本设置</a></dd>
<dd><a href="{:url('user/message/index')}"><i class="iconfont icon-tongzhi" style="top: 4px;"></i>我的消息</a></dd>
<hr style="margin: 5px 0;">
<dd><a href="{:url('user/index/loginout')}" style="text-align: center;">退出</a></dd>
</dl>
</li>
{else/}
<!-- 未登入的状态 -->
<li class="layui-nav-item">
<a class="iconfont icon-touxiang layui-hide-xs" href="{:url('user/login/index')}"></a>
</li>
<li class="layui-nav-item">
<a href="{:url('user/login/index')}">登入</a>
</li>
{/if}



{tp:ads name='ads' id='1'}
<div class="picture">
<a href="{$ads.url}" target="_blank">
<div class="banner-title">{$ads.title}</div>
<img src="{$ads.pic}">
</a>
</div>
{/tp:ads}


{tp:dblist db='debris' id='list' limit="3" where="type_id = 1"}
<div class="layui-col-xs12 layui-col-sm12 layui-col-md4">
<div class="site-idea">
<fieldset class="layui-elem-field layui-field-title">
<legend>{$list.title}</legend>
<div class="info">
{$list.content|raw}
</div>
</fieldset>
</div>
</div>
{/tp:dblist}

//友情链接
{tp:link name='link'}
<a href="{$link.url}" target="_blank">{$link.title}</a>
{/tp:link}

模板标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{tp:nav name='nav' limit='10'}
//当前控制器
{if $controller == 'index'}layui-this{/if}
//高亮
{if $cate and $nav['id'] == $cate['topid']}layui-this{/if}
//判断二级导航
{if $nav.sub}
//循环二级导航
{volist name="$nav.sub" id="vo"}
//判断三级导航
{if $vo.sub}
//循环三级导航
{volist name="$nav.sub" id="vs"}
...以此类推
{/volist}
{/volist}
{/if}
//链接
{:url('index/'.$nav['catdir'].'/index',['catid'=>$nav.id])}
{:url('index/news/info',array('catid'=>$vo['catid'],'id'=>$vo['id']))}
/index/{$nav.catdir}/index.html?catid={$vo.id}
{/tp:nav}
{if condition="$k % 2 == 0"}
{if $controller == 'Product'}{/if}
{:toDate($info.createtime,'Y-m-d')}


<div>上一篇:{tp:prev len="120"}</div>
<div>下一篇:{tp:next len="120"}</div>

cate栏目信息标签

1
2
{tp:cate id='1'}
//cate用于显示当前分类的信息

position位置信息标签

1
2
3
4
5
6
7
8
{tp:position name="p"}

{/tp:position}
position 标签是一个非闭合标签,以{tp:position}开头,以{/tp:position}结尾
//页面数据输出
{tp:position name="p"}
<a href="{$p.url}">{$p.catname}<i class="iconfont icon-gengduo"></i></a>
{/tp:position}

link获取友情链接

1
2
3
4
5
6
7
{tp:link name="link"}

{/tp:link}
//页面数据输出
{tp:link name="link"}
<a href="{$link.url}" target="_blank">{$link.title}</a>
{/tp:link}

ad获取广告信息

1
2
3
4
5
6
7
8
9
10
11
12
{tp:ad name='ad' id='1'}

{/tp:ad}
//页面数据输出
{tp:ad name='ad' id='1'}
<div class="picture">
<a href="{$ad.url}" target="_blank">
<div class="banner-title">{$ad.title}</div>
<img src="{$ad.pic}">
</a>
</div>
{/tp:ad}

clist普通列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{tp:clist db='article' id='list' limit="3" where="catid=1" order="id desc" key="i"}

{/tp:clist}
//参数解释
db:所以获取数据的表名
id:页面输出数据的循环变量
limit:获取数据条数
where:查询条件
order:排序
key:循环键名

//页面数据输出
<dl class="fly-panel fly-list-one">
<dt class="fly-panel-title">推荐内容</dt>
{tp:clist db='article' id='list' limit="3" where=""}
<dd>
<a href="{$list.url}" title="{$list.title}" style="{$list.title_style}">{$list.title}</a>
<span class="pull-right"><i class="iconfont" title="点击">&#xe60b;</i> {$list.hits}</span>
</dd>
{/tp:clist}
</dl>

网站功能

字段输出问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//多图
$firstImage = $duotu[0];
if (!empty($info['duotu'])) {
// $info['duotu'] 已经是数组,可以直接使用
// 例如,遍历数组并打印图片路径
foreach ($info['duotu'] as $key => $value) {
echo "图片ID: $key, 图片路径: $value<br>";
}
} else {
echo "没有图片数据。";
}

//多图获取第一张
$productlist = Db::name("goods")->where(['posid'=>1,'status'=>1])->order('id')->select();
$productlists = [];
foreach ($productlist as $k => $v) {
// if (!empty($v['duotu'])) {
// $v['duotu'] = json_decode($v['duotu'], true);
// }
// 多图获取第一张
$duotuArray = json_decode($v['duotu'], true);
if (is_array($duotuArray) && !empty($duotuArray)) {
$firstKey = array_keys($duotuArray)[0];
$v['oneimg'] = $duotuArray[$firstKey];
} else {
$v['oneimg'] = '';
}
$v['zhongleiname'] = $optionsarr[$v['zhonglei']]['val'];
$v['lingyangname'] = $lingyangarr[$v['lingyang']]['val'];
$productlists[] = $v;
}




//字符串组成数组
$array = explode(",", $string);


//单选按钮
$setup = Db::name('field')->where(['modelid'=>17,'field'=>'zhonglei'])->value('setup');
$optionsarr = array();
if ($setup) {
$setup = is_array($setup) ? $setup : string2array($setup);
$options = explode("\n", $setup['options']);
foreach ($options as $r) {
$v = explode("|", $r);
$k = trim($v[1]);
$optionsarr[$k]['val'] = $v[0];
$optionsarr[$k]['key'] = $k;
}
}


//编辑器视图渲染html转换为纯文本
{php}$text = strip_tags($vo['content']);echo $text;{/php}

循环产品根据catid去重选出分类并循环分类下产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$recommend = Db::name("test")
->where('is_recommend', 1)
->order('id')
->select()
->toArray();

// 2. 提取分类信息(去重)
$recommend_catid = array_unique(array_column($recommend, 'catid'));
$categories = Db::name('category')
->whereIn('id', $recommend_catid)
->column('catname', 'id');

// 3. 构建新结构:分类信息 + 商品数据
$is_recommend = [];
foreach ($recommend_catid as $catId) {
// 获取当前分类的商品
$products = array_filter($recommend, function($item) use ($catId) {
return $item['catid'] == $catId;
});

// 存入统一数组
$is_recommend[] = [
'catid' => $catId,
'catname' => $categories[$catId] ?? '未分类',
'test' => array_map(function($product) {
return [
'id' => $product['id'],
'test_title' => $product['test_title'],
'test_img' => $product['test_img'] ?? 'default.jpg'
];
}, $products)
];
}

在线留言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//HTML
<script type="text/javascript" src="__INDEX__/index/mods/js/jquery-3.7.0.min.js"></script>
<script type="text/javascript">
$("#buttonesx").click(function(){
var flag=true;
var name=$("#name").val();
var email=$("#email").val();
var tel=$("#title").val();
var content=$("#message").val();
if(!name){
alert('请填写姓名!');
flag=false;
return false;
}
if(!email){
alert('请填写邮箱!');
flag=false;
return false;
}
if(!content){
alert('请填写详细备注!');
flag=false;
return false;
}
if(flag){
$.post({
url:"/index/index/contace.html",
data:{
'name':name,
'email':email,
'tel':tel,
'content':content,
},
success:function(res){
if (res.success == true) {
alert(res.msg); // 显示成功消息
location.reload(); // 刷新页面
} else {
alert('提交失败!');
}
}
})
}
return false;
});
</script>

产品模型

循环2级所以产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if($cate['pid'] !=0){
$products = Db::name("product")->where('catid', $catid)->order('id')->select();
}else{
$categoryId = $category['id']; // 一级分类ID
$subCategoryIds = explode(',', $category['arrchildid']); // 二级分类ID数组arrchildid
// 获取所有相关的二级分类
$subCategories = Db::name("category")->where('pid', $categoryId)->order('id')->select();
// 遍历每个二级分类
$products = [];
foreach ($subCategories as $subCategory) {
// 检查当前二级分类的ID是否在允许的ID列表中
if (in_array($subCategory['id'], $subCategoryIds)) {
// 获取当前二级分类下的所有产品
$subCategoryProducts = Db::name("product")->where('catid', $subCategory['id'])->order('id')->select();
$products = array_merge($products, $subCategoryProducts->toArray());
}
}
}

循环1-4级分类已经分类下的产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 假设你已经获取到了一级分类ID和二级分类数据
$categoryId = $category['id']; // 一级分类ID
$subCategoryIds = explode(',', $category['arrchildid']); // 二级分类ID数组(包含部分三级和四级分类ID,但这里我们只关注二级分类ID开头)
// 首先获取所有相关的二级分类
$subCategories = Db::name("category")->where('pid', $catid)->order('id')->select()->toArray();
// 初始化一个数组来存储所有相关的三级、四级分类及产品数据
$allSubCategories = [];
// 遍历二级分类
foreach ($subCategories as $subCategory) {
$subCategoryId = $subCategory['id']; // 当前二级分类的ID
// 假设二级分类的ID在$subCategoryIds数组中(实际上这一步可能是多余的,因为我们已经从数据库按pid获取了)
if (in_array($subCategoryId, $subCategoryIds)) {
// 获取当前二级分类下的所有三级分类
$thirdLevelCategories = Db::name("category")->where('pid', $subCategoryId)->order('id')->select()->toArray();
$product = Db::name("product")->where('catid', $subCategoryId)->order('id')->select()->toArray();
// $subCategoryIds['product'] = $product;
$subCategory['third_level'] = []; // 初始化三级分类数组
$subCategory['product'] = $product; // 初始化三级分类产品数组
// 遍历三级分类
foreach ($thirdLevelCategories as $thirdLevelCategory) {
$thirdLevelCategoryId = $thirdLevelCategory['id']; // 当前三级分类的ID
// 获取当前三级分类下的所有四级分类
$fourthLevelCategories = Db::name("category")->where('pid', $thirdLevelCategoryId)->order('id')->select()->toArray();
$product = Db::name("product")->where('catid', $thirdLevelCategoryId)->order('id')->select()->toArray();
$thirdLevelCategory['fourth_level'] = $fourthLevelCategories;
$thirdLevelCategory['product'] = $product;
// 将四级分类赋值给三级分类的'fourth_level'键
// 初始化当前三级分类下的产品数据数组
// $thirdLevelCategory['product'] = [];
// 遍历四级分类(如果有的话,也可以直接在三级分类下查询产品,如果不需要四级分类细分)
// foreach ($fourthLevelCategories as $fourthLevelCategory) {
// $fourthLevelCategoryId = $fourthLevelCategory['id']; // 当前四级分类的ID

// 获取当前四级分类下的所有产品(或者根据需求,直接在三级分类下查询产品)
// $product = Db::name("product")->where('catid', $fourthLevelCategoryId)->order('id')->select()->toArray();
// 将产品数据添加到四级分类的'product'键中(或者三级分类,如果直接在三级分类下查询)
// 如果不需要四级分类细分,可以将查询条件改为 $thirdLevelCategoryId
// $fourthLevelCategory['product'] = $product;

// 如果产品数据直接挂在三级分类下,则使用以下代码替代上面的产品查询和赋值
// $product = Db::name("product")->where('category_id', $thirdLevelCategoryId)->order('id')->select()->toArray();
// $thirdLevelCategory['product'] = array_merge($thirdLevelCategory['product'], $product); // 注意这里使用array_merge来合并产品数组
// }

// 如果产品数据直接挂在三级分类下,并且不需要遍历四级分类,则上面的四级分类循环可以省略,
// 并且产品查询和赋值应该直接放在三级分类的循环中,如上面注释所示。

// 将(可能包含四级分类及产品的)三级分类添加到二级分类的'third_level'数组中
$subCategory['third_level'][] = $thirdLevelCategory;
}

// 将处理后的二级分类(可能包含三级和四级分类及产品数据)添加到最终数组中
$allSubCategories[] = $subCategory;
}
}

产品每输出三个切换数组继续循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$products = Db::name("goods")->where(['posid'=>1,'status'=>1])->order('id')->select();
// 初始化存放数组的变量
$productLists = [];
$currentSubArrayIndex = 0;
$itemsPerSubArray = 3; // 每个子数组存放的数据项数量
// 遍历所有产品
foreach ($products as $product) {
// 添加iqoo字段到每个产品
$product['iqoo'] = 123;
// 如果当前子数组已满,则创建一个新的子数组
if (!isset($productLists[$currentSubArrayIndex]) || count($productLists[$currentSubArrayIndex]) >= $itemsPerSubArray) {
$currentSubArrayIndex++;
}
// 将当前产品(已添加iqoo字段)添加到当前子数组中
$productLists[$currentSubArrayIndex][] = $product;
}

现有问题

1、一个模型不能写两个一级导航