作者 魏强

4.4

正在显示 31 个修改的文件 包含 1242 行增加674 行删除
@@ -10,6 +10,9 @@ return [ @@ -10,6 +10,9 @@ return [
10 // | 应用设置 10 // | 应用设置
11 // +---------------------------------------------------------------------- 11 // +----------------------------------------------------------------------
12 12
  13 + //wechat
  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);
  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' => '停用管理员',
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 // [ 入口文件 ] 10 // [ 入口文件 ]
11 11
12 // 调试模式开关 12 // 调试模式开关
13 -define("APP_DEBUG", true); 13 +define("APP_DEBUG", false);
14 14
15 // 定义CMF根目录,可更改此目录 15 // 定义CMF根目录,可更改此目录
16 define('CMF_ROOT', __DIR__ . '/../'); 16 define('CMF_ROOT', __DIR__ . '/../');
@@ -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"> &nbsp; &nbsp;
  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>
  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 +}
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 +}