正在显示
31 个修改的文件
包含
1242 行增加
和
674 行删除
@@ -10,6 +10,9 @@ return [ | @@ -10,6 +10,9 @@ return [ | ||
10 | // | 应用设置 | 10 | // | 应用设置 |
11 | // +---------------------------------------------------------------------- | 11 | // +---------------------------------------------------------------------- |
12 | 12 | ||
13 | |||
14 | + 'app_id' => 'wx610594b3642770b0', | ||
15 | + 'app_secret' => '399ab87a53d788e82eec2bc0b02e256e', | ||
13 | // 应用命名空间 | 16 | // 应用命名空间 |
14 | 'app_namespace' => 'api', | 17 | 'app_namespace' => 'api', |
15 | // 应用模式状态 | 18 | // 应用模式状态 |
@@ -12,41 +12,6 @@ use api\home\service\AnswerService; | @@ -12,41 +12,6 @@ use api\home\service\AnswerService; | ||
12 | */ | 12 | */ |
13 | class IndexController extends RestUserBaseController | 13 | class IndexController extends RestUserBaseController |
14 | { | 14 | { |
15 | - /** | ||
16 | - * @title 首页信息接口 | ||
17 | - * @description BannerTitle | ||
18 | - * @author WeiQiang | ||
19 | - * @url /home/index/index | ||
20 | - * @method POST | ||
21 | - * @header name:XX-Token require:1 default: desc:token | ||
22 | - * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | ||
23 | - * @return banner:顶部标语@ | ||
24 | - * @banner title:标语标题 content:标语列表@ | ||
25 | - * @content name:文字 | ||
26 | - * @return index_text:优惠券标语信息 | ||
27 | - * @return tpl:联系电话 | ||
28 | - */ | ||
29 | - public function index() | ||
30 | - { | ||
31 | - $list = Db::name('banner') | ||
32 | - ->field('title ,content') | ||
33 | - ->order('id','DESC') | ||
34 | - ->select(); | ||
35 | - $array = []; | ||
36 | - foreach ($list as $l){ | ||
37 | - $arr = explode('/',$l['content']); | ||
38 | - $content_array = []; | ||
39 | - for($i=0;$i<count($arr);$i++){ | ||
40 | - $content_array[] = ['name'=>$arr[$i]]; | ||
41 | - } | ||
42 | - array_push($array , ['title'=>$l['title'],'content'=>$content_array]); | ||
43 | - } | ||
44 | - $PublicConfig = Db::name('public_config')->where('id',1)->find(); | ||
45 | - $index_text = $PublicConfig['index_text']; | ||
46 | - $tpl = $PublicConfig['tpl']; | ||
47 | - | ||
48 | - $this->success("SUCCESS", ['banner'=>$array,'tpl'=>$tpl,'index_text'=>$index_text]); | ||
49 | - } | ||
50 | 15 | ||
51 | /** | 16 | /** |
52 | * @title 判断用户是否保存手机接口 | 17 | * @title 判断用户是否保存手机接口 |
@@ -121,12 +86,16 @@ class IndexController extends RestUserBaseController | @@ -121,12 +86,16 @@ class IndexController extends RestUserBaseController | ||
121 | * @method POST | 86 | * @method POST |
122 | * @header name:XX-Token require:1 default: desc:token | 87 | * @header name:XX-Token require:1 default: desc:token |
123 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 88 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
124 | - * @return type:领取成功返回true | 89 | + * @return type:领取成功返回true,返回40002为已经领取,40001数据库写入错误 |
125 | * @return coupon_text:成功返回成功消息语 | 90 | * @return coupon_text:成功返回成功消息语 |
126 | */ | 91 | */ |
127 | public function couponPost(){ | 92 | public function couponPost(){ |
128 | $user_id = $this->getUserId(); | 93 | $user_id = $this->getUserId(); |
129 | $coupon = Db::name('coupon')->where('type',1)->where('delete_time',0)->find(); | 94 | $coupon = Db::name('coupon')->where('type',1)->where('delete_time',0)->find(); |
95 | + $user_coupon = Db::name('user_coupon')->where('user_id',$user_id)->where('coupon_id',$coupon['id'])->count(); | ||
96 | + if($user_coupon > 0){ | ||
97 | + $this->error(['code'=>40002,'msg'=>'该优惠券一个用户仅限领取一次']); | ||
98 | + } | ||
130 | if(Db::name('user_coupon')->insert([ | 99 | if(Db::name('user_coupon')->insert([ |
131 | 'user_id' => $user_id, | 100 | 'user_id' => $user_id, |
132 | 'coupon_id' => $coupon['id'], | 101 | 'coupon_id' => $coupon['id'], |
@@ -151,11 +120,11 @@ class IndexController extends RestUserBaseController | @@ -151,11 +120,11 @@ class IndexController extends RestUserBaseController | ||
151 | * @header name:XX-Token require:1 default: desc:token | 120 | * @header name:XX-Token require:1 default: desc:token |
152 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 121 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
153 | * @return list:题目列表@ | 122 | * @return list:题目列表@ |
154 | - * @list id:题目id title:题目 content:选错提示 type:正确选项1为是2为否 | 123 | + * @list id:题目id title:题目 content:选错提示 type:正确选项1为是0为否 order_id:题目排序 |
155 | */ | 124 | */ |
156 | public function qualification(){ | 125 | public function qualification(){ |
157 | $list = Db::name('qualification') | 126 | $list = Db::name('qualification') |
158 | - ->field('id,title,content,type') | 127 | + ->field('id,title,content,type ,order_id') |
159 | ->where('delete_time',0) | 128 | ->where('delete_time',0) |
160 | ->order('order_id') | 129 | ->order('order_id') |
161 | ->select(); | 130 | ->select(); |
@@ -187,8 +156,8 @@ class IndexController extends RestUserBaseController | @@ -187,8 +156,8 @@ class IndexController extends RestUserBaseController | ||
187 | * @header name:XX-Token require:1 default: desc:token | 156 | * @header name:XX-Token require:1 default: desc:token |
188 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 157 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
189 | * @return list:题目列表@ | 158 | * @return list:题目列表@ |
190 | - * @list id:题目id title:题目 hint_type:是否有答题提示1为有0为没有 hint_title:答题提示标题 hint_content:答题提示内容 question:选项列表@ | ||
191 | - * @question id:选项列表 title:选项内容 | 159 | + * @list id:题目id title:题目 hint_type:是否有答题提示1为有0为没有 hint_text:答题提示标注 hint_title:答题提示标题 hint_content:答题提示内容 question:选项列表@ order_id:问题排序 |
160 | + * @question id:选项列表 title:选项内容 order_id:选项排序 | ||
192 | */ | 161 | */ |
193 | public function question(){ | 162 | public function question(){ |
194 | $list = Db::name('question')->where('delete_time',0)->where('parent_id',0)->order('order_id')->select(); | 163 | $list = Db::name('question')->where('delete_time',0)->where('parent_id',0)->order('order_id')->select(); |
@@ -200,8 +169,10 @@ class IndexController extends RestUserBaseController | @@ -200,8 +169,10 @@ class IndexController extends RestUserBaseController | ||
200 | $arr['hint_type'] = $l['hint_type']; | 169 | $arr['hint_type'] = $l['hint_type']; |
201 | $arr['hint_title'] = $l['hint_title']; | 170 | $arr['hint_title'] = $l['hint_title']; |
202 | $arr['hint_content'] = $l['hint_content']; | 171 | $arr['hint_content'] = $l['hint_content']; |
172 | + $arr['hint_text'] = $l['hint_text']; | ||
173 | + $arr['order_id'] = $l['order_id']; | ||
203 | $question = Db::name('question') | 174 | $question = Db::name('question') |
204 | - ->field('id ,title') | 175 | + ->field('id ,title ,order_id') |
205 | ->where('delete_time',0) | 176 | ->where('delete_time',0) |
206 | ->where('parent_id',$l['id']) | 177 | ->where('parent_id',$l['id']) |
207 | ->order('order_id') | 178 | ->order('order_id') |
@@ -221,15 +192,24 @@ class IndexController extends RestUserBaseController | @@ -221,15 +192,24 @@ class IndexController extends RestUserBaseController | ||
221 | * @header name:XX-Token require:1 default: desc:token | 192 | * @header name:XX-Token require:1 default: desc:token |
222 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 193 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
223 | * @param name:questionStr type:string require:1 other:问题id-选项id,问题id-选项id desc:答题结果字符串 | 194 | * @param name:questionStr type:string require:1 other:问题id-选项id,问题id-选项id desc:答题结果字符串 |
224 | - * @return fen:分数区间 content:分数评价 type:是否显示评星1为显示 start:评星数量@ question:题目单独评价列表@ | ||
225 | - * @start num:评星数量 title:解释文字 type:1为知识产权2为科技成果转化情况3为研发组织管理水平4为财务增长情况 | 195 | + * @return fen:分数区间 |
196 | + * @return content:分数评价 | ||
197 | + * @return type:是否显示评星1为显示 | ||
198 | + * @return start:评星数量@ | ||
199 | + * @return question:题目单独评价列表@ | ||
200 | + * @start text:类型内容 num:评星数量 title:解释文字 type:1为知识产权2为科技成果转化情况3为研发组织管理水平4为财务增长情况 | ||
226 | * @question title:题目编号 content:单独评价题目内容 | 201 | * @question title:题目编号 content:单独评价题目内容 |
202 | + * @return all_fen:总分 | ||
227 | */ | 203 | */ |
228 | public function questionPost(){ | 204 | public function questionPost(){ |
229 | $question_str = input('questionStr'); | 205 | $question_str = input('questionStr'); |
230 | //结果采集 | 206 | //结果采集 |
207 | + | ||
231 | $Answer = new AnswerService(); | 208 | $Answer = new AnswerService(); |
232 | $array = $Answer->answer($question_str); | 209 | $array = $Answer->answer($question_str); |
210 | + if($array == false){ | ||
211 | + $this->error(['code'=>40001,'msg'=>'请完成所有题目']); | ||
212 | + } | ||
233 | //保存结果 | 213 | //保存结果 |
234 | $user_id = $this->getUserId(); | 214 | $user_id = $this->getUserId(); |
235 | $user_answer = Db::name('user_answer')->where('user_id',$user_id)->find(); | 215 | $user_answer = Db::name('user_answer')->where('user_id',$user_id)->find(); |
@@ -271,9 +251,15 @@ class IndexController extends RestUserBaseController | @@ -271,9 +251,15 @@ class IndexController extends RestUserBaseController | ||
271 | * @method POST | 251 | * @method POST |
272 | * @header name:XX-Token require:1 default: desc:token | 252 | * @header name:XX-Token require:1 default: desc:token |
273 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 253 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
274 | - * @return answer:有结果返回true无结果返回false fen:分数区间 content:分数评价 type:是否显示评星1为显示 start:评星数量@ question:题目单独评价列表@ | ||
275 | - * @start num:评星数量 title:解释文字 type:1为知识产权2为科技成果转化情况3为研发组织管理水平4为财务增长情况 | 254 | + * @return answer:有结果返回true无结果返回false |
255 | + * @return fen:分数区间 | ||
256 | + * @return content:分数评价 | ||
257 | + * @return type:是否显示评星1为显示 | ||
258 | + * @return start:评星数量@ | ||
259 | + * @return question:题目单独评价列表@ | ||
260 | + * @start text:类型内容 num:评星数量 title:解释文字 type:1为知识产权2为科技成果转化情况3为研发组织管理水平4为财务增长情况 | ||
276 | * @question title:题目编号 content:单独评价题目内容 | 261 | * @question title:题目编号 content:单独评价题目内容 |
262 | + * @return all_fen:总分 | ||
277 | */ | 263 | */ |
278 | public function MyAnswer(){ | 264 | public function MyAnswer(){ |
279 | $user_id = $this->getUserId(); | 265 | $user_id = $this->getUserId(); |
@@ -296,10 +282,12 @@ class IndexController extends RestUserBaseController | @@ -296,10 +282,12 @@ class IndexController extends RestUserBaseController | ||
296 | * @method POST | 282 | * @method POST |
297 | * @header name:XX-Token require:1 default: desc:token | 283 | * @header name:XX-Token require:1 default: desc:token |
298 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 | 284 | * @header name:XX-Device-Type require:1 default:wxapp desc:固定参数 |
285 | + *@param name:type type:int require:1 other:0为未使用,1为已使用,2为已过期 desc:优惠券类型 | ||
299 | * @return list:优惠券列表@ | 286 | * @return list:优惠券列表@ |
300 | - * @list title:优惠券名称 start_time:开始时间 end_time:结束时间 money:金额 content:简介 status:优惠券状态0待使用1已使用2已过期 | 287 | + * @list title:优惠券名称 start_time:开始时间 end_time:结束时间 money:金额 content:简介 type:优惠券状态0待使用1已使用2已过期 |
301 | */ | 288 | */ |
302 | public function MyCoupon(){ | 289 | public function MyCoupon(){ |
290 | + $type = input('type'); | ||
303 | $user_id = $this->getUserId(); | 291 | $user_id = $this->getUserId(); |
304 | $list = Db::name('user_coupon') | 292 | $list = Db::name('user_coupon') |
305 | ->alias('uc') | 293 | ->alias('uc') |
@@ -317,7 +305,13 @@ class IndexController extends RestUserBaseController | @@ -317,7 +305,13 @@ class IndexController extends RestUserBaseController | ||
317 | $item['end_time'] = date('Y-m-d',$item['end_time']); | 305 | $item['end_time'] = date('Y-m-d',$item['end_time']); |
318 | return $item; | 306 | return $item; |
319 | }); | 307 | }); |
320 | - $this->success('SUCCESS',$list); | 308 | + $this_list = []; |
309 | + foreach ($list as $l){ | ||
310 | + if($l['type'] == $type){ | ||
311 | + $this_list[] = $l; | ||
312 | + } | ||
313 | + } | ||
314 | + $this->success('SUCCESS',$this_list); | ||
321 | } | 315 | } |
322 | 316 | ||
323 | /** | 317 | /** |
@@ -10,6 +10,7 @@ use Think\Db; | @@ -10,6 +10,7 @@ use Think\Db; | ||
10 | class AnswerService | 10 | class AnswerService |
11 | { | 11 | { |
12 | public function answer($str){ | 12 | public function answer($str){ |
13 | + $str = trim(trim(htmlspecialchars_decode($str),'['),']'); | ||
13 | $arr_str = explode(',',$str); | 14 | $arr_str = explode(',',$str); |
14 | $question = []; | 15 | $question = []; |
15 | $start = []; | 16 | $start = []; |
@@ -18,7 +19,13 @@ class AnswerService | @@ -18,7 +19,13 @@ class AnswerService | ||
18 | $score_2 = 0; //11 | 19 | $score_2 = 0; //11 |
19 | $score_3 = 0; //12-13 | 20 | $score_3 = 0; //12-13 |
20 | $score_4 = 0; //14-15 | 21 | $score_4 = 0; //14-15 |
22 | + $question_title_count = Db::name('question')->where('delete_time',0)->where('parent_id',0)->count(); | ||
23 | + $question_this_count = count($arr_str); | ||
24 | + if($question_this_count != $question_title_count){ | ||
25 | + return false; | ||
26 | + } | ||
21 | for($i=0;$i<count($arr_str);$i++){ | 27 | for($i=0;$i<count($arr_str);$i++){ |
28 | + $arr_str[$i] = trim($arr_str[$i],'"'); | ||
22 | $arr_q = explode('-',$arr_str[$i]); | 29 | $arr_q = explode('-',$arr_str[$i]); |
23 | if(!empty($arr_q[0]) && !empty($arr_q[1])){ | 30 | if(!empty($arr_q[0]) && !empty($arr_q[1])){ |
24 | //题目 | 31 | //题目 |
@@ -29,8 +36,8 @@ class AnswerService | @@ -29,8 +36,8 @@ class AnswerService | ||
29 | $all_score +=$question_choose; | 36 | $all_score +=$question_choose; |
30 | //查看题目是否需要单独评分 | 37 | //查看题目是否需要单独评分 |
31 | if($question_title['type'] == 1){ | 38 | if($question_title['type'] == 1){ |
32 | - if(intval($question_title['min']) <= $question_choose && $question_choose <= intval($question_title['max'])){ | ||
33 | - array_push($question,['name'=>'第'.$question_title['order_id'].'题','content'=>$question_title['content']]); | 39 | + if(intval($question_title['min']) <= $question_choose && $question_choose < intval($question_title['max'])){ |
40 | + array_push($question,['name'=>'','content'=>$question_title['content']]); | ||
34 | } | 41 | } |
35 | } | 42 | } |
36 | //评星分数 | 43 | //评星分数 |
@@ -54,50 +61,57 @@ class AnswerService | @@ -54,50 +61,57 @@ class AnswerService | ||
54 | //分数归类 | 61 | //分数归类 |
55 | $answer = Db::name('answer')->where('delete_time',0)->select(); | 62 | $answer = Db::name('answer')->where('delete_time',0)->select(); |
56 | $fen = []; | 63 | $fen = []; |
57 | - $content = 0; | 64 | + $content = ''; |
65 | + | ||
58 | foreach ($answer as $an){ | 66 | foreach ($answer as $an){ |
59 | - if(intval($an['min']) < $all_score && intval($an['max']) > $all_score ) { | 67 | + if(intval($an['min']) <= $all_score && intval($an['max']) >= $all_score ) { |
60 | $fen = ['min'=>$an['min'] , 'max'=>$an['max']]; | 68 | $fen = ['min'=>$an['min'] , 'max'=>$an['max']]; |
61 | $content = $an['content']; | 69 | $content = $an['content']; |
62 | } | 70 | } |
63 | } | 71 | } |
64 | //评星 | 72 | //评星 |
65 | $type = 0; | 73 | $type = 0; |
66 | - if($all_score < 71){ | 74 | + //if($all_score < 71){ |
67 | $type = 1; | 75 | $type = 1; |
68 | if($score_1 < 18){ | 76 | if($score_1 < 18){ |
69 | - array_push($start,['num'=>1,'title'=>'知识产权情况较差','type'=>1]); | 77 | + array_push($start,['text'=>'知识产权情况','num'=>1,'title'=>'知识产权情况较差','type'=>1]); |
70 | } elseif ($score_1 >= 18 && $score_1 < 21){ | 78 | } elseif ($score_1 >= 18 && $score_1 < 21){ |
71 | - array_push($start,['num'=>2,'title'=>'知识产权情况差','type'=>1]); | 79 | + array_push($start,['text'=>'知识产权情况','num'=>2,'title'=>'知识产权情况差','type'=>1]); |
72 | } elseif ($score_1 >= 21 && $score_1 < 24){ | 80 | } elseif ($score_1 >= 21 && $score_1 < 24){ |
73 | - array_push($start,['num'=>3,'title'=>'知识产权情况一般','type'=>1]); | 81 | + array_push($start,['text'=>'知识产权情况','num'=>3,'title'=>'知识产权情况一般','type'=>1]); |
74 | } elseif ($score_1 >= 24){ | 82 | } elseif ($score_1 >= 24){ |
75 | - array_push($start,['num'=>4,'title'=>'知识产权情况优秀','type'=>1]); | 83 | + array_push($start,['text'=>'知识产权情况','num'=>4,'title'=>'知识产权情况优秀','type'=>1]); |
76 | } | 84 | } |
77 | - if($score_2 == 28){ | ||
78 | - | 85 | + if($score_2 == 28 || $score_2==27){ |
86 | + array_push($start,['text'=>'科技成果转化','num'=>4,'title'=>'科技成果转化优秀','type'=>2]); | ||
87 | + } elseif ($score_2 == 22 || $score_2 == 16){ | ||
88 | + array_push($start,['text'=>'科技成果转化','num'=>3,'title'=>'科技成果转化一般','type'=>2]); | ||
89 | + } elseif($score_2 == 10){ | ||
90 | + array_push($start,['text'=>'科技成果转化','num'=>2,'title'=>'科技成果转化较差','type'=>2]); | ||
91 | + } elseif ($score_2 == 3 || $score_2 == 0){ | ||
92 | + array_push($start,['text'=>'科技成果转化','num'=>1,'title'=>'科技成果转化差','type'=>2]); | ||
79 | } | 93 | } |
80 | if($score_3 == 18){ | 94 | if($score_3 == 18){ |
81 | - array_push($start,['num'=>4,'title'=>'企业研发组织管理水平较好','type'=>3]); | 95 | + array_push($start,['text'=>'企业研发组织管理水平','num'=>4,'title'=>'企业研发组织管理水平较好','type'=>3]); |
82 | } elseif ($score_3 == 15){ | 96 | } elseif ($score_3 == 15){ |
83 | - array_push($start,['num'=>3,'title'=>'企业研发组织管理水平好','type'=>3]); | 97 | + array_push($start,['text'=>'企业研发组织管理水平','num'=>3,'title'=>'企业研发组织管理水平好','type'=>3]); |
84 | } elseif ( $score_3 == 3){ | 98 | } elseif ( $score_3 == 3){ |
85 | - array_push($start,['num'=>2,'title'=>'企业研发组织管理水平差','type'=>3]); | 99 | + array_push($start,['text'=>'企业研发组织管理水平','num'=>2,'title'=>'企业研发组织管理水平差','type'=>3]); |
86 | } elseif ($score_3 == 0){ | 100 | } elseif ($score_3 == 0){ |
87 | - array_push($start,['num'=>1,'title'=>'企业研发组织管理水平较差','type'=>3]); | 101 | + array_push($start,['text'=>'企业研发组织管理水平','num'=>1,'title'=>'企业研发组织管理水平较差','type'=>3]); |
88 | } | 102 | } |
89 | if($score_4 >= 10){ | 103 | if($score_4 >= 10){ |
90 | - array_push($start,['num'=>4,'title'=>'财务增长情况:优秀','type'=>4]); | 104 | + array_push($start,['text'=>'财务增长情况','num'=>4,'title'=>'财务增长情况:优秀','type'=>4]); |
91 | } elseif ($score_4 <10 && $score_4 >=7) { | 105 | } elseif ($score_4 <10 && $score_4 >=7) { |
92 | - array_push($start,['num'=>3,'title'=>'财务增长情况:良好','type'=>4]); | 106 | + array_push($start,['text'=>'财务增长情况','num'=>3,'title'=>'财务增长情况:良好','type'=>4]); |
93 | } elseif ($score_4 < 7 && $score_4 >= 5){ | 107 | } elseif ($score_4 < 7 && $score_4 >= 5){ |
94 | - array_push($start,['num'=>2,'title'=>'财务增长情况:一般','type'=>4]); | 108 | + array_push($start,['text'=>'财务增长情况','num'=>2,'title'=>'财务增长情况:一般','type'=>4]); |
95 | } elseif ($score_4 <5){ | 109 | } elseif ($score_4 <5){ |
96 | - array_push($start,['num'=>1,'title'=>'财务增长情况:差','type'=>4]); | 110 | + array_push($start,['text'=>'财务增长情况','num'=>1,'title'=>'财务增长情况:差','type'=>4]); |
97 | } | 111 | } |
98 | - } | 112 | + //} |
99 | 113 | ||
100 | - return ['fen'=>$fen,'content'=>$content,'type'=>$type,'start'=>$start,'question'=>$question]; | 114 | + return ['fen'=>$fen,'content'=>$content,'type'=>$type,'start'=>$start,'question'=>$question,'all_fen'=>$all_score]; |
101 | } | 115 | } |
102 | 116 | ||
103 | } | 117 | } |
@@ -18,6 +18,41 @@ use think\Validate; | @@ -18,6 +18,41 @@ use think\Validate; | ||
18 | */ | 18 | */ |
19 | class PublicController extends RestBaseController | 19 | class PublicController extends RestBaseController |
20 | { | 20 | { |
21 | + | ||
22 | + /** | ||
23 | + * @title 首页信息接口 | ||
24 | + * @description BannerTitle | ||
25 | + * @author WeiQiang | ||
26 | + * @url /wxapp/public/index | ||
27 | + * @method POST | ||
28 | + * @return banner:顶部标语@ | ||
29 | + * @banner title:标语标题 content:标语列表@ | ||
30 | + * @content name:文字 | ||
31 | + * @return index_text:优惠券标语信息 | ||
32 | + * @return tpl:联系电话 | ||
33 | + */ | ||
34 | + public function index() | ||
35 | + { | ||
36 | + $list = Db::name('banner') | ||
37 | + ->field('title ,content') | ||
38 | + ->order('id') | ||
39 | + ->select(); | ||
40 | + $array = []; | ||
41 | + foreach ($list as $l){ | ||
42 | + $arr = explode('/',$l['content']); | ||
43 | + $content_array = []; | ||
44 | + for($i=0;$i<count($arr);$i++){ | ||
45 | + $content_array[] = ['name'=>$arr[$i]]; | ||
46 | + } | ||
47 | + array_push($array , ['title'=>$l['title'],'content'=>$content_array]); | ||
48 | + } | ||
49 | + $PublicConfig = Db::name('public_config')->where('id',1)->find(); | ||
50 | + $index_text = $PublicConfig['index_text']; | ||
51 | + $tpl = $PublicConfig['tpl']; | ||
52 | + | ||
53 | + $this->success("SUCCESS", ['banner'=>$array,'tpl'=>$tpl,'index_text'=>$index_text]); | ||
54 | + } | ||
55 | + | ||
21 | /** | 56 | /** |
22 | * @title 获取sessionKey和openid | 57 | * @title 获取sessionKey和openid |
23 | * @description 小程序登录注册 | 58 | * @description 小程序登录注册 |
@@ -51,6 +86,7 @@ class PublicController extends RestBaseController | @@ -51,6 +86,7 @@ class PublicController extends RestBaseController | ||
51 | $response = cmf_curl_get("https://api.weixin.qq.com/sns/jscode2session?appid=$appId&secret=$appSecret&js_code=$code&grant_type=authorization_code"); | 86 | $response = cmf_curl_get("https://api.weixin.qq.com/sns/jscode2session?appid=$appId&secret=$appSecret&js_code=$code&grant_type=authorization_code"); |
52 | 87 | ||
53 | $response = json_decode($response, true); | 88 | $response = json_decode($response, true); |
89 | + | ||
54 | if (!empty($response['errcode'])) { | 90 | if (!empty($response['errcode'])) { |
55 | $this->error(['code'=>'41001','msg'=>'操作失败:'.$response['errcode']]); | 91 | $this->error(['code'=>'41001','msg'=>'操作失败:'.$response['errcode']]); |
56 | } | 92 | } |
@@ -133,7 +169,7 @@ class PublicController extends RestBaseController | @@ -133,7 +169,7 @@ class PublicController extends RestBaseController | ||
133 | ->where('openid', $openid) | 169 | ->where('openid', $openid) |
134 | ->where('app_id', $appId) | 170 | ->where('app_id', $appId) |
135 | ->update($userData); | 171 | ->update($userData); |
136 | - $user_id = $this->getUserId(); | 172 | + $user_id = $findThirdPartyUser['user_id']; |
137 | Db::name("user") | 173 | Db::name("user") |
138 | ->where('id',$user_id) | 174 | ->where('id',$user_id) |
139 | ->update([ | 175 | ->update([ |
@@ -177,8 +177,11 @@ class CouponController extends AdminBaseController | @@ -177,8 +177,11 @@ class CouponController extends AdminBaseController | ||
177 | { | 177 | { |
178 | $rquest = $this->request->param(); | 178 | $rquest = $this->request->param(); |
179 | $where = []; | 179 | $where = []; |
180 | + if(!empty($rquest['nickname'])){ | ||
181 | + $where['u.user_nickname'] = ['like',"%$rquest[nickname]%"]; | ||
182 | + } | ||
180 | if(!empty($rquest['mobile'])){ | 183 | if(!empty($rquest['mobile'])){ |
181 | - $where['u.mobile'] = $rquest['mobile']; | 184 | + $where['u.mobile'] = ['like',"%$rquest[mobile]%"]; |
182 | } | 185 | } |
183 | $Coupon = new CouponModel(); | 186 | $Coupon = new CouponModel(); |
184 | $list = $Coupon->CouponUser($where,$rquest); | 187 | $list = $Coupon->CouponUser($where,$rquest); |
app/admin/controller/StartController.php
0 → 100644
1 | +<?php | ||
2 | +// +---------------------------------------------------------------------- | ||
3 | +// | 答题结果标星模块 | ||
4 | +// +---------------------------------------------------------------------- | ||
5 | +// | Author: 魏强 | ||
6 | +// +---------------------------------------------------------------------- | ||
7 | +namespace app\admin\controller; | ||
8 | + | ||
9 | +use cmf\controller\AdminBaseController; | ||
10 | +use think\Db; | ||
11 | + | ||
12 | +/** | ||
13 | + * Class StartController | ||
14 | + * @package app\admin\controller | ||
15 | + * @adminMenuRoot( | ||
16 | + * 'name' => '标星规则', | ||
17 | + * 'action' => 'index', | ||
18 | + * 'parent' => '', | ||
19 | + * 'display'=> true, | ||
20 | + * 'order' => 100, | ||
21 | + * 'icon' => 'star', | ||
22 | + * 'remark' => '标星规则' | ||
23 | + * ) | ||
24 | + */ | ||
25 | +class StartController extends AdminBaseController | ||
26 | +{ | ||
27 | + | ||
28 | + public function index() | ||
29 | + { | ||
30 | + return $this->fetch(); | ||
31 | + } | ||
32 | + | ||
33 | +} |
1 | +<?php | ||
2 | +// +---------------------------------------------------------------------- | ||
3 | +// | 用户答题结果模块 | ||
4 | +// +---------------------------------------------------------------------- | ||
5 | +// | Author: 魏强 | ||
6 | +// +---------------------------------------------------------------------- | ||
7 | +namespace app\admin\controller; | ||
8 | + | ||
9 | +use cmf\controller\AdminBaseController; | ||
10 | +use think\Db; | ||
11 | +use func\func; | ||
12 | + | ||
13 | +/** | ||
14 | + * Class UserAnswerController | ||
15 | + * @package app\admin\controller | ||
16 | + * @adminMenuRoot( | ||
17 | + * 'name' => '用户答题列表', | ||
18 | + * 'action' => 'index', | ||
19 | + * 'parent' => '', | ||
20 | + * 'display'=> true, | ||
21 | + * 'order' => 100, | ||
22 | + * 'icon' => 'pencil', | ||
23 | + * 'remark' => '用户答题列表' | ||
24 | + * ) | ||
25 | + */ | ||
26 | +class UserAnswerController extends AdminBaseController | ||
27 | +{ | ||
28 | + | ||
29 | + public function index() | ||
30 | + { | ||
31 | + $request = $this->request->param(); | ||
32 | + $where = []; | ||
33 | + if(!empty($request['mobile'])) { | ||
34 | + $where['u.mobile'] = ['like', "%$request[mobile]%"]; | ||
35 | + } | ||
36 | + !empty($request['start_time']) ? $start_time = $request['start_time'] : $start_time = 0; | ||
37 | + !empty($request['end_time']) ? $end_time = $request['end_time'] : $end_time = time(); | ||
38 | + $list = Db::name('user_answer') | ||
39 | + ->alias('ua') | ||
40 | + ->field('ua.* ,u.user_nickname ,u.mobile') | ||
41 | + ->join('user u','ua.user_id = u.id') | ||
42 | + ->where($where) | ||
43 | + ->whereTime('ua.create_time','between',[$start_time,$end_time]) | ||
44 | + ->order('ua.create_time','DESC') | ||
45 | + ->paginate(2,false,['query'=>$request]) | ||
46 | + ->each(function ($item){ | ||
47 | + //用户当前优惠券情况 | ||
48 | + $user_coupon = Db::name('user_coupon') | ||
49 | + ->alias('uc') | ||
50 | + ->field('c.title ,uc.type') | ||
51 | + ->join('coupon c','uc.coupon_id = c.id') | ||
52 | + ->where('uc.user_id',$item['user_id']) | ||
53 | + ->where('uc.delete_time',0) | ||
54 | + ->select(); | ||
55 | + count($user_coupon) != 0 ? $item['user_coupon_text'] = '' : $item['user_coupon_text'] = '无优惠券'; | ||
56 | + foreach($user_coupon as $uc){ | ||
57 | + $uc['type'] == 0 ? $user_coupon_type_text = '未使用' : $user_coupon_type_text = '已使用'; | ||
58 | + $item['user_coupon_text'] .= $uc['title']."($user_coupon_type_text) "; | ||
59 | + } | ||
60 | + //获取题目信息 | ||
61 | + $str = trim(trim(htmlspecialchars_decode($item['str']),'['),']'); | ||
62 | + $arr_str = explode(',',$str); | ||
63 | + $item['question_text'] = []; | ||
64 | + $all_score = 0; | ||
65 | + //循环查询每道题目的内容 | ||
66 | + for($i=0;$i<count($arr_str);$i++) { | ||
67 | + $arr_str[$i] = trim($arr_str[$i], '"'); | ||
68 | + $arr_q = explode('-', $arr_str[$i]); | ||
69 | + if (!empty($arr_q[0]) && !empty($arr_q[1])) { | ||
70 | + //题目 | ||
71 | + $question_title = Db::name('question')->where('id', $arr_q[0])->find(); | ||
72 | + //选项 | ||
73 | + $question_choose = Db::name('question')->where('id', $arr_q[1])->find(); | ||
74 | + $all_score +=$question_choose['score']; | ||
75 | + $item['question_text'][] = [ | ||
76 | + 'order'=>$question_title['order_id'], | ||
77 | + 'title'=>$question_choose['title'], | ||
78 | + 'score'=>$question_choose['score'] | ||
79 | + ]; | ||
80 | + | ||
81 | + } | ||
82 | + } | ||
83 | + $item['all_score'] = $all_score; | ||
84 | + return $item; | ||
85 | + }); | ||
86 | + $this->assign('page',$list->render()); | ||
87 | + $this->assign('list', $list); | ||
88 | + return $this->fetch(); | ||
89 | + } | ||
90 | + | ||
91 | + /** | ||
92 | + * 导出答题结果 | ||
93 | + * @adminMenu( | ||
94 | + * 'name' => '导出答题结果', | ||
95 | + * 'parent' => 'index', | ||
96 | + * 'display'=> false, | ||
97 | + * 'hasView'=> false, | ||
98 | + * 'order' => 1000, | ||
99 | + * 'icon' => '', | ||
100 | + * 'remark' => '导出答题结果', | ||
101 | + * 'param' => '' | ||
102 | + * ) | ||
103 | + */ | ||
104 | + public function Exl(){ | ||
105 | + $request = $this->request->param(); | ||
106 | + $where = []; | ||
107 | + if(!empty($request['mobile'])) { | ||
108 | + $where['u.mobile'] = ['like', "%$request[mobile]%"]; | ||
109 | + } | ||
110 | + !empty($request['start_time']) ? $start_time = $request['start_time'] : $start_time = 0; | ||
111 | + !empty($request['end_time']) ? $end_time = $request['end_time'] : $end_time = time(); | ||
112 | + $list = Db::name('user_answer') | ||
113 | + ->alias('ua') | ||
114 | + ->field('ua.* ,u.user_nickname ,u.mobile') | ||
115 | + ->join('user u','ua.user_id = u.id') | ||
116 | + ->where($where) | ||
117 | + ->whereTime('ua.create_time','between',[$start_time,$end_time]) | ||
118 | + ->order('u.create_time','DESC') | ||
119 | + ->select() | ||
120 | + ->each(function ($item){ | ||
121 | + //用户当前优惠券情况 | ||
122 | + $user_coupon = Db::name('user_coupon') | ||
123 | + ->alias('uc') | ||
124 | + ->field('c.title ,uc.type') | ||
125 | + ->join('coupon c','uc.coupon_id = c.id') | ||
126 | + ->where('uc.user_id',$item['user_id']) | ||
127 | + ->where('uc.delete_time',0) | ||
128 | + ->select(); | ||
129 | + count($user_coupon) != 0 ? $item['user_coupon_text'] = '' : $item['user_coupon_text'] = '无优惠券'; | ||
130 | + foreach($user_coupon as $uc){ | ||
131 | + $uc['type'] == 0 ? $user_coupon_type_text = '未使用' : $user_coupon_type_text = '已使用'; | ||
132 | + $item['user_coupon_text'] .= $uc['title']."($user_coupon_type_text) "; | ||
133 | + } | ||
134 | + //获取题目信息 | ||
135 | + $str = trim(trim(htmlspecialchars_decode($item['str']),'['),']'); | ||
136 | + $arr_str = explode(',',$str); | ||
137 | + $item['question_text'] = []; | ||
138 | + $all_score = 0; | ||
139 | + for($i=0;$i<count($arr_str);$i++) { | ||
140 | + $arr_str[$i] = trim($arr_str[$i], '"'); | ||
141 | + $arr_q = explode('-', $arr_str[$i]); | ||
142 | + if (!empty($arr_q[0]) && !empty($arr_q[1])) { | ||
143 | + //题目 | ||
144 | + $question_title = Db::name('question')->where('id', $arr_q[0])->find(); | ||
145 | + //选项 | ||
146 | + $question_choose = Db::name('question')->where('id', $arr_q[1])->find(); | ||
147 | + $all_score +=$question_choose['score']; | ||
148 | + $item['question_text'][] = [ | ||
149 | + 'order'=>$question_title['order_id'], | ||
150 | + 'title'=>$question_choose['title'], | ||
151 | + 'score'=>$question_choose['score'] | ||
152 | + ]; | ||
153 | + | ||
154 | + } | ||
155 | + } | ||
156 | + $item['all_score'] = $all_score; | ||
157 | + return $item; | ||
158 | + }); | ||
159 | + $exl = new func(); | ||
160 | + $exl_title = ['用户昵称','用户电话','题目编号','用户答案','答题分数','答题总分数','当前优惠券信息','答题时间']; | ||
161 | + $exl_dis = []; | ||
162 | + foreach ($list as $li){ | ||
163 | + foreach ($li['question_text'] as $qt){ | ||
164 | + $exl_dis[] = [ | ||
165 | + $exl->filterEmoji($li['user_nickname']), | ||
166 | + $li['mobile'], | ||
167 | + $qt['order'], | ||
168 | + $qt['title'], | ||
169 | + $qt['score'], | ||
170 | + $li['all_score'], | ||
171 | + $li['user_coupon_text'], | ||
172 | + date('Y-m-d H:i',$li['create_time']) | ||
173 | + ]; | ||
174 | + } | ||
175 | + } | ||
176 | + $exl->exportExcel($exl_title, $exl_dis, '用户答题列表', './', true); | ||
177 | + } | ||
178 | + | ||
179 | + | ||
180 | + | ||
181 | + | ||
182 | +} |
@@ -26,6 +26,8 @@ class QuestionValidate extends Validate | @@ -26,6 +26,8 @@ class QuestionValidate extends Validate | ||
26 | } | 26 | } |
27 | else if(empty($post['hint_content'])){ | 27 | else if(empty($post['hint_content'])){ |
28 | return '提示信息内容不能为空'; | 28 | return '提示信息内容不能为空'; |
29 | + } elseif(empty($post['hint_text'])){ | ||
30 | + return '提示标注不能为空'; | ||
29 | } else { | 31 | } else { |
30 | return true; | 32 | return true; |
31 | } | 33 | } |
@@ -74,6 +74,8 @@ return array ( | @@ -74,6 +74,8 @@ return array ( | ||
74 | 'ADMIN_PUBLICCONFIG_PUBLICCONFIG' => '平台基本信息', | 74 | 'ADMIN_PUBLICCONFIG_PUBLICCONFIG' => '平台基本信息', |
75 | 'ADMIN_PUBLICCONFIG_PUBLICCONFIGPOST' => '平台基本信息提交', | 75 | 'ADMIN_PUBLICCONFIG_PUBLICCONFIGPOST' => '平台基本信息提交', |
76 | 'ADMIN_QUESTION_DEFAULT' => '题目管理', | 76 | 'ADMIN_QUESTION_DEFAULT' => '题目管理', |
77 | + 'ADMIN_QUESTION_IMAGES' => '问题背景图', | ||
78 | + 'ADMIN_QUESTION_IMAGESPOST' => '问题背景图提交', | ||
77 | 'ADMIN_QUESTION_LISTORDER' => '评分题目排序', | 79 | 'ADMIN_QUESTION_LISTORDER' => '评分题目排序', |
78 | 'ADMIN_QUESTION_QUALIFICATION' => '资格题目', | 80 | 'ADMIN_QUESTION_QUALIFICATION' => '资格题目', |
79 | 'ADMIN_QUESTION_QUALIFICATIONADD' => '添加资格题目', | 81 | 'ADMIN_QUESTION_QUALIFICATIONADD' => '添加资格题目', |
@@ -147,6 +149,8 @@ return array ( | @@ -147,6 +149,8 @@ return array ( | ||
147 | 'ADMIN_THEME_SETTINGPOST' => '模板文件编辑提交保存', | 149 | 'ADMIN_THEME_SETTINGPOST' => '模板文件编辑提交保存', |
148 | 'ADMIN_THEME_UNINSTALL' => '卸载模板', | 150 | 'ADMIN_THEME_UNINSTALL' => '卸载模板', |
149 | 'ADMIN_THEME_UPDATE' => '模板更新', | 151 | 'ADMIN_THEME_UPDATE' => '模板更新', |
152 | + 'ADMIN_TICKLING_DELETE' => '删除反馈意见', | ||
153 | + 'ADMIN_TICKLING_INDEX' => '意见反馈列表', | ||
150 | 'ADMIN_USER_ADD' => '管理员添加', | 154 | 'ADMIN_USER_ADD' => '管理员添加', |
151 | 'ADMIN_USER_ADDPOST' => '管理员添加提交', | 155 | 'ADMIN_USER_ADDPOST' => '管理员添加提交', |
152 | 'ADMIN_USER_BAN' => '停用管理员', | 156 | 'ADMIN_USER_BAN' => '停用管理员', |
public/defen_img@2x.png
0 → 100644
10.9 KB
public/gerenzhongxin_bg@2x.png
0 → 100644
14.3 KB
public/gongxi_img@2x.png
0 → 100644
54.7 KB
public/jieguo_bg@2x.png
0 → 100644
4.0 KB
public/qidongye_bg@2x.png
0 → 100644
28.8 KB
public/shouye_bg@2x.png
0 → 100644
59.7 KB
@@ -6,6 +6,8 @@ | @@ -6,6 +6,8 @@ | ||
6 | <li class="active"><a href="#">用户优惠券列表</a></li> | 6 | <li class="active"><a href="#">用户优惠券列表</a></li> |
7 | </ul> | 7 | </ul> |
8 | <form class="well form-inline margin-top-20" method="post" action="{:url('Coupon/user')}"> | 8 | <form class="well form-inline margin-top-20" method="post" action="{:url('Coupon/user')}"> |
9 | + 用户昵称: | ||
10 | + <input type="text" class="form-control" name="nickname" style="width: 180px;" value="{:input('request.nickname/s','')}" placeholder="请输入用户昵称"> | ||
9 | 用户电话: | 11 | 用户电话: |
10 | <input type="number" class="form-control" name="mobile" style="width: 180px;" value="{:input('request.mobile/s','')}" placeholder="请输入用户电话"> | 12 | <input type="number" class="form-control" name="mobile" style="width: 180px;" value="{:input('request.mobile/s','')}" placeholder="请输入用户电话"> |
11 | <input type="submit" class="btn btn-primary" value="搜索"/> | 13 | <input type="submit" class="btn btn-primary" value="搜索"/> |
@@ -8,9 +8,9 @@ | @@ -8,9 +8,9 @@ | ||
8 | </ul> | 8 | </ul> |
9 | <form method="post" class="form-horizontal js-ajax-form margin-top-20" action="{:url('PublicConfig/bannerAddPost')}"> | 9 | <form method="post" class="form-horizontal js-ajax-form margin-top-20" action="{:url('PublicConfig/bannerAddPost')}"> |
10 | <div id="fen1" class="form-group"> | 10 | <div id="fen1" class="form-group"> |
11 | - <label class="col-sm-2 control-label"><span class="form-required">*</span>标题</label> | 11 | + <label class="col-sm-2 control-label">标题</label> |
12 | <div class="col-md-6 col-sm-10"> | 12 | <div class="col-md-6 col-sm-10"> |
13 | - <input type="text" class="form-control" name="title" required> | 13 | + <input type="text" class="form-control" name="title" > |
14 | </div> | 14 | </div> |
15 | </div> | 15 | </div> |
16 | <div class="form-group"> | 16 | <div class="form-group"> |
@@ -9,9 +9,9 @@ | @@ -9,9 +9,9 @@ | ||
9 | <form method="post" class="form-horizontal js-ajax-form margin-top-20" action="{:url('PublicConfig/bannerEditPost')}"> | 9 | <form method="post" class="form-horizontal js-ajax-form margin-top-20" action="{:url('PublicConfig/bannerEditPost')}"> |
10 | <input type="hidden" name="id" value="{$edit.id}"> | 10 | <input type="hidden" name="id" value="{$edit.id}"> |
11 | <div id="fen1" class="form-group"> | 11 | <div id="fen1" class="form-group"> |
12 | - <label class="col-sm-2 control-label"><span class="form-required">*</span>标题</label> | 12 | + <label class="col-sm-2 control-label">标题</label> |
13 | <div class="col-md-6 col-sm-10"> | 13 | <div class="col-md-6 col-sm-10"> |
14 | - <input type="text" class="form-control" name="title" required value="{$edit.title}"> | 14 | + <input type="text" class="form-control" name="title" value="{$edit.title}"> |
15 | </div> | 15 | </div> |
16 | </div> | 16 | </div> |
17 | <div class="form-group"> | 17 | <div class="form-group"> |
@@ -43,6 +43,12 @@ | @@ -43,6 +43,12 @@ | ||
43 | </td> | 43 | </td> |
44 | </tr> | 44 | </tr> |
45 | <tr> | 45 | <tr> |
46 | + <th width="100">客服电话<span class="form-required">*</span></th> | ||
47 | + <td> | ||
48 | + <input type="text" class="form-control" required name="mobile" value="{$mobile|default=''}"> | ||
49 | + </td> | ||
50 | + </tr> | ||
51 | + <tr> | ||
46 | <th width="100">客服QQ<span class="form-required">*</span></th> | 52 | <th width="100">客服QQ<span class="form-required">*</span></th> |
47 | <td> | 53 | <td> |
48 | <input type="text" class="form-control" required name="qq" value="{$qq|default=''}"> | 54 | <input type="text" class="form-control" required name="qq" value="{$qq|default=''}"> |
@@ -99,7 +105,7 @@ | @@ -99,7 +105,7 @@ | ||
99 | </table> | 105 | </table> |
100 | <div class="form-group"> | 106 | <div class="form-group"> |
101 | <div class="col-sm-offset-2 col-sm-10"> | 107 | <div class="col-sm-offset-2 col-sm-10"> |
102 | - <button type="submit" class="btn btn-primary js-ajax-submit">{:lang('ADD')}</button> | 108 | + <button type="submit" class="btn btn-primary js-ajax-submit">保存</button> |
103 | </div> | 109 | </div> |
104 | </div> | 110 | </div> |
105 | </div> | 111 | </div> |
@@ -14,8 +14,8 @@ | @@ -14,8 +14,8 @@ | ||
14 | <th width="50">ID</th> | 14 | <th width="50">ID</th> |
15 | <th>题目内容</th> | 15 | <th>题目内容</th> |
16 | <th>选错提示信息</th> | 16 | <th>选错提示信息</th> |
17 | - <th>排序</th> | ||
18 | - <th>正确选项</th> | 17 | + <th width="50">题号</th> |
18 | + <th width="80">正确选项</th> | ||
19 | <th width="130">{:lang('ACTIONS')}</th> | 19 | <th width="130">{:lang('ACTIONS')}</th> |
20 | </tr> | 20 | </tr> |
21 | </thead> | 21 | </thead> |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | </div> | 27 | </div> |
28 | </div> | 28 | </div> |
29 | <div class="form-group"> | 29 | <div class="form-group"> |
30 | - <label class="col-sm-2 control-label"><span class="form-required">*</span>排序</label> | 30 | + <label class="col-sm-2 control-label"><span class="form-required">*</span>题号</label> |
31 | <div class="col-md-6 col-sm-10"> | 31 | <div class="col-md-6 col-sm-10"> |
32 | <input type="number" class="form-control" id="order_id" name="order_id" placeholder="由小到大排序"> | 32 | <input type="number" class="form-control" id="order_id" name="order_id" placeholder="由小到大排序"> |
33 | </div> | 33 | </div> |
@@ -28,7 +28,7 @@ | @@ -28,7 +28,7 @@ | ||
28 | </div> | 28 | </div> |
29 | </div> | 29 | </div> |
30 | <div class="form-group"> | 30 | <div class="form-group"> |
31 | - <label class="col-sm-2 control-label"><span class="form-required">*</span>排序</label> | 31 | + <label class="col-sm-2 control-label"><span class="form-required">*</span>题号</label> |
32 | <div class="col-md-6 col-sm-10"> | 32 | <div class="col-md-6 col-sm-10"> |
33 | <input type="number" class="form-control" id="order_id" name="order_id" value="{$edit.order_id}" placeholder="由小到大排序"> | 33 | <input type="number" class="form-control" id="order_id" name="order_id" value="{$edit.order_id}" placeholder="由小到大排序"> |
34 | </div> | 34 | </div> |
@@ -52,6 +52,12 @@ | @@ -52,6 +52,12 @@ | ||
52 | <input type="radio" name="hint_type" value="1">有提示信息 | 52 | <input type="radio" name="hint_type" value="1">有提示信息 |
53 | </div> | 53 | </div> |
54 | </div> | 54 | </div> |
55 | + <div id="ti3" class="form-group hidden"> | ||
56 | + <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标题</label> | ||
57 | + <div class="col-md-6 col-sm-10"> | ||
58 | + <input type="text" class="form-control" name="hint_text"> | ||
59 | + </div> | ||
60 | + </div> | ||
55 | <div id="ti1" class="form-group hidden"> | 61 | <div id="ti1" class="form-group hidden"> |
56 | <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标题</label> | 62 | <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标题</label> |
57 | <div class="col-md-6 col-sm-10"> | 63 | <div class="col-md-6 col-sm-10"> |
@@ -102,6 +108,7 @@ | @@ -102,6 +108,7 @@ | ||
102 | $('#ti').attr('class','form-group hidden'); | 108 | $('#ti').attr('class','form-group hidden'); |
103 | $('#ti1').attr('class','form-group hidden'); | 109 | $('#ti1').attr('class','form-group hidden'); |
104 | $('#ti2').attr('class','form-group hidden'); | 110 | $('#ti2').attr('class','form-group hidden'); |
111 | + $('#ti3').attr('class','form-group hidden'); | ||
105 | } | 112 | } |
106 | //动态改变页面信息 | 113 | //动态改变页面信息 |
107 | $('#parent_id').on('change',function () { | 114 | $('#parent_id').on('change',function () { |
@@ -123,6 +130,7 @@ | @@ -123,6 +130,7 @@ | ||
123 | $('#ti').attr('class','form-group hidden'); | 130 | $('#ti').attr('class','form-group hidden'); |
124 | $('#ti1').attr('class','form-group hidden'); | 131 | $('#ti1').attr('class','form-group hidden'); |
125 | $('#ti2').attr('class','form-group hidden'); | 132 | $('#ti2').attr('class','form-group hidden'); |
133 | + $('#ti3').attr('class','form-group hidden'); | ||
126 | $('input[type=radio]').removeAttr('checked'); | 134 | $('input[type=radio]').removeAttr('checked'); |
127 | $('#thishint').prop('checked',true); | 135 | $('#thishint').prop('checked',true); |
128 | $('#thistype').prop('checked',true); | 136 | $('#thistype').prop('checked',true); |
@@ -149,9 +157,11 @@ | @@ -149,9 +157,11 @@ | ||
149 | if(ti == 0){ | 157 | if(ti == 0){ |
150 | $('#ti1').attr('class','form-group hidden'); | 158 | $('#ti1').attr('class','form-group hidden'); |
151 | $('#ti2').attr('class','form-group hidden'); | 159 | $('#ti2').attr('class','form-group hidden'); |
160 | + $('#ti3').attr('class','form-group hidden'); | ||
152 | } else { | 161 | } else { |
153 | $('#ti1').attr('class','form-group'); | 162 | $('#ti1').attr('class','form-group'); |
154 | $('#ti2').attr('class','form-group'); | 163 | $('#ti2').attr('class','form-group'); |
164 | + $('#ti3').attr('class','form-group'); | ||
155 | } | 165 | } |
156 | }) | 166 | }) |
157 | 167 |
@@ -53,6 +53,12 @@ | @@ -53,6 +53,12 @@ | ||
53 | <input type="radio" name="hint_type" value="1" <eq name="$edit.hint_type" value="1">checked</eq> >有提示信息 | 53 | <input type="radio" name="hint_type" value="1" <eq name="$edit.hint_type" value="1">checked</eq> >有提示信息 |
54 | </div> | 54 | </div> |
55 | </div> | 55 | </div> |
56 | + <div id="ti3" class="form-group <eq name="$edit.hint_type" value="0">hidden</eq> "> | ||
57 | + <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标注</label> | ||
58 | + <div class="col-md-6 col-sm-10"> | ||
59 | + <input type="text" class="form-control" name="hint_text" value="{$edit.hint_text}"> | ||
60 | + </div> | ||
61 | + </div> | ||
56 | <div id="ti1" class="form-group <eq name="$edit.hint_type" value="0">hidden</eq> "> | 62 | <div id="ti1" class="form-group <eq name="$edit.hint_type" value="0">hidden</eq> "> |
57 | <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标题</label> | 63 | <label class="col-sm-2 control-label"><span class="form-required">*</span>提示信息标题</label> |
58 | <div class="col-md-6 col-sm-10"> | 64 | <div class="col-md-6 col-sm-10"> |
@@ -103,6 +109,7 @@ | @@ -103,6 +109,7 @@ | ||
103 | $('#ti').attr('class','form-group hidden'); | 109 | $('#ti').attr('class','form-group hidden'); |
104 | $('#ti1').attr('class','form-group hidden'); | 110 | $('#ti1').attr('class','form-group hidden'); |
105 | $('#ti2').attr('class','form-group hidden'); | 111 | $('#ti2').attr('class','form-group hidden'); |
112 | + $('#ti3').attr('class','form-group hidden'); | ||
106 | } | 113 | } |
107 | //动态改变页面信息 | 114 | //动态改变页面信息 |
108 | $('#parent_id').on('change',function () { | 115 | $('#parent_id').on('change',function () { |
@@ -124,6 +131,7 @@ | @@ -124,6 +131,7 @@ | ||
124 | $('#ti').attr('class','form-group hidden'); | 131 | $('#ti').attr('class','form-group hidden'); |
125 | $('#ti1').attr('class','form-group hidden'); | 132 | $('#ti1').attr('class','form-group hidden'); |
126 | $('#ti2').attr('class','form-group hidden'); | 133 | $('#ti2').attr('class','form-group hidden'); |
134 | + $('#ti3').attr('class','form-group hidden'); | ||
127 | $('input[type=radio]').removeAttr('checked'); | 135 | $('input[type=radio]').removeAttr('checked'); |
128 | $('#thishint').prop('checked',true); | 136 | $('#thishint').prop('checked',true); |
129 | $('#thistype').prop('checked',true); | 137 | $('#thistype').prop('checked',true); |
@@ -150,9 +158,11 @@ | @@ -150,9 +158,11 @@ | ||
150 | if(ti == 0){ | 158 | if(ti == 0){ |
151 | $('#ti1').attr('class','form-group hidden'); | 159 | $('#ti1').attr('class','form-group hidden'); |
152 | $('#ti2').attr('class','form-group hidden'); | 160 | $('#ti2').attr('class','form-group hidden'); |
161 | + $('#ti3').attr('class','form-group hidden'); | ||
153 | } else { | 162 | } else { |
154 | $('#ti1').attr('class','form-group'); | 163 | $('#ti1').attr('class','form-group'); |
155 | $('#ti2').attr('class','form-group'); | 164 | $('#ti2').attr('class','form-group'); |
165 | + $('#ti3').attr('class','form-group'); | ||
156 | } | 166 | } |
157 | }) | 167 | }) |
158 | 168 |
1 | +<include file="public@header" /> | ||
2 | +</head> | ||
3 | +<body> | ||
4 | +<div class="wrap js-check-wrap"> | ||
5 | + <ul class="nav nav-tabs"> | ||
6 | + <li class="active"><a href="#">标星规则</a></li> | ||
7 | + </ul> | ||
8 | + <!--<form class="well form-inline margin-top-20" method="post" action="{:url('User/index')}">--> | ||
9 | + <!--</form>--> | ||
10 | + <table class="table table-hover table-bordered"> | ||
11 | + <thead> | ||
12 | + <tr> | ||
13 | + <th>标星分类</th> | ||
14 | + <th>包含题目</th> | ||
15 | + <th>分数区间</th> | ||
16 | + <th>标星数量</th> | ||
17 | + <th>提示内容</th> | ||
18 | + </tr> | ||
19 | + </thead> | ||
20 | + <tbody> | ||
21 | + <tr> | ||
22 | + <td rowspan="4">知识产权情况</td> | ||
23 | + <td rowspan="4">第八题、第九题、第十题</td> | ||
24 | + <td>大于等于24分</td> | ||
25 | + <td>4星</td> | ||
26 | + <td>知识产权情况优秀</td> | ||
27 | + </tr> | ||
28 | + <tr> | ||
29 | + <td>小于24分并且大于等于21分</td> | ||
30 | + <td>3星</td> | ||
31 | + <td>知识产权情况一般</td> | ||
32 | + </tr> | ||
33 | + <tr> | ||
34 | + <td>小于21分并且大于等于18分</td> | ||
35 | + <td>2星</td> | ||
36 | + <td>知识产权情况差</td> | ||
37 | + </tr> | ||
38 | + <tr> | ||
39 | + <td>小于18分</td> | ||
40 | + <td>1星</td> | ||
41 | + <td>知识产权情况较差</td> | ||
42 | + </tr> | ||
43 | + | ||
44 | + <tr> | ||
45 | + <td rowspan="4">科技成果转化</td> | ||
46 | + <td rowspan="4">第十一题</td> | ||
47 | + <td>等于28分或者等于27分</td> | ||
48 | + <td>4星</td> | ||
49 | + <td>科技成果转化优秀</td> | ||
50 | + </tr> | ||
51 | + <tr> | ||
52 | + <td>等于22分或者等于16分</td> | ||
53 | + <td>3星</td> | ||
54 | + <td>科技成果转化一般</td> | ||
55 | + </tr> | ||
56 | + <tr> | ||
57 | + <td>等于10分</td> | ||
58 | + <td>2星</td> | ||
59 | + <td>科技成果转化较差</td> | ||
60 | + </tr> | ||
61 | + <tr> | ||
62 | + <td>等于3分或者等于0分</td> | ||
63 | + <td>1星</td> | ||
64 | + <td>科技成果转化差</td> | ||
65 | + </tr> | ||
66 | + | ||
67 | + <tr> | ||
68 | + <td rowspan="4">企业研发组织管理水平</td> | ||
69 | + <td rowspan="4">第十二题、第十三题</td> | ||
70 | + <td>等于18分</td> | ||
71 | + <td>4星</td> | ||
72 | + <td>企业研发组织管理水平较好</td> | ||
73 | + </tr> | ||
74 | + <tr> | ||
75 | + <td>等于15分</td> | ||
76 | + <td>3星</td> | ||
77 | + <td>企业研发组织管理水平好</td> | ||
78 | + </tr> | ||
79 | + <tr> | ||
80 | + <td>等于3分</td> | ||
81 | + <td>2星</td> | ||
82 | + <td>企业研发组织管理水平差</td> | ||
83 | + </tr> | ||
84 | + <tr> | ||
85 | + <td>等于0分</td> | ||
86 | + <td>1星</td> | ||
87 | + <td>企业研发组织管理水平较差</td> | ||
88 | + </tr> | ||
89 | + | ||
90 | + <tr> | ||
91 | + <td rowspan="4">财务增长情况</td> | ||
92 | + <td rowspan="4">第十四题、第十五题</td> | ||
93 | + <td>大于等于10分</td> | ||
94 | + <td>4星</td> | ||
95 | + <td>财务增长情况:优秀</td> | ||
96 | + </tr> | ||
97 | + <tr> | ||
98 | + <td>小于10分并且大于等于7分</td> | ||
99 | + <td>3星</td> | ||
100 | + <td>财务增长情况:良好</td> | ||
101 | + </tr> | ||
102 | + <tr> | ||
103 | + <td>小于7分并且大于等于5分</td> | ||
104 | + <td>2星</td> | ||
105 | + <td>财务增长情况:一般</td> | ||
106 | + </tr> | ||
107 | + <tr> | ||
108 | + <td>小于5分</td> | ||
109 | + <td>1星</td> | ||
110 | + <td>财务增长情况:差</td> | ||
111 | + </tr> | ||
112 | + </tbody> | ||
113 | + </table> | ||
114 | +</div> | ||
115 | +<script src="__STATIC__/js/admin.js"></script> | ||
116 | +</body> | ||
117 | +</html> |
@@ -11,10 +11,10 @@ | @@ -11,10 +11,10 @@ | ||
11 | <thead> | 11 | <thead> |
12 | <tr> | 12 | <tr> |
13 | <th width="50">ID</th> | 13 | <th width="50">ID</th> |
14 | - <th>用户昵称</th> | 14 | + <th width="150">用户昵称</th> |
15 | <th>用户手机</th> | 15 | <th>用户手机</th> |
16 | <th>留言内容</th> | 16 | <th>留言内容</th> |
17 | - <th>留言时间</th> | 17 | + <th width="120">留言时间</th> |
18 | <th width="50">{:lang('ACTIONS')}</th> | 18 | <th width="50">{:lang('ACTIONS')}</th> |
19 | </tr> | 19 | </tr> |
20 | </thead> | 20 | </thead> |
@@ -25,7 +25,7 @@ | @@ -25,7 +25,7 @@ | ||
25 | <td>{$vo.user_nickname}</td> | 25 | <td>{$vo.user_nickname}</td> |
26 | <td>{$vo.mobile}</td> | 26 | <td>{$vo.mobile}</td> |
27 | <td>{$vo.content}</td> | 27 | <td>{$vo.content}</td> |
28 | - <td>{:date('Y-m-d',$vo.create_time)}</td> | 28 | + <td>{:date('Y-m-d H:i',$vo.create_time)}</td> |
29 | <td> | 29 | <td> |
30 | <a class="js-ajax-delete" href="{:url('Tickling/delete',array('id'=>$vo['id']))}">{:lang('DELETE')}</a> | 30 | <a class="js-ajax-delete" href="{:url('Tickling/delete',array('id'=>$vo['id']))}">{:lang('DELETE')}</a> |
31 | </td> | 31 | </td> |
1 | +<include file="public@header" /> | ||
2 | +</head> | ||
3 | +<body> | ||
4 | +<div class="wrap js-check-wrap"> | ||
5 | + <ul class="nav nav-tabs"> | ||
6 | + <li class="active"><a href="###">用户答题列表</a></li> | ||
7 | + </ul> | ||
8 | + <form class="well form-inline margin-top-20" method="post" action="{:url('UserAnswer/index')}"> | ||
9 | + 用户电话: | ||
10 | + <input type="text" class="form-control" name="mobile" style="width: 140px;" value="{:input('mobile','')}" placeholder="请输入用户电话"> | ||
11 | + 时间: | ||
12 | + <input type="text" class="form-control js-bootstrap-datetime" name="start_time" | ||
13 | + value="{:input('start_time','')}" | ||
14 | + style="width: 140px;" autocomplete="off">- | ||
15 | + <input type="text" class="form-control js-bootstrap-datetime" name="end_time" | ||
16 | + value="{:input('end_time','')}" | ||
17 | + style="width: 140px;" autocomplete="off"> | ||
18 | + <input type="submit" class="btn btn-primary" value="搜索" /> | ||
19 | + <a class="btn btn-danger" href="{:url('UserAnswer/index')}">清空</a> | ||
20 | + <a class="btn btn-primary" href="###" onclick="openexl()">导出</a> | ||
21 | + </form> | ||
22 | + <table class="table table-hover table-bordered"> | ||
23 | + <thead> | ||
24 | + <tr> | ||
25 | + <th>用户昵称</th> | ||
26 | + <th>用户电话</th> | ||
27 | + <th>题目编号</th> | ||
28 | + <th>用户答案</th> | ||
29 | + <th>答题分数</th> | ||
30 | + <th>答题总分数</th> | ||
31 | + <th>当前优惠券信息</th> | ||
32 | + <th>答题时间</th> | ||
33 | + </tr> | ||
34 | + </thead> | ||
35 | + <tbody> | ||
36 | + <foreach name="list" item="vo"> | ||
37 | + <foreach name="vo.question_text" item="qt"> | ||
38 | + <tr> | ||
39 | + <td>{$vo.user_nickname}</td> | ||
40 | + <td>{$vo.mobile}</td> | ||
41 | + <td>{$qt.order}</td> | ||
42 | + <td>{$qt.title}</td> | ||
43 | + <td>{$qt.score}</td> | ||
44 | + <td>{$vo.all_score}</td> | ||
45 | + <td>{$vo.user_coupon_text}</td> | ||
46 | + <td>{:date('Y-m-d H:i',$vo.create_time)}</td> | ||
47 | + </tr> | ||
48 | + </foreach> | ||
49 | + | ||
50 | + </foreach> | ||
51 | + </tbody> | ||
52 | + </table> | ||
53 | + <div class="pagination">{$page}</div> | ||
54 | +</div> | ||
55 | +<script src="__STATIC__/js/admin.js"></script> | ||
56 | +<script> | ||
57 | + function openexl() { | ||
58 | + var mobile = $('input[name=mobile]').val(); | ||
59 | + var start_time = $('input[name=start_time]').val(); | ||
60 | + var end_time = $('input[name=end_time]').val(); | ||
61 | + window.location.href="{:url('UserAnswer/Exl')}?mobile="+mobile+"&start_time="+start_time+"&end_time="+end_time; | ||
62 | + } | ||
63 | +</script> | ||
64 | +</body> | ||
65 | +</html> |
public/youhuiquan_img@2x.png
0 → 100644
4.7 KB
simplewind/extend/func/func.php
0 → 100644
1 | +<?php | ||
2 | +namespace func; | ||
3 | +class func | ||
4 | +{ | ||
5 | + /** | ||
6 | + * 数据导出 | ||
7 | + * @param array $title 标题行名称 | ||
8 | + * @param array $data 导出数据 | ||
9 | + * @param string $fileName 文件名 | ||
10 | + * @param string $savePath 保存路径 | ||
11 | + * @param $type 是否下载 false--保存 true--下载 | ||
12 | + * @return string 返回文件全路径 | ||
13 | + * @throws PHPExcel_Exception | ||
14 | + * @throws PHPExcel_Reader_Exception | ||
15 | + * exportExcel(array('姓名','年龄'), array(array('a',21),array('b',23)), '档案', './', true); | ||
16 | + */ | ||
17 | + function exportExcel($title = array(), $data = array(), $fileName = '', $savePath = './', $isDown = false) | ||
18 | + { | ||
19 | + vendor('phpoffice.phpexcel.Classes.PHPExcel'); | ||
20 | + $obj = new \PHPExcel(); | ||
21 | + $objWrite = new \PHPExcel_Writer_Excel2007($obj); | ||
22 | + $objWrite = new \PHPExcel_Writer_Excel5($obj); | ||
23 | + | ||
24 | +//横向单元格标识 | ||
25 | + $cellName = 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', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ'); | ||
26 | + | ||
27 | + $obj->getActiveSheet(0)->setTitle('sheet名称'); //设置sheet名称 | ||
28 | + $_row = 1; //设置纵向单元格标识 | ||
29 | + if ($title) { | ||
30 | + $_cnt = count($title); | ||
31 | + $obj->getActiveSheet(0)->mergeCells('A' . $_row . ':' . $cellName[$_cnt - 1] . $_row); //合并单元格 | ||
32 | + $obj->setActiveSheetIndex(0)->setCellValue('A' . $_row, '数据导出:' . date('Y-m-d H:i:s')); //设置合并后的单元格内容 | ||
33 | + $_row++; | ||
34 | + $i = 0; | ||
35 | + foreach ($title AS $v) { //设置列标题 | ||
36 | + $obj->setActiveSheetIndex(0)->setCellValue($cellName[$i] . $_row, $v); | ||
37 | + $i++; | ||
38 | + } | ||
39 | + $_row++; | ||
40 | + } | ||
41 | + | ||
42 | +//填写数据 | ||
43 | + if ($data) { | ||
44 | + $i = 0; | ||
45 | + foreach ($data AS $_v) { | ||
46 | + $j = 0; | ||
47 | + foreach ($_v AS $_cell) { | ||
48 | + $obj->getActiveSheet(0)->setCellValue($cellName[$j] . ($i + $_row), $_cell); | ||
49 | + $j++; | ||
50 | + } | ||
51 | + $i++; | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | +//文件名处理 | ||
56 | + if (!$fileName) { | ||
57 | + $fileName = uniqid(time(), true); | ||
58 | + } | ||
59 | + | ||
60 | + //$objWrite = PHPExcel_IOFactory::createWriter($obj, 'Excel2007'); | ||
61 | + | ||
62 | + if ($isDown) { //网页下载 | ||
63 | + header('pragma:public'); | ||
64 | + header("Content-Disposition:attachment;filename=$fileName.xls"); | ||
65 | + $objWrite->save('php://output'); | ||
66 | + exit; | ||
67 | + } | ||
68 | + | ||
69 | + $_fileName = iconv("utf-8", "gb2312", $fileName); //转码 | ||
70 | + $_savePath = $savePath . $_fileName . '.xlsx'; | ||
71 | + $objWrite->save($_savePath); | ||
72 | + | ||
73 | + return $savePath . $fileName . '.xlsx'; | ||
74 | + } | ||
75 | + | ||
76 | + //协助数据导出,过滤特殊字符 | ||
77 | + public function filterEmoji($emojiStr){ | ||
78 | + $emojiStr = preg_replace_callback('/./u',function(array $match){ | ||
79 | + return strlen($match[0]) >= 4 ? '' : $match[0]; | ||
80 | + },$emojiStr); | ||
81 | + return $emojiStr; | ||
82 | + } | ||
83 | +} |
simplewind/thinkphp/library/think/App.php
100644 → 100755
1 | -<?php | ||
2 | -// +---------------------------------------------------------------------- | ||
3 | -// | ThinkPHP [ WE CAN DO IT JUST THINK ] | ||
4 | -// +---------------------------------------------------------------------- | ||
5 | -// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. | ||
6 | -// +---------------------------------------------------------------------- | ||
7 | -// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) | ||
8 | -// +---------------------------------------------------------------------- | ||
9 | -// | Author: liu21st <liu21st@gmail.com> | ||
10 | -// +---------------------------------------------------------------------- | ||
11 | - | ||
12 | -namespace think; | ||
13 | - | ||
14 | -use think\exception\ClassNotFoundException; | ||
15 | -use think\exception\HttpException; | ||
16 | -use think\exception\HttpResponseException; | ||
17 | -use think\exception\RouteNotFoundException; | ||
18 | - | ||
19 | -/** | ||
20 | - * App 应用管理 | ||
21 | - * @author liu21st <liu21st@gmail.com> | ||
22 | - */ | ||
23 | -class App | ||
24 | -{ | ||
25 | - /** | ||
26 | - * @var bool 是否初始化过 | ||
27 | - */ | ||
28 | - protected static $init = false; | ||
29 | - | ||
30 | - /** | ||
31 | - * @var string 当前模块路径 | ||
32 | - */ | ||
33 | - public static $modulePath; | ||
34 | - | ||
35 | - /** | ||
36 | - * @var bool 应用调试模式 | ||
37 | - */ | ||
38 | - public static $debug = true; | ||
39 | - | ||
40 | - /** | ||
41 | - * @var string 应用类库命名空间 | ||
42 | - */ | ||
43 | - public static $namespace = 'app'; | ||
44 | - | ||
45 | - /** | ||
46 | - * @var bool 应用类库后缀 | ||
47 | - */ | ||
48 | - public static $suffix = false; | ||
49 | - | ||
50 | - /** | ||
51 | - * @var bool 应用路由检测 | ||
52 | - */ | ||
53 | - protected static $routeCheck; | ||
54 | - | ||
55 | - /** | ||
56 | - * @var bool 严格路由检测 | ||
57 | - */ | ||
58 | - protected static $routeMust; | ||
59 | - | ||
60 | - protected static $dispatch; | ||
61 | - protected static $file = []; | ||
62 | - | ||
63 | - /** | ||
64 | - * 执行应用程序 | ||
65 | - * @access public | ||
66 | - * @param Request $request Request对象 | ||
67 | - * @return Response | ||
68 | - * @throws Exception | ||
69 | - */ | ||
70 | - public static function run(Request $request = null) | ||
71 | - { | ||
72 | - is_null($request) && $request = Request::instance(); | ||
73 | - | ||
74 | - try { | ||
75 | - $config = self::initCommon(); | ||
76 | - if (defined('BIND_MODULE')) { | ||
77 | - // 模块/控制器绑定 | ||
78 | - BIND_MODULE && Route::bind(BIND_MODULE); | ||
79 | - } elseif ($config['auto_bind_module']) { | ||
80 | - // 入口自动绑定 | ||
81 | - $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); | ||
82 | - if ($name && 'index' != $name && is_dir(APP_PATH . $name)) { | ||
83 | - Route::bind($name); | ||
84 | - } | ||
85 | - } | ||
86 | - | ||
87 | - $request->filter($config['default_filter']); | ||
88 | - | ||
89 | - // 默认语言 | ||
90 | - Lang::range($config['default_lang']); | ||
91 | - if ($config['lang_switch_on']) { | ||
92 | - // 开启多语言机制 检测当前语言 | ||
93 | - Lang::detect(); | ||
94 | - } | ||
95 | - $request->langset(Lang::range()); | ||
96 | - | ||
97 | - // 加载系统语言包 | ||
98 | - Lang::load([ | ||
99 | - THINK_PATH . 'lang' . DS . $request->langset() . EXT, | ||
100 | - APP_PATH . 'lang' . DS . $request->langset() . EXT, | ||
101 | - ]); | ||
102 | - | ||
103 | - // 获取应用调度信息 | ||
104 | - $dispatch = self::$dispatch; | ||
105 | - if (empty($dispatch)) { | ||
106 | - // 进行URL路由检测 | ||
107 | - $dispatch = self::routeCheck($request, $config); | ||
108 | - } | ||
109 | - // 记录当前调度信息 | ||
110 | - $request->dispatch($dispatch); | ||
111 | - | ||
112 | - // 记录路由和请求信息 | ||
113 | - if (self::$debug) { | ||
114 | - Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); | ||
115 | - Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info'); | ||
116 | - Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); | ||
117 | - } | ||
118 | - | ||
119 | - // 监听app_begin | ||
120 | - Hook::listen('app_begin', $dispatch); | ||
121 | - // 请求缓存检查 | ||
122 | - $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); | ||
123 | - | ||
124 | - $data = self::exec($dispatch, $config); | ||
125 | - } catch (HttpResponseException $exception) { | ||
126 | - $data = $exception->getResponse(); | ||
127 | - } | ||
128 | - | ||
129 | - // 清空类的实例化 | ||
130 | - Loader::clearInstance(); | ||
131 | - | ||
132 | - // 输出数据到客户端 | ||
133 | - if ($data instanceof Response) { | ||
134 | - $response = $data; | ||
135 | - } elseif (!is_null($data)) { | ||
136 | - // 默认自动识别响应输出类型 | ||
137 | - $isAjax = $request->isAjax(); | ||
138 | - $type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); | ||
139 | - $response = Response::create($data, $type); | ||
140 | - } else { | ||
141 | - $response = Response::create(); | ||
142 | - } | ||
143 | - | ||
144 | - // 监听app_end | ||
145 | - Hook::listen('app_end', $response); | ||
146 | - | ||
147 | - return $response; | ||
148 | - } | ||
149 | - | ||
150 | - /** | ||
151 | - * 设置当前请求的调度信息 | ||
152 | - * @access public | ||
153 | - * @param array|string $dispatch 调度信息 | ||
154 | - * @param string $type 调度类型 | ||
155 | - * @return void | ||
156 | - */ | ||
157 | - public static function dispatch($dispatch, $type = 'module') | ||
158 | - { | ||
159 | - self::$dispatch = ['type' => $type, $type => $dispatch]; | ||
160 | - } | ||
161 | - | ||
162 | - /** | ||
163 | - * 执行函数或者闭包方法 支持参数调用 | ||
164 | - * @access public | ||
165 | - * @param string|array|\Closure $function 函数或者闭包 | ||
166 | - * @param array $vars 变量 | ||
167 | - * @return mixed | ||
168 | - */ | ||
169 | - public static function invokeFunction($function, $vars = []) | ||
170 | - { | ||
171 | - $reflect = new \ReflectionFunction($function); | ||
172 | - $args = self::bindParams($reflect, $vars); | ||
173 | - // 记录执行信息 | ||
174 | - self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); | ||
175 | - return $reflect->invokeArgs($args); | ||
176 | - } | ||
177 | - | ||
178 | - /** | ||
179 | - * 调用反射执行类的方法 支持参数绑定 | ||
180 | - * @access public | ||
181 | - * @param string|array $method 方法 | ||
182 | - * @param array $vars 变量 | ||
183 | - * @return mixed | ||
184 | - */ | ||
185 | - public static function invokeMethod($method, $vars = []) | ||
186 | - { | ||
187 | - if (is_array($method)) { | ||
188 | - $class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]); | ||
189 | - $reflect = new \ReflectionMethod($class, $method[1]); | ||
190 | - } else { | ||
191 | - // 静态方法 | ||
192 | - $reflect = new \ReflectionMethod($method); | ||
193 | - } | ||
194 | - $args = self::bindParams($reflect, $vars); | ||
195 | - | ||
196 | - self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); | ||
197 | - return $reflect->invokeArgs(isset($class) ? $class : null, $args); | ||
198 | - } | ||
199 | - | ||
200 | - /** | ||
201 | - * 调用反射执行类的实例化 支持依赖注入 | ||
202 | - * @access public | ||
203 | - * @param string $class 类名 | ||
204 | - * @param array $vars 变量 | ||
205 | - * @return mixed | ||
206 | - */ | ||
207 | - public static function invokeClass($class, $vars = []) | ||
208 | - { | ||
209 | - $reflect = new \ReflectionClass($class); | ||
210 | - $constructor = $reflect->getConstructor(); | ||
211 | - if ($constructor) { | ||
212 | - $args = self::bindParams($constructor, $vars); | ||
213 | - } else { | ||
214 | - $args = []; | ||
215 | - } | ||
216 | - return $reflect->newInstanceArgs($args); | ||
217 | - } | ||
218 | - | ||
219 | - /** | ||
220 | - * 绑定参数 | ||
221 | - * @access private | ||
222 | - * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 | ||
223 | - * @param array $vars 变量 | ||
224 | - * @return array | ||
225 | - */ | ||
226 | - private static function bindParams($reflect, $vars = []) | ||
227 | - { | ||
228 | - if (empty($vars)) { | ||
229 | - // 自动获取请求变量 | ||
230 | - if (Config::get('url_param_type')) { | ||
231 | - $vars = Request::instance()->route(); | ||
232 | - } else { | ||
233 | - $vars = Request::instance()->param(); | ||
234 | - } | ||
235 | - } | ||
236 | - $args = []; | ||
237 | - if ($reflect->getNumberOfParameters() > 0) { | ||
238 | - // 判断数组类型 数字数组时按顺序绑定参数 | ||
239 | - reset($vars); | ||
240 | - $type = key($vars) === 0 ? 1 : 0; | ||
241 | - $params = $reflect->getParameters(); | ||
242 | - foreach ($params as $param) { | ||
243 | - $args[] = self::getParamValue($param, $vars, $type); | ||
244 | - } | ||
245 | - } | ||
246 | - return $args; | ||
247 | - } | ||
248 | - | ||
249 | - /** | ||
250 | - * 获取参数值 | ||
251 | - * @access private | ||
252 | - * @param \ReflectionParameter $param | ||
253 | - * @param array $vars 变量 | ||
254 | - * @param string $type | ||
255 | - * @return array | ||
256 | - */ | ||
257 | - private static function getParamValue($param, &$vars, $type) | ||
258 | - { | ||
259 | - $name = $param->getName(); | ||
260 | - $class = $param->getClass(); | ||
261 | - if ($class) { | ||
262 | - $className = $class->getName(); | ||
263 | - $bind = Request::instance()->$name; | ||
264 | - if ($bind instanceof $className) { | ||
265 | - $result = $bind; | ||
266 | - } else { | ||
267 | - if (method_exists($className, 'invoke')) { | ||
268 | - $method = new \ReflectionMethod($className, 'invoke'); | ||
269 | - if ($method->isPublic() && $method->isStatic()) { | ||
270 | - return $className::invoke(Request::instance()); | ||
271 | - } | ||
272 | - } | ||
273 | - $result = method_exists($className, 'instance') ? $className::instance() : new $className; | ||
274 | - } | ||
275 | - } elseif (1 == $type && !empty($vars)) { | ||
276 | - $result = array_shift($vars); | ||
277 | - } elseif (0 == $type && isset($vars[$name])) { | ||
278 | - $result = $vars[$name]; | ||
279 | - } elseif ($param->isDefaultValueAvailable()) { | ||
280 | - $result = $param->getDefaultValue(); | ||
281 | - } else { | ||
282 | - throw new \InvalidArgumentException('method param miss:' . $name); | ||
283 | - } | ||
284 | - return $result; | ||
285 | - } | ||
286 | - | ||
287 | - protected static function exec($dispatch, $config) | ||
288 | - { | ||
289 | - switch ($dispatch['type']) { | ||
290 | - case 'redirect': | ||
291 | - // 执行重定向跳转 | ||
292 | - $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']); | ||
293 | - break; | ||
294 | - case 'module': | ||
295 | - // 模块/控制器/操作 | ||
296 | - $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null); | ||
297 | - break; | ||
298 | - case 'controller': | ||
299 | - // 执行控制器操作 | ||
300 | - $vars = array_merge(Request::instance()->param(), $dispatch['var']); | ||
301 | - $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']); | ||
302 | - break; | ||
303 | - case 'method': | ||
304 | - // 执行回调方法 | ||
305 | - $vars = array_merge(Request::instance()->param(), $dispatch['var']); | ||
306 | - $data = self::invokeMethod($dispatch['method'], $vars); | ||
307 | - break; | ||
308 | - case 'function': | ||
309 | - // 执行闭包 | ||
310 | - $data = self::invokeFunction($dispatch['function']); | ||
311 | - break; | ||
312 | - case 'response': | ||
313 | - $data = $dispatch['response']; | ||
314 | - break; | ||
315 | - default: | ||
316 | - throw new \InvalidArgumentException('dispatch type not support'); | ||
317 | - } | ||
318 | - return $data; | ||
319 | - } | ||
320 | - | ||
321 | - /** | ||
322 | - * 执行模块 | ||
323 | - * @access public | ||
324 | - * @param array $result 模块/控制器/操作 | ||
325 | - * @param array $config 配置参数 | ||
326 | - * @param bool $convert 是否自动转换控制器和操作名 | ||
327 | - * @return mixed | ||
328 | - */ | ||
329 | - public static function module($result, $config, $convert = null) | ||
330 | - { | ||
331 | - if (is_string($result)) { | ||
332 | - $result = explode('/', $result); | ||
333 | - } | ||
334 | - $request = Request::instance(); | ||
335 | - if ($config['app_multi_module']) { | ||
336 | - // 多模块部署 | ||
337 | - $module = strip_tags(strtolower($result[0] ?: $config['default_module'])); | ||
338 | - $bind = Route::getBind('module'); | ||
339 | - $available = false; | ||
340 | - if ($bind) { | ||
341 | - // 绑定模块 | ||
342 | - list($bindModule) = explode('/', $bind); | ||
343 | - if (empty($result[0])) { | ||
344 | - $module = $bindModule; | ||
345 | - $available = true; | ||
346 | - } elseif ($module == $bindModule) { | ||
347 | - $available = true; | ||
348 | - } | ||
349 | - } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) { | ||
350 | - $available = true; | ||
351 | - } | ||
352 | - | ||
353 | - // 模块初始化 | ||
354 | - if ($module && $available) { | ||
355 | - // 初始化模块 | ||
356 | - $request->module($module); | ||
357 | - $config = self::init($module); | ||
358 | - // 模块请求缓存检查 | ||
359 | - $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); | ||
360 | - } else { | ||
361 | - throw new HttpException(404, 'module not exists:' . $module); | ||
362 | - } | ||
363 | - } else { | ||
364 | - // 单一模块部署 | ||
365 | - $module = ''; | ||
366 | - $request->module($module); | ||
367 | - } | ||
368 | - // 当前模块路径 | ||
369 | - App::$modulePath = APP_PATH . ($module ? $module . DS : ''); | ||
370 | - | ||
371 | - // 是否自动转换控制器和操作名 | ||
372 | - $convert = is_bool($convert) ? $convert : $config['url_convert']; | ||
373 | - // 获取控制器名 | ||
374 | - $controller = strip_tags($result[1] ?: $config['default_controller']); | ||
375 | - $controller = $convert ? strtolower($controller) : $controller; | ||
376 | - | ||
377 | - // 获取操作名 | ||
378 | - $actionName = strip_tags($result[2] ?: $config['default_action']); | ||
379 | - $actionName = $convert ? strtolower($actionName) : $actionName; | ||
380 | - | ||
381 | - // 设置当前请求的控制器、操作 | ||
382 | - $request->controller(Loader::parseName($controller, 1))->action($actionName); | ||
383 | - | ||
384 | - // 监听module_init | ||
385 | - Hook::listen('module_init', $request); | ||
386 | - | ||
387 | - try { | ||
388 | - $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']); | ||
389 | - } catch (ClassNotFoundException $e) { | ||
390 | - throw new HttpException(404, 'controller not exists:' . $e->getClass()); | ||
391 | - } | ||
392 | - | ||
393 | - // 获取当前操作名 | ||
394 | - $action = $actionName . $config['action_suffix']; | ||
395 | - | ||
396 | - $vars = []; | ||
397 | - if (is_callable([$instance, $action])) { | ||
398 | - // 执行操作方法 | ||
399 | - $call = [$instance, $action]; | ||
400 | - } elseif (is_callable([$instance, '_empty'])) { | ||
401 | - // 空操作 | ||
402 | - $call = [$instance, '_empty']; | ||
403 | - $vars = [$actionName]; | ||
404 | - } else { | ||
405 | - // 操作不存在 | ||
406 | - throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); | ||
407 | - } | ||
408 | - | ||
409 | - Hook::listen('action_begin', $call); | ||
410 | - | ||
411 | - return self::invokeMethod($call, $vars); | ||
412 | - } | ||
413 | - | ||
414 | - /** | ||
415 | - * 初始化应用 | ||
416 | - */ | ||
417 | - public static function initCommon() | ||
418 | - { | ||
419 | - if (empty(self::$init)) { | ||
420 | - if (defined('APP_NAMESPACE')) { | ||
421 | - self::$namespace = APP_NAMESPACE; | ||
422 | - } | ||
423 | - Loader::addNamespace(self::$namespace, APP_PATH); | ||
424 | - | ||
425 | - // 初始化应用 | ||
426 | - $config = self::init(); | ||
427 | - self::$suffix = $config['class_suffix']; | ||
428 | - | ||
429 | - // 应用调试模式 | ||
430 | - self::$debug = Env::get('app_debug', Config::get('app_debug')); | ||
431 | - if (!self::$debug) { | ||
432 | - ini_set('display_errors', 'Off'); | ||
433 | - } elseif (!IS_CLI) { | ||
434 | - //重新申请一块比较大的buffer | ||
435 | - if (ob_get_level() > 0) { | ||
436 | - $output = ob_get_clean(); | ||
437 | - } | ||
438 | - ob_start(); | ||
439 | - if (!empty($output)) { | ||
440 | - echo $output; | ||
441 | - } | ||
442 | - } | ||
443 | - | ||
444 | - if (!empty($config['root_namespace'])) { | ||
445 | - Loader::addNamespace($config['root_namespace']); | ||
446 | - } | ||
447 | - | ||
448 | - // 加载额外文件 | ||
449 | - if (!empty($config['extra_file_list'])) { | ||
450 | - foreach ($config['extra_file_list'] as $file) { | ||
451 | - $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; | ||
452 | - if (is_file($file) && !isset(self::$file[$file])) { | ||
453 | - include $file; | ||
454 | - self::$file[$file] = true; | ||
455 | - } | ||
456 | - } | ||
457 | - } | ||
458 | - | ||
459 | - // 设置系统时区 | ||
460 | - date_default_timezone_set($config['default_timezone']); | ||
461 | - | ||
462 | - // 监听app_init | ||
463 | - Hook::listen('app_init'); | ||
464 | - | ||
465 | - self::$init = true; | ||
466 | - } | ||
467 | - return Config::get(); | ||
468 | - } | ||
469 | - | ||
470 | - /** | ||
471 | - * 初始化应用或模块 | ||
472 | - * @access public | ||
473 | - * @param string $module 模块名 | ||
474 | - * @return array | ||
475 | - */ | ||
476 | - private static function init($module = '') | ||
477 | - { | ||
478 | - // 定位模块目录 | ||
479 | - $module = $module ? $module . DS : ''; | ||
480 | - | ||
481 | - // 加载初始化文件 | ||
482 | - if (is_file(APP_PATH . $module . 'init' . EXT)) { | ||
483 | - include APP_PATH . $module . 'init' . EXT; | ||
484 | - } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { | ||
485 | - include RUNTIME_PATH . $module . 'init' . EXT; | ||
486 | - } else { | ||
487 | - $path = APP_PATH . $module; | ||
488 | - // 加载模块配置 | ||
489 | - $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); | ||
490 | - // 读取数据库配置文件 | ||
491 | - $filename = CONF_PATH . $module . 'database' . CONF_EXT; | ||
492 | - Config::load($filename, 'database'); | ||
493 | - // 读取扩展配置文件 | ||
494 | - if (is_dir(CONF_PATH . $module . 'extra')) { | ||
495 | - $dir = CONF_PATH . $module . 'extra'; | ||
496 | - $files = scandir($dir); | ||
497 | - foreach ($files as $file) { | ||
498 | - if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { | ||
499 | - $filename = $dir . DS . $file; | ||
500 | - Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); | ||
501 | - } | ||
502 | - } | ||
503 | - } | ||
504 | - | ||
505 | - // 加载应用状态配置 | ||
506 | - if ($config['app_status']) { | ||
507 | - $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); | ||
508 | - } | ||
509 | - | ||
510 | - // 加载行为扩展文件 | ||
511 | - if (is_file(CONF_PATH . $module . 'tags' . EXT)) { | ||
512 | - Hook::import(include CONF_PATH . $module . 'tags' . EXT); | ||
513 | - } | ||
514 | - | ||
515 | - // 加载公共文件 | ||
516 | - if (is_file($path . 'common' . EXT)) { | ||
517 | - include $path . 'common' . EXT; | ||
518 | - } | ||
519 | - | ||
520 | - // 加载当前模块语言包 | ||
521 | - if ($module) { | ||
522 | - Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); | ||
523 | - } | ||
524 | - } | ||
525 | - return Config::get(); | ||
526 | - } | ||
527 | - | ||
528 | - /** | ||
529 | - * URL路由检测(根据PATH_INFO) | ||
530 | - * @access public | ||
531 | - * @param \think\Request $request | ||
532 | - * @param array $config | ||
533 | - * @return array | ||
534 | - * @throws \think\Exception | ||
535 | - */ | ||
536 | - public static function routeCheck($request, array $config) | ||
537 | - { | ||
538 | - $path = $request->path(); | ||
539 | - $depr = $config['pathinfo_depr']; | ||
540 | - $result = false; | ||
541 | - // 路由检测 | ||
542 | - $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; | ||
543 | - if ($check) { | ||
544 | - // 开启路由 | ||
545 | - if (is_file(RUNTIME_PATH . 'route.php')) { | ||
546 | - // 读取路由缓存 | ||
547 | - $rules = include RUNTIME_PATH . 'route.php'; | ||
548 | - if (is_array($rules)) { | ||
549 | - Route::rules($rules); | ||
550 | - } | ||
551 | - } else { | ||
552 | - $files = $config['route_config_file']; | ||
553 | - foreach ($files as $file) { | ||
554 | - if (is_file(CONF_PATH . $file . CONF_EXT)) { | ||
555 | - // 导入路由配置 | ||
556 | - $rules = include CONF_PATH . $file . CONF_EXT; | ||
557 | - if (is_array($rules)) { | ||
558 | - Route::import($rules); | ||
559 | - } | ||
560 | - } | ||
561 | - } | ||
562 | - } | ||
563 | - | ||
564 | - // 路由检测(根据路由定义返回不同的URL调度) | ||
565 | - $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); | ||
566 | - $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; | ||
567 | - if ($must && false === $result) { | ||
568 | - // 路由无效 | ||
569 | - throw new RouteNotFoundException(); | ||
570 | - } | ||
571 | - } | ||
572 | - if (false === $result) { | ||
573 | - // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 | ||
574 | - $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); | ||
575 | - } | ||
576 | - return $result; | ||
577 | - } | ||
578 | - | ||
579 | - /** | ||
580 | - * 设置应用的路由检测机制 | ||
581 | - * @access public | ||
582 | - * @param bool $route 是否需要检测路由 | ||
583 | - * @param bool $must 是否强制检测路由 | ||
584 | - * @return void | ||
585 | - */ | ||
586 | - public static function route($route, $must = false) | ||
587 | - { | ||
588 | - self::$routeCheck = $route; | ||
589 | - self::$routeMust = $must; | ||
590 | - } | ||
591 | -} | 1 | +<?php |
2 | +// +---------------------------------------------------------------------- | ||
3 | +// | ThinkPHP [ WE CAN DO IT JUST THINK ] | ||
4 | +// +---------------------------------------------------------------------- | ||
5 | +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. | ||
6 | +// +---------------------------------------------------------------------- | ||
7 | +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) | ||
8 | +// +---------------------------------------------------------------------- | ||
9 | +// | Author: liu21st <liu21st@gmail.com> | ||
10 | +// +---------------------------------------------------------------------- | ||
11 | + | ||
12 | +namespace think; | ||
13 | + | ||
14 | +use think\exception\ClassNotFoundException; | ||
15 | +use think\exception\HttpException; | ||
16 | +use think\exception\HttpResponseException; | ||
17 | +use think\exception\RouteNotFoundException; | ||
18 | + | ||
19 | +/** | ||
20 | + * App 应用管理 | ||
21 | + * @author liu21st <liu21st@gmail.com> | ||
22 | + */ | ||
23 | +class App | ||
24 | +{ | ||
25 | + /** | ||
26 | + * @var bool 是否初始化过 | ||
27 | + */ | ||
28 | + protected static $init = false; | ||
29 | + | ||
30 | + /** | ||
31 | + * @var string 当前模块路径 | ||
32 | + */ | ||
33 | + public static $modulePath; | ||
34 | + | ||
35 | + /** | ||
36 | + * @var bool 应用调试模式 | ||
37 | + */ | ||
38 | + public static $debug = true; | ||
39 | + | ||
40 | + /** | ||
41 | + * @var string 应用类库命名空间 | ||
42 | + */ | ||
43 | + public static $namespace = 'app'; | ||
44 | + | ||
45 | + /** | ||
46 | + * @var bool 应用类库后缀 | ||
47 | + */ | ||
48 | + public static $suffix = false; | ||
49 | + | ||
50 | + /** | ||
51 | + * @var bool 应用路由检测 | ||
52 | + */ | ||
53 | + protected static $routeCheck; | ||
54 | + | ||
55 | + /** | ||
56 | + * @var bool 严格路由检测 | ||
57 | + */ | ||
58 | + protected static $routeMust; | ||
59 | + | ||
60 | + protected static $dispatch; | ||
61 | + protected static $file = []; | ||
62 | + | ||
63 | + /** | ||
64 | + * 执行应用程序 | ||
65 | + * @access public | ||
66 | + * @param Request $request Request对象 | ||
67 | + * @return Response | ||
68 | + * @throws Exception | ||
69 | + */ | ||
70 | + public static function run(Request $request = null) | ||
71 | + { | ||
72 | + is_null($request) && $request = Request::instance(); | ||
73 | + | ||
74 | + try { | ||
75 | + $config = self::initCommon(); | ||
76 | + if (defined('BIND_MODULE')) { | ||
77 | + // 模块/控制器绑定 | ||
78 | + BIND_MODULE && Route::bind(BIND_MODULE); | ||
79 | + } elseif ($config['auto_bind_module']) { | ||
80 | + // 入口自动绑定 | ||
81 | + $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); | ||
82 | + if ($name && 'index' != $name && is_dir(APP_PATH . $name)) { | ||
83 | + Route::bind($name); | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + $request->filter($config['default_filter']); | ||
88 | + | ||
89 | + // 默认语言 | ||
90 | + Lang::range($config['default_lang']); | ||
91 | + if ($config['lang_switch_on']) { | ||
92 | + // 开启多语言机制 检测当前语言 | ||
93 | + Lang::detect(); | ||
94 | + } | ||
95 | + $request->langset(Lang::range()); | ||
96 | + | ||
97 | + // 加载系统语言包 | ||
98 | + Lang::load([ | ||
99 | + THINK_PATH . 'lang' . DS . $request->langset() . EXT, | ||
100 | + APP_PATH . 'lang' . DS . $request->langset() . EXT, | ||
101 | + ]); | ||
102 | + | ||
103 | + // 获取应用调度信息 | ||
104 | + $dispatch = self::$dispatch; | ||
105 | + if (empty($dispatch)) { | ||
106 | + // 进行URL路由检测 | ||
107 | + $dispatch = self::routeCheck($request, $config); | ||
108 | + } | ||
109 | + // 记录当前调度信息 | ||
110 | + $request->dispatch($dispatch); | ||
111 | + | ||
112 | + // 记录路由和请求信息 | ||
113 | + if (self::$debug) { | ||
114 | + Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); | ||
115 | + Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info'); | ||
116 | + Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); | ||
117 | + } | ||
118 | + | ||
119 | + // 监听app_begin | ||
120 | + Hook::listen('app_begin', $dispatch); | ||
121 | + // 请求缓存检查 | ||
122 | + $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); | ||
123 | + | ||
124 | + $data = self::exec($dispatch, $config); | ||
125 | + } catch (HttpResponseException $exception) { | ||
126 | + $data = $exception->getResponse(); | ||
127 | + } | ||
128 | + | ||
129 | + // 清空类的实例化 | ||
130 | + Loader::clearInstance(); | ||
131 | + | ||
132 | + // 输出数据到客户端 | ||
133 | + if ($data instanceof Response) { | ||
134 | + $response = $data; | ||
135 | + } elseif (!is_null($data)) { | ||
136 | + // 默认自动识别响应输出类型 | ||
137 | + $isAjax = $request->isAjax(); | ||
138 | + $type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); | ||
139 | + $response = Response::create($data, $type); | ||
140 | + } else { | ||
141 | + $response = Response::create(); | ||
142 | + } | ||
143 | + | ||
144 | + // 监听app_end | ||
145 | + Hook::listen('app_end', $response); | ||
146 | + | ||
147 | + return $response; | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * 设置当前请求的调度信息 | ||
152 | + * @access public | ||
153 | + * @param array|string $dispatch 调度信息 | ||
154 | + * @param string $type 调度类型 | ||
155 | + * @return void | ||
156 | + */ | ||
157 | + public static function dispatch($dispatch, $type = 'module') | ||
158 | + { | ||
159 | + self::$dispatch = ['type' => $type, $type => $dispatch]; | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * 执行函数或者闭包方法 支持参数调用 | ||
164 | + * @access public | ||
165 | + * @param string|array|\Closure $function 函数或者闭包 | ||
166 | + * @param array $vars 变量 | ||
167 | + * @return mixed | ||
168 | + */ | ||
169 | + public static function invokeFunction($function, $vars = []) | ||
170 | + { | ||
171 | + $reflect = new \ReflectionFunction($function); | ||
172 | + $args = self::bindParams($reflect, $vars); | ||
173 | + // 记录执行信息 | ||
174 | + self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); | ||
175 | + return $reflect->invokeArgs($args); | ||
176 | + } | ||
177 | + | ||
178 | + /** | ||
179 | + * 调用反射执行类的方法 支持参数绑定 | ||
180 | + * @access public | ||
181 | + * @param string|array $method 方法 | ||
182 | + * @param array $vars 变量 | ||
183 | + * @return mixed | ||
184 | + */ | ||
185 | + public static function invokeMethod($method, $vars = []) | ||
186 | + { | ||
187 | + if (is_array($method)) { | ||
188 | + $class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]); | ||
189 | + $reflect = new \ReflectionMethod($class, $method[1]); | ||
190 | + } else { | ||
191 | + // 静态方法 | ||
192 | + $reflect = new \ReflectionMethod($method); | ||
193 | + } | ||
194 | + $args = self::bindParams($reflect, $vars); | ||
195 | + | ||
196 | + self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); | ||
197 | + return $reflect->invokeArgs(isset($class) ? $class : null, $args); | ||
198 | + } | ||
199 | + | ||
200 | + /** | ||
201 | + * 调用反射执行类的实例化 支持依赖注入 | ||
202 | + * @access public | ||
203 | + * @param string $class 类名 | ||
204 | + * @param array $vars 变量 | ||
205 | + * @return mixed | ||
206 | + */ | ||
207 | + public static function invokeClass($class, $vars = []) | ||
208 | + { | ||
209 | + $reflect = new \ReflectionClass($class); | ||
210 | + $constructor = $reflect->getConstructor(); | ||
211 | + if ($constructor) { | ||
212 | + $args = self::bindParams($constructor, $vars); | ||
213 | + } else { | ||
214 | + $args = []; | ||
215 | + } | ||
216 | + return $reflect->newInstanceArgs($args); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * 绑定参数 | ||
221 | + * @access private | ||
222 | + * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 | ||
223 | + * @param array $vars 变量 | ||
224 | + * @return array | ||
225 | + */ | ||
226 | + private static function bindParams($reflect, $vars = []) | ||
227 | + { | ||
228 | + if (empty($vars)) { | ||
229 | + // 自动获取请求变量 | ||
230 | + if (Config::get('url_param_type')) { | ||
231 | + $vars = Request::instance()->route(); | ||
232 | + } else { | ||
233 | + $vars = Request::instance()->param(); | ||
234 | + } | ||
235 | + } | ||
236 | + $args = []; | ||
237 | + if ($reflect->getNumberOfParameters() > 0) { | ||
238 | + // 判断数组类型 数字数组时按顺序绑定参数 | ||
239 | + reset($vars); | ||
240 | + $type = key($vars) === 0 ? 1 : 0; | ||
241 | + $params = $reflect->getParameters(); | ||
242 | + foreach ($params as $param) { | ||
243 | + $args[] = self::getParamValue($param, $vars, $type); | ||
244 | + } | ||
245 | + } | ||
246 | + return $args; | ||
247 | + } | ||
248 | + | ||
249 | + /** | ||
250 | + * 获取参数值 | ||
251 | + * @access private | ||
252 | + * @param \ReflectionParameter $param | ||
253 | + * @param array $vars 变量 | ||
254 | + * @param string $type | ||
255 | + * @return array | ||
256 | + */ | ||
257 | + private static function getParamValue($param, &$vars, $type) | ||
258 | + { | ||
259 | + $name = $param->getName(); | ||
260 | + $class = $param->getClass(); | ||
261 | + if ($class) { | ||
262 | + $className = $class->getName(); | ||
263 | + $bind = Request::instance()->$name; | ||
264 | + if ($bind instanceof $className) { | ||
265 | + $result = $bind; | ||
266 | + } else { | ||
267 | + if (method_exists($className, 'invoke')) { | ||
268 | + $method = new \ReflectionMethod($className, 'invoke'); | ||
269 | + if ($method->isPublic() && $method->isStatic()) { | ||
270 | + return $className::invoke(Request::instance()); | ||
271 | + } | ||
272 | + } | ||
273 | + $result = method_exists($className, 'instance') ? $className::instance() : new $className; | ||
274 | + } | ||
275 | + } elseif (1 == $type && !empty($vars)) { | ||
276 | + $result = array_shift($vars); | ||
277 | + } elseif (0 == $type && isset($vars[$name])) { | ||
278 | + $result = $vars[$name]; | ||
279 | + } elseif ($param->isDefaultValueAvailable()) { | ||
280 | + $result = $param->getDefaultValue(); | ||
281 | + } else { | ||
282 | + throw new \InvalidArgumentException('method param miss:' . $name); | ||
283 | + } | ||
284 | + return $result; | ||
285 | + } | ||
286 | + | ||
287 | + protected static function exec($dispatch, $config) | ||
288 | + { | ||
289 | + switch ($dispatch['type']) { | ||
290 | + case 'redirect': | ||
291 | + // 执行重定向跳转 | ||
292 | + $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']); | ||
293 | + break; | ||
294 | + case 'module': | ||
295 | + // 模块/控制器/操作 | ||
296 | + $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null); | ||
297 | + break; | ||
298 | + case 'controller': | ||
299 | + // 执行控制器操作 | ||
300 | + $vars = array_merge(Request::instance()->param(), $dispatch['var']); | ||
301 | + $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']); | ||
302 | + break; | ||
303 | + case 'method': | ||
304 | + // 执行回调方法 | ||
305 | + $vars = array_merge(Request::instance()->param(), $dispatch['var']); | ||
306 | + $data = self::invokeMethod($dispatch['method'], $vars); | ||
307 | + break; | ||
308 | + case 'function': | ||
309 | + // 执行闭包 | ||
310 | + $data = self::invokeFunction($dispatch['function']); | ||
311 | + break; | ||
312 | + case 'response': | ||
313 | + $data = $dispatch['response']; | ||
314 | + break; | ||
315 | + default: | ||
316 | + throw new \InvalidArgumentException('dispatch type not support'); | ||
317 | + } | ||
318 | + return $data; | ||
319 | + } | ||
320 | + | ||
321 | + /** | ||
322 | + * 执行模块 | ||
323 | + * @access public | ||
324 | + * @param array $result 模块/控制器/操作 | ||
325 | + * @param array $config 配置参数 | ||
326 | + * @param bool $convert 是否自动转换控制器和操作名 | ||
327 | + * @return mixed | ||
328 | + */ | ||
329 | + public static function module($result, $config, $convert = null) | ||
330 | + { | ||
331 | + if (is_string($result)) { | ||
332 | + $result = explode('/', $result); | ||
333 | + } | ||
334 | + $request = Request::instance(); | ||
335 | + if ($config['app_multi_module']) { | ||
336 | + // 多模块部署 | ||
337 | + $module = strip_tags(strtolower($result[0] ?: $config['default_module'])); | ||
338 | + $bind = Route::getBind('module'); | ||
339 | + $available = false; | ||
340 | + if ($bind) { | ||
341 | + // 绑定模块 | ||
342 | + list($bindModule) = explode('/', $bind); | ||
343 | + if (empty($result[0])) { | ||
344 | + $module = $bindModule; | ||
345 | + $available = true; | ||
346 | + } elseif ($module == $bindModule) { | ||
347 | + $available = true; | ||
348 | + } | ||
349 | + } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) { | ||
350 | + $available = true; | ||
351 | + } | ||
352 | + | ||
353 | + // 模块初始化 | ||
354 | + if ($module && $available) { | ||
355 | + // 初始化模块 | ||
356 | + $request->module($module); | ||
357 | + $config = self::init($module); | ||
358 | + // 模块请求缓存检查 | ||
359 | + $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); | ||
360 | + } else { | ||
361 | + throw new HttpException(404, 'module not exists:' . $module); | ||
362 | + } | ||
363 | + } else { | ||
364 | + // 单一模块部署 | ||
365 | + $module = ''; | ||
366 | + $request->module($module); | ||
367 | + } | ||
368 | + // 当前模块路径 | ||
369 | + App::$modulePath = APP_PATH . ($module ? $module . DS : ''); | ||
370 | + | ||
371 | + // 是否自动转换控制器和操作名 | ||
372 | + $convert = is_bool($convert) ? $convert : $config['url_convert']; | ||
373 | + // 获取控制器名 | ||
374 | + $controller = strip_tags($result[1] ?: $config['default_controller']); | ||
375 | + $controller = $convert ? strtolower($controller) : $controller; | ||
376 | + | ||
377 | + if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { | ||
378 | + throw new HttpException(404, 'controller not exists:' . $controller); | ||
379 | + } | ||
380 | + | ||
381 | + // 获取操作名 | ||
382 | + $actionName = strip_tags($result[2] ?: $config['default_action']); | ||
383 | + $actionName = $convert ? strtolower($actionName) : $actionName; | ||
384 | + | ||
385 | + // 设置当前请求的控制器、操作 | ||
386 | + $request->controller(Loader::parseName($controller, 1))->action($actionName); | ||
387 | + | ||
388 | + // 监听module_init | ||
389 | + Hook::listen('module_init', $request); | ||
390 | + | ||
391 | + try { | ||
392 | + $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']); | ||
393 | + } catch (ClassNotFoundException $e) { | ||
394 | + throw new HttpException(404, 'controller not exists:' . $e->getClass()); | ||
395 | + } | ||
396 | + | ||
397 | + // 获取当前操作名 | ||
398 | + $action = $actionName . $config['action_suffix']; | ||
399 | + | ||
400 | + $vars = []; | ||
401 | + if (is_callable([$instance, $action])) { | ||
402 | + // 执行操作方法 | ||
403 | + $call = [$instance, $action]; | ||
404 | + } elseif (is_callable([$instance, '_empty'])) { | ||
405 | + // 空操作 | ||
406 | + $call = [$instance, '_empty']; | ||
407 | + $vars = [$actionName]; | ||
408 | + } else { | ||
409 | + // 操作不存在 | ||
410 | + throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); | ||
411 | + } | ||
412 | + | ||
413 | + Hook::listen('action_begin', $call); | ||
414 | + | ||
415 | + return self::invokeMethod($call, $vars); | ||
416 | + } | ||
417 | + | ||
418 | + /** | ||
419 | + * 初始化应用 | ||
420 | + */ | ||
421 | + public static function initCommon() | ||
422 | + { | ||
423 | + if (empty(self::$init)) { | ||
424 | + if (defined('APP_NAMESPACE')) { | ||
425 | + self::$namespace = APP_NAMESPACE; | ||
426 | + } | ||
427 | + Loader::addNamespace(self::$namespace, APP_PATH); | ||
428 | + | ||
429 | + // 初始化应用 | ||
430 | + $config = self::init(); | ||
431 | + self::$suffix = $config['class_suffix']; | ||
432 | + | ||
433 | + // 应用调试模式 | ||
434 | + self::$debug = Env::get('app_debug', Config::get('app_debug')); | ||
435 | + if (!self::$debug) { | ||
436 | + ini_set('display_errors', 'Off'); | ||
437 | + } elseif (!IS_CLI) { | ||
438 | + //重新申请一块比较大的buffer | ||
439 | + if (ob_get_level() > 0) { | ||
440 | + $output = ob_get_clean(); | ||
441 | + } | ||
442 | + ob_start(); | ||
443 | + if (!empty($output)) { | ||
444 | + echo $output; | ||
445 | + } | ||
446 | + } | ||
447 | + | ||
448 | + if (!empty($config['root_namespace'])) { | ||
449 | + Loader::addNamespace($config['root_namespace']); | ||
450 | + } | ||
451 | + | ||
452 | + // 加载额外文件 | ||
453 | + if (!empty($config['extra_file_list'])) { | ||
454 | + foreach ($config['extra_file_list'] as $file) { | ||
455 | + $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; | ||
456 | + if (is_file($file) && !isset(self::$file[$file])) { | ||
457 | + include $file; | ||
458 | + self::$file[$file] = true; | ||
459 | + } | ||
460 | + } | ||
461 | + } | ||
462 | + | ||
463 | + // 设置系统时区 | ||
464 | + date_default_timezone_set($config['default_timezone']); | ||
465 | + | ||
466 | + // 监听app_init | ||
467 | + Hook::listen('app_init'); | ||
468 | + | ||
469 | + self::$init = true; | ||
470 | + } | ||
471 | + return Config::get(); | ||
472 | + } | ||
473 | + | ||
474 | + /** | ||
475 | + * 初始化应用或模块 | ||
476 | + * @access public | ||
477 | + * @param string $module 模块名 | ||
478 | + * @return array | ||
479 | + */ | ||
480 | + private static function init($module = '') | ||
481 | + { | ||
482 | + // 定位模块目录 | ||
483 | + $module = $module ? $module . DS : ''; | ||
484 | + | ||
485 | + // 加载初始化文件 | ||
486 | + if (is_file(APP_PATH . $module . 'init' . EXT)) { | ||
487 | + include APP_PATH . $module . 'init' . EXT; | ||
488 | + } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { | ||
489 | + include RUNTIME_PATH . $module . 'init' . EXT; | ||
490 | + } else { | ||
491 | + $path = APP_PATH . $module; | ||
492 | + // 加载模块配置 | ||
493 | + $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); | ||
494 | + // 读取数据库配置文件 | ||
495 | + $filename = CONF_PATH . $module . 'database' . CONF_EXT; | ||
496 | + Config::load($filename, 'database'); | ||
497 | + // 读取扩展配置文件 | ||
498 | + if (is_dir(CONF_PATH . $module . 'extra')) { | ||
499 | + $dir = CONF_PATH . $module . 'extra'; | ||
500 | + $files = scandir($dir); | ||
501 | + foreach ($files as $file) { | ||
502 | + if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { | ||
503 | + $filename = $dir . DS . $file; | ||
504 | + Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); | ||
505 | + } | ||
506 | + } | ||
507 | + } | ||
508 | + | ||
509 | + // 加载应用状态配置 | ||
510 | + if ($config['app_status']) { | ||
511 | + $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); | ||
512 | + } | ||
513 | + | ||
514 | + // 加载行为扩展文件 | ||
515 | + if (is_file(CONF_PATH . $module . 'tags' . EXT)) { | ||
516 | + Hook::import(include CONF_PATH . $module . 'tags' . EXT); | ||
517 | + } | ||
518 | + | ||
519 | + // 加载公共文件 | ||
520 | + if (is_file($path . 'common' . EXT)) { | ||
521 | + include $path . 'common' . EXT; | ||
522 | + } | ||
523 | + | ||
524 | + // 加载当前模块语言包 | ||
525 | + if ($module) { | ||
526 | + Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); | ||
527 | + } | ||
528 | + } | ||
529 | + return Config::get(); | ||
530 | + } | ||
531 | + | ||
532 | + /** | ||
533 | + * URL路由检测(根据PATH_INFO) | ||
534 | + * @access public | ||
535 | + * @param \think\Request $request | ||
536 | + * @param array $config | ||
537 | + * @return array | ||
538 | + * @throws \think\Exception | ||
539 | + */ | ||
540 | + public static function routeCheck($request, array $config) | ||
541 | + { | ||
542 | + $path = $request->path(); | ||
543 | + $depr = $config['pathinfo_depr']; | ||
544 | + $result = false; | ||
545 | + // 路由检测 | ||
546 | + $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; | ||
547 | + if ($check) { | ||
548 | + // 开启路由 | ||
549 | + if (is_file(RUNTIME_PATH . 'route.php')) { | ||
550 | + // 读取路由缓存 | ||
551 | + $rules = include RUNTIME_PATH . 'route.php'; | ||
552 | + if (is_array($rules)) { | ||
553 | + Route::rules($rules); | ||
554 | + } | ||
555 | + } else { | ||
556 | + $files = $config['route_config_file']; | ||
557 | + foreach ($files as $file) { | ||
558 | + if (is_file(CONF_PATH . $file . CONF_EXT)) { | ||
559 | + // 导入路由配置 | ||
560 | + $rules = include CONF_PATH . $file . CONF_EXT; | ||
561 | + if (is_array($rules)) { | ||
562 | + Route::import($rules); | ||
563 | + } | ||
564 | + } | ||
565 | + } | ||
566 | + } | ||
567 | + | ||
568 | + // 路由检测(根据路由定义返回不同的URL调度) | ||
569 | + $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); | ||
570 | + $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; | ||
571 | + if ($must && false === $result) { | ||
572 | + // 路由无效 | ||
573 | + throw new RouteNotFoundException(); | ||
574 | + } | ||
575 | + } | ||
576 | + if (false === $result) { | ||
577 | + // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 | ||
578 | + $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); | ||
579 | + } | ||
580 | + return $result; | ||
581 | + } | ||
582 | + | ||
583 | + /** | ||
584 | + * 设置应用的路由检测机制 | ||
585 | + * @access public | ||
586 | + * @param bool $route 是否需要检测路由 | ||
587 | + * @param bool $must 是否强制检测路由 | ||
588 | + * @return void | ||
589 | + */ | ||
590 | + public static function route($route, $must = false) | ||
591 | + { | ||
592 | + self::$routeCheck = $route; | ||
593 | + self::$routeMust = $must; | ||
594 | + } | ||
595 | +} |
-
请 注册 或 登录 后发表评论