stanley-king 1 year atrás
parent
commit
6f468d290d
100 changed files with 23128 additions and 12 deletions
  1. 130 0
      docker/compose/homecuda/conf/nginx/mapi.conf
  2. 40 0
      docker/compose/homecuda/mapi/docker-compose.yml
  3. 1 12
      docker/compose/homecuda/worker/docker-compose.yml
  4. 98 0
      mapi/alipay_notify_url.php
  5. 11 0
      mapi/api/payment/wxpay/lib/SDKRuntimeException.php
  6. 37 0
      mapi/api/payment/wxpay/lib/WxPay.pub.config.php
  7. 896 0
      mapi/api/payment/wxpay/lib/WxPayPubHelper.php
  8. 16 0
      mapi/api/payment/wxpay/lib/log_.php
  9. 33 0
      mapi/api/payment/wxpay/lib/notify_url.log
  10. 68 0
      mapi/api/payment/wxpay/notify_url.php
  11. 5 0
      mapi/api/payment/wxpay/redirect_uri.php
  12. 176 0
      mapi/api/payment/wxpay/wxpay.php
  13. 10 0
      mapi/bridge_shr.php
  14. 17 0
      mapi/cmbpay_notify.php
  15. 11 0
      mapi/cmbpay_sign.php
  16. 3 0
      mapi/config/config.ini.php
  17. 448 0
      mapi/control/activity.php
  18. 549 0
      mapi/control/admin_oper.php
  19. 152 0
      mapi/control/app_update.php
  20. 33 0
      mapi/control/article.php
  21. 462 0
      mapi/control/bargain.php
  22. 1132 0
      mapi/control/bonusex.php
  23. 36 0
      mapi/control/brand.php
  24. 882 0
      mapi/control/cart.php
  25. 20 0
      mapi/control/category.php
  26. 58 0
      mapi/control/config.php
  27. 412 0
      mapi/control/control.php
  28. 177 0
      mapi/control/convert.php
  29. 47 0
      mapi/control/crash_log.php
  30. 7 0
      mapi/control/enterprise_certs.php
  31. 171 0
      mapi/control/fcode.php
  32. 657 0
      mapi/control/festval.php
  33. 78 0
      mapi/control/game.php
  34. 39 0
      mapi/control/goods.php
  35. 342 0
      mapi/control/goods_common.php
  36. 27 0
      mapi/control/home.php
  37. 297 0
      mapi/control/index.php
  38. 306 0
      mapi/control/inoherb.php
  39. 348 0
      mapi/control/invite_friend.php
  40. 124 0
      mapi/control/log.php
  41. 858 0
      mapi/control/login.php
  42. 391 0
      mapi/control/member_address.php
  43. 1548 0
      mapi/control/member_bonus.php
  44. 514 0
      mapi/control/member_buy.php
  45. 116 0
      mapi/control/member_card.php
  46. 23 0
      mapi/control/member_cart.php
  47. 306 0
      mapi/control/member_evaluate.php
  48. 162 0
      mapi/control/member_favorites.php
  49. 155 0
      mapi/control/member_fcode.php
  50. 50 0
      mapi/control/member_feedback.php
  51. 293 0
      mapi/control/member_info.php
  52. 146 0
      mapi/control/member_invitee.php
  53. 125 0
      mapi/control/member_invoice.php
  54. 27 0
      mapi/control/member_logout.php
  55. 309 0
      mapi/control/member_message.php
  56. 114 0
      mapi/control/member_notice.php
  57. 435 0
      mapi/control/member_order.php
  58. 116 0
      mapi/control/member_payment.php
  59. 473 0
      mapi/control/member_refund.php
  60. 280 0
      mapi/control/member_relation.php
  61. 1456 0
      mapi/control/member_talk.php
  62. 735 0
      mapi/control/member_ugc.php
  63. 355 0
      mapi/control/member_vorder.php
  64. 34 0
      mapi/control/member_voucher.php
  65. 106 0
      mapi/control/member_vr_buy.php
  66. 556 0
      mapi/control/merchant_info.php
  67. 54 0
      mapi/control/merchant_login.php
  68. 289 0
      mapi/control/merchant_order.php
  69. 133 0
      mapi/control/merchant_refill.php
  70. 159 0
      mapi/control/merchantweb.php
  71. 264 0
      mapi/control/mshop.php
  72. 32 0
      mapi/control/mtest.php
  73. 44 0
      mapi/control/patch.php
  74. 48 0
      mapi/control/pay_return.php
  75. 228 0
      mapi/control/payment.php
  76. 158 0
      mapi/control/rank_list.php
  77. 59 0
      mapi/control/room.php
  78. 931 0
      mapi/control/search.php
  79. 908 0
      mapi/control/special.php
  80. 43 0
      mapi/control/umeng.php
  81. 29 0
      mapi/control/uploader.php
  82. 219 0
      mapi/control/user_index.php
  83. 141 0
      mapi/control/webpush.php
  84. 61 0
      mapi/dispatch_notify.php
  85. 124 0
      mapi/framework/function/function.php
  86. 1 0
      mapi/framework/index.html
  87. 9 0
      mapi/index.php
  88. 3 0
      mapi/innercb.php
  89. 46 0
      mapi/kdniao_notify.php
  90. 0 0
      mapi/language/index.html
  91. 10 0
      mapi/language/zh_cn/mobile.php
  92. 73 0
      mapi/mobile_run.php
  93. 96 0
      mapi/pub_wxnotify.php
  94. 36 0
      mapi/signature.php
  95. 176 0
      mapi/templates/default/activity/limit_entra.php
  96. 75 0
      mapi/templates/default/article/show.php
  97. 448 0
      mapi/templates/default/bargain/bargain.php
  98. 91 0
      mapi/templates/default/bonus/bind.php
  99. 101 0
      mapi/templates/default/bonus/detail.php
  100. 0 0
      mapi/templates/default/bonus/end.php

+ 130 - 0
docker/compose/homecuda/conf/nginx/mapi.conf

@@ -0,0 +1,130 @@
+user nginx;
+worker_processes  16;
+error_log   /var/error.log  info;
+worker_rlimit_nofile 10240;
+
+events {
+    worker_connections  8192;
+    multi_accept on;
+    use epoll;
+}
+
+http 
+{
+    include       mime.types;
+    default_type  application/octet-stream;
+
+    underscores_in_headers on;
+    client_max_body_size 32M;
+    client_body_buffer_size 1024K;
+
+    tcp_nopush on;
+
+    sendfile            on;
+    keepalive_timeout   300;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    server 
+    {
+    	listen       80;
+        set  $folder_name /var/www/html;
+        server_name 192.168.3.104;
+        root $folder_name;
+        index index.html index.php; 
+
+    	proxy_connect_timeout 500s;
+        proxy_read_timeout 500s;
+        proxy_send_timeout 500s;
+
+        fastcgi_connect_timeout 75;
+        fastcgi_read_timeout 600;   
+        fastcgi_send_timeout 600;
+        fastcgi_buffer_size  32K;
+        fastcgi_buffers      32 32K;
+
+        set_real_ip_from 100.64.0.0/10;
+        real_ip_header X-Forwarded-For;
+
+        charset utf-8;
+        
+        location /logs {
+            deny all;
+            return 403;
+        }
+
+        location /data/log {
+            deny all;
+            return 403;
+        }
+        location / {
+            index  index.html index.htm index.php;
+        }
+        
+        location /mshop {
+            root $folder_name;
+            autoindex on;        
+            index  index.html index.htm index.php;
+	        try_files $uri $uri/ /mshop/index.html;
+        }
+
+        location /plot {
+            deny all;
+            return 403;
+        }
+
+        location /merchant {
+            deny all;
+            return 403;
+        }
+
+        location ~ /mobile {
+            deny all;
+            return 403;
+        }
+
+        location ~ /racc/[/\w]+\.php$ {
+            deny all;
+            return 403;
+        }
+
+        location ~ /mchsrv/[/\w]+\.php$ {
+            deny all;
+            return 403;
+        }
+
+        ################################################################################################################
+        location ~ /mapi/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   mapi:9000;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param  SIGN $http_sign;
+            include fastcgi_params;
+        }
+        location ~ /mapi/[/\w]+\.html$ {
+            try_files $uri $uri/ /mobile/index.html;
+        }
+
+        location ~ \.php$ {
+	        add_header Cache-Control no-store;
+            root           $folder_name;
+            fastcgi_pass   mapi:9000;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_buffer_size  1024K;
+            fastcgi_buffers      32 1024K;
+            proxy_buffer_size  128k;
+            proxy_buffers 100  128k;
+            proxy_read_timeout 900s;
+            proxy_send_timeout 900s;
+            fastcgi_read_timeout 900;
+            fastcgi_send_timeout 900;
+            keepalive_timeout    900;
+
+            include        fastcgi_params;
+        }
+    }
+}

+ 40 - 0
docker/compose/homecuda/mapi/docker-compose.yml

@@ -0,0 +1,40 @@
+version: "3.7"
+
+services:
+  nginx:
+    image: nginx:alpine
+    ports:
+      - 8100:80
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
+      - /mnt/upload:/var/www/html/data/upload
+      - /mnt/merchant:/var/www/html/merchant
+    container_name: "panda-nginx"
+    command: [nginx,'-g','daemon off;']
+    extra_hosts:
+      - "docker.hostip:172.17.0.1"
+
+  mapi:
+    image: php-zts:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php-debug.ini:/usr/local/etc/php/php.ini
+      - /mnt/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../conf/php/mobile-spwan-start:/usr/local/bin/docker-spwan-start
+    container_name: "panda-mapi"
+    command: ['docker-spwan-start']
+
+  searcher:
+    image: php-zts:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /data/shop_share/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-searcher"
+    command: [php, "/var/www/html/searcher.php"]

+ 1 - 12
docker/compose/homecuda/worker/docker-compose.yml

@@ -25,15 +25,4 @@ services:
       - /data/shop_share/upload:/var/www/html/data/upload
       - /mnt/shoplog:/var/www/html/data/log
     container_name: "panda-queue"
-    command: [php,"/var/www/html/queue/index.php", "queue", "index"]
-
-  searcher:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../../../:/var/www/html
-      - ../conf/etc/localtime:/etc/localtime:ro
-      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
-      - /data/shop_share/upload:/var/www/html/data/upload
-      - /mnt/shoplog:/var/www/html/data/log
-    container_name: "panda-searcher"
-    command: [php, "/var/www/html/searcher.php"]
+    command: [php,"/var/www/html/queue/index.php", "queue", "index"]

+ 98 - 0
mapi/alipay_notify_url.php

@@ -0,0 +1,98 @@
+<?php
+
+require_once(BASE_ROOT_PATH   . '/helper/pay_helper.php');
+require_once(BASE_DATA_PATH   . '/logic/delivery.logic.php');
+
+$pay_sn = $_POST['out_trade_no'];       // 商户订单号
+$trade_no = $_POST['trade_no'];         // 支付宝交易号
+
+Log::record("alipay_notify_url: pay_sn={$pay_sn} total_fee={$total_fee}", Log::DEBUG);
+
+
+// 步骤一:验证数据来源正确性
+if(defined('SERVER_TYPE') && SERVER_TYPE == 'panda')
+{
+    define(ALIPAY_PATH, BASE_DATA_PATH . '/api/alipay');
+    require_once(ALIPAY_PATH . '/alipay.config.php');
+    require_once(ALIPAY_PATH . '/lib/alipay_notify.class.php');
+
+    $alipayNotify = new AlipayNotify($alipay_config);
+    $verify_result = $alipayNotify->verifyReturn();
+
+    $total_fee = doubleval(trim($_POST['total_fee']));
+
+    Log::record("走pandaup 阿里支付验签过程", Log::DEBUG);
+}
+elseif(defined('SERVER_TYPE') && SERVER_TYPE == 'car') {
+    $ipay = new pay\aopay();
+    $verify_result = $ipay->verify($_POST);
+    $total_fee = doubleval(trim($_POST['total_amount']));
+    Log::record("走pandaup 阿里支付验签过程", Log::DEBUG);
+}
+else {
+    Log::record("没有找到阿里支付密钥",Log::DEBUG);
+}
+
+Log::record("verify_result={$verify_result}, pay_sn={$pay_sn},", Log::DEBUG);
+fcgi_header("Content-Type: text/plain; charset=UTF-8\r\n\r\n");
+
+Log::record("ali post data:{$_SERVER['post_content']}",Log::DEBUG);
+
+if ($verify_result)
+{
+    $payer = new pay_helper($pay_sn);
+
+    $trade_status = $_POST['trade_status'];
+    if ($trade_status === 'TRADE_FINISHED' || $trade_status === 'TRADE_SUCCESS')
+    {
+        if($payer->paied()) {
+            echo('success'); //该订单已经支付
+            return;
+        }
+
+        $chk = $payer->check_fee($total_fee,$need_pay);
+        if($chk == false) {
+            Log::record("AliPay check: pay_sn={$pay_sn},total_fee={$total_fee},need_pay={$need_pay}",Log::ERR);
+            echo("fail");
+            return;
+        }
+        else
+        {
+            Log::record("AliPay check: pay_sn={$pay_sn},total_fee={$total_fee},need_pay={$need_pay}",Log::DEBUG);
+            // 步骤二:更新订单状态
+            $cb_info = $payer->update_order($trade_no, 'alipay');
+            if ($cb_info['state'] == false) {
+                Log::record("update_order fail: pay_sn={$pay_sn}", Log::DEBUG);
+                echo('fail');
+                return;
+            }
+            else
+            {
+                if(is_pushoms()) {
+                    $logic_delivery = Logic('delivery');
+                    $ret = $logic_delivery->putOrder($pay_sn, $trade_no);
+                    Log::record("update_order success: pay_sn={$pay_sn}", Log::DEBUG);
+                }
+                $payer->OnSuccess();
+
+                echo('success');
+                return;
+            }
+         }
+    }
+    elseif ($trade_status == 'WAIT_BUYER_PAY') {
+
+    }
+    else {
+
+    }
+    echo("success"); // 交易正确时,返回success
+    return;
+}
+else
+{
+    Log::record("verify notify fail : pay_sn={$pay_sn}");
+    echo("fail");
+    return;
+}
+?>

+ 11 - 0
mapi/api/payment/wxpay/lib/SDKRuntimeException.php

@@ -0,0 +1,11 @@
+<?php
+
+class  SDKRuntimeException extends Exception {
+	public function errorMessage()
+	{
+		return $this->getMessage();
+	}
+
+}
+
+?>

+ 37 - 0
mapi/api/payment/wxpay/lib/WxPay.pub.config.php

@@ -0,0 +1,37 @@
+<?php
+/**
+* 	配置账号信息
+*/
+
+class WxPayConf_pub
+{
+	//=======【基本信息设置】=====================================
+	//微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
+	const APPID = 'wx24c5645aa986234a';
+	//受理商ID,身份标识
+	const MCHID = '1279745801';
+	//商户支付密钥Key。审核通过后,在微信发送的邮件中查看
+	const KEY = 'e5f421ca4df74abcfa8451d7a3f8142e';
+	//JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
+	const APPSECRET = '41f93fef3207e917e742b9ebcd540cb2';
+	
+	//=======【JSAPI路径设置】===================================
+	//获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面
+	const JS_API_CALL_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx181c8e7c3b271a9c&redirect_uri=http://www.huilx.com/mobile/api/payment/wxpay/wxpay.php';
+
+	//'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx6d584353dde12089&secret=ebe955894869c8e6adf02688f3674518'
+	//=======【证书路径设置】=====================================
+	//证书路径,注意应该填写绝对路径
+	const SSLCERT_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_cert.pem';
+	const SSLKEY_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_key.pem';
+	
+	//=======【异步通知url设置】===================================
+	//异步通知url,商户根据实际开发过程设定
+	const NOTIFY_URL = 'http://www.huilx.com/mobile/api/payment/wxpay/notify_url.php';
+
+	//=======【curl超时设置】===================================
+	//本例程通过curl使用HTTP POST方法,此处可修改其超时时间,默认为30秒
+	const CURL_TIMEOUT = 30;
+}
+	
+?>

+ 896 - 0
mapi/api/payment/wxpay/lib/WxPayPubHelper.php

@@ -0,0 +1,896 @@
+<?php
+/**
+ * 微信支付帮助库
+ * ====================================================
+ * 接口分三种类型:
+ * 【请求型接口】--Wxpay_client_
+ * 		统一支付接口类--UnifiedOrder
+ * 		订单查询接口--OrderQuery
+ * 		退款申请接口--Refund
+ * 		退款查询接口--RefundQuery
+ * 		对账单接口--DownloadBill
+ * 		短链接转换接口--ShortUrl
+ * 【响应型接口】--Wxpay_server_
+ * 		通用通知接口--Notify
+ * 		Native支付——请求商家获取商品信息接口--NativeCall
+ * 【其他】
+ * 		静态链接二维码--NativeLink
+ * 		JSAPI支付--JsApi
+ * =====================================================
+ * 【CommonUtil】常用工具:
+ * 		trimString(),设置参数时需要用到的字符处理函数
+ * 		createNoncestr(),产生随机字符串,不长于32位
+ * 		formatBizQueryParaMap(),格式化参数,签名过程需要用到
+ * 		getSign(),生成签名
+ * 		arrayToXml(),array转xml
+ * 		xmlToArray(),xml转 array
+ * 		postXmlCurl(),以post方式提交xml到对应的接口url
+ * 		postXmlSSLCurl(),使用证书,以post方式提交xml到对应的接口url
+*/
+	include_once("SDKRuntimeException.php");
+	include_once("WxPay.pub.config.php");
+	include_once("log_.php");
+
+/**
+ * 所有接口的基类
+ */
+class Common_util_pub
+{
+
+
+	function __construct() {
+	}
+
+	function trimString($value)
+	{
+		$ret = null;
+		if (null != $value) 
+		{
+			$ret = $value;
+			if (strlen($ret) == 0) 
+			{
+				$ret = null;
+			}
+		}
+		return $ret;
+	}
+	
+	/**
+	 * 	作用:产生随机字符串,不长于32位
+	 */
+	public function createNoncestr( $length = 32 ) 
+	{
+		$chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
+		$str ="";
+		for ( $i = 0; $i < $length; $i++ )  {  
+			$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
+		}  
+		return $str;
+	}
+	
+	/**
+	 * 	作用:格式化参数,签名过程需要使用
+	 */
+	function formatBizQueryParaMap($paraMap, $urlencode)
+	{
+		$buff = "";
+		ksort($paraMap);
+		foreach ($paraMap as $k => $v)
+		{
+		    if($urlencode)
+		    {
+			   $v = urlencode($v);
+			}
+			//$buff .= strtolower($k) . "=" . $v . "&";
+			$buff .= $k . "=" . $v . "&";
+		}
+		$reqPar;
+		if (strlen($buff) > 0) 
+		{
+			$reqPar = substr($buff, 0, strlen($buff)-1);
+		}
+		return $reqPar;
+	}
+	
+	/**
+	 * 	作用:生成签名
+	 */
+	public function getSign($Obj)
+	{
+		foreach ($Obj as $k => $v)
+		{
+			$Parameters[$k] = $v;
+		}
+		//签名步骤一:按字典序排序参数
+		ksort($Parameters);
+		$String = $this->formatBizQueryParaMap($Parameters, false);
+		//echo '【string1】'.$String.'</br>';
+		//签名步骤二:在string后加入KEY
+		$String = $String."&key=".WxPayConf_pub::KEY;
+		//echo "【string2】".$String."</br>";
+		//签名步骤三:MD5加密
+		$String = md5($String);
+		//echo "【string3】 ".$String."</br>";
+		//签名步骤四:所有字符转为大写
+		$result_ = strtoupper($String);
+		//echo "【result】 ".$result_."</br>";
+		return $result_;
+	}
+	
+	/**
+	 * 	作用:array转xml
+	 */
+	function arrayToXml($arr)
+    {
+        $xml = "<xml>";
+        foreach ($arr as $key=>$val)
+        {
+        	 if (is_numeric($val))
+        	 {
+        	 	$xml.="<".$key.">".$val."</".$key.">"; 
+
+        	 }
+        	 else
+        	 	$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";  
+        }
+        $xml.="</xml>";
+        return $xml; 
+    }
+	
+	/**
+	 * 	作用:将xml转为array
+	 */
+	public function xmlToArray($xml)
+	{		
+        //将XML转为array        
+        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);		
+		return $array_data;
+	}
+
+	/**
+	 * 	作用:以post方式提交xml到对应的接口url
+	 */
+	public function postXmlCurl($xml,$url,$second=30)
+	{
+		//以log文件形式记录回调信息
+		$log_ = new Log_();
+		$log_name="./notify_url.log";//log文件路径
+		$log_->log_result($log_name,"【postXmlCurl xml】:\n".$xml."\n");
+		$log_->log_result($log_name,"【postXmlCurl url】:\n".$url."\n");
+        //初始化curl        
+       	$ch = curl_init();
+		//设置超时
+		curl_setopt($ch, CURLOPT_TIMEOUT, $second);
+        //这里设置代理,如果有的话
+        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
+        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
+        curl_setopt($ch,CURLOPT_URL, $url);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
+		//设置header
+		curl_setopt($ch, CURLOPT_HEADER, FALSE);
+		//要求结果为字符串且输出到屏幕上
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+		//post提交方式
+		curl_setopt($ch, CURLOPT_POST, TRUE);
+		curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+		//运行curl
+        $data = curl_exec($ch);
+		curl_close($ch);
+		//返回结果
+		if($data)
+		{
+			//curl_close($ch);
+			return $data;
+		}
+		else 
+		{ 
+			$error = curl_errno($ch);
+			echo "curl出错,错误码:$error"."<br>"; 
+			echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
+			curl_close($ch);
+			return false;
+		}
+	}
+
+	/**
+	 * 	作用:使用证书,以post方式提交xml到对应的接口url
+	 */
+	function postXmlSSLCurl($xml,$url,$second=30)
+	{
+		$ch = curl_init();
+		//超时时间
+		curl_setopt($ch,CURLOPT_TIMEOUT,$second);
+		//这里设置代理,如果有的话
+        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
+        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
+        curl_setopt($ch,CURLOPT_URL, $url);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
+		//设置header
+		curl_setopt($ch,CURLOPT_HEADER,FALSE);
+		//要求结果为字符串且输出到屏幕上
+		curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
+		//设置证书
+		//使用证书:cert 与 key 分别属于两个.pem文件
+		//默认格式为PEM,可以注释
+		curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
+		curl_setopt($ch,CURLOPT_SSLCERT, WxPayConf_pub::SSLCERT_PATH);
+		//默认格式为PEM,可以注释
+		curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
+		curl_setopt($ch,CURLOPT_SSLKEY, WxPayConf_pub::SSLKEY_PATH);
+		//post提交方式
+		curl_setopt($ch,CURLOPT_POST, true);
+		curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
+		$data = curl_exec($ch);
+		//返回结果
+		if($data){
+			curl_close($ch);
+			return $data;
+		}
+		else { 
+			$error = curl_errno($ch);
+			echo "curl出错,错误码:$error"."<br>"; 
+			echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
+			curl_close($ch);
+			return false;
+		}
+	}
+	
+	/**
+	 * 	作用:打印数组
+	 */
+	function printErr($wording='',$err='')
+	{
+		print_r('<pre>');
+		echo $wording."</br>";
+		var_dump($err);
+		print_r('</pre>');
+	}
+}
+
+/**
+ * 请求型接口的基类
+ */
+class Wxpay_client_pub extends Common_util_pub 
+{
+	var $parameters;//请求参数,类型为关联数组
+	public $response;//微信返回的响应
+	public $result;//返回参数,类型为关联数组
+	var $url;//接口链接
+	var $curl_timeout;//curl超时时间
+	
+	/**
+	 * 	作用:设置请求参数
+	 */
+	function setParameter($parameter, $parameterValue)
+	{
+		$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
+	}
+	
+	/**
+	 * 	作用:设置标配的请求参数,生成签名,生成接口参数xml
+	 */
+	function createXml()
+	{
+	   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+	   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+	    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+	    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+	    return  $this->arrayToXml($this->parameters);
+	}
+	
+	/**
+	 * 	作用:post请求xml
+	 */
+	function postXml()
+	{
+		//以log文件形式记录回调信息
+		$log_ = new Log_();
+		$log_name="./notify_url.log";//log文件路径
+		$log_->log_result($log_name,"【postXml 】:\n\n");
+
+
+
+	    $xml = $this->createXml();
+
+		$log_->log_result($log_name,"【xml 】:\n".$xml."\n");
+		$log_->log_result($log_name,"【url 】:\n".$this->url."\n");
+		$this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout);
+		return $this->response;
+	}
+	
+	/**
+	 * 	作用:使用证书post请求xml
+	 */
+	function postXmlSSL()
+	{	
+	    $xml = $this->createXml();
+		$this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
+		return $this->response;
+	}
+
+	/**
+	 * 	作用:获取结果,默认不使用证书
+	 */
+	function getResult() 
+	{		
+		$this->postXml();
+		$this->result = $this->xmlToArray($this->response);
+		return $this->result;
+	}
+}
+
+
+/**
+ * 统一支付接口类
+ */
+class UnifiedOrder_pub extends Wxpay_client_pub
+{	
+	function __construct() 
+	{
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
+	}
+	
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{
+		try
+		{
+			//检测必填参数
+			if($this->parameters["out_trade_no"] == null) 
+			{
+				throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>");
+			}elseif($this->parameters["body"] == null){
+				throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>");
+			}elseif ($this->parameters["total_fee"] == null ) {
+				throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>");
+			}elseif ($this->parameters["notify_url"] == null) {
+				throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!"."<br>");
+			}elseif ($this->parameters["trade_type"] == null) {
+				throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!"."<br>");
+			}elseif ($this->parameters["trade_type"] == "JSAPI" &&
+				$this->parameters["openid"] == NULL){
+				throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		   	$this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip	    
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+	
+	/**
+	 * 获取prepay_id
+	 */
+	function getPrepayId()
+	{
+		//以log文件形式记录回调信息
+		$log_ = new Log_();
+		$log_name="./notify_url.log";//log文件路径
+
+		$this->postXml();
+		$this->result = $this->xmlToArray($this->response);
+		$log_->log_result($log_name,"【接收到的notify通知】:\n".$this->response."\n");
+		$prepay_id = $this->result["prepay_id"];
+		$log_->log_result($log_name,"【接收到的notify通知】:\n".$prepay_id."\n");
+		return $prepay_id;
+	}
+	
+}
+
+/**
+ * 订单查询接口
+ */
+class OrderQuery_pub extends Wxpay_client_pub
+{
+	function __construct() 
+	{
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/pay/orderquery";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;		
+	}
+
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{
+		try
+		{
+			//检测必填参数
+			if($this->parameters["out_trade_no"] == null && 
+				$this->parameters["transaction_id"] == null) 
+			{
+				throw new SDKRuntimeException("订单查询接口中,out_trade_no、transaction_id至少填一个!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+
+}
+
+/**
+ * 退款申请接口
+ */
+class Refund_pub extends Wxpay_client_pub
+{
+	
+	function __construct() {
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;		
+	}
+	
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{
+		try
+		{
+			//检测必填参数
+			if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) {
+				throw new SDKRuntimeException("退款申请接口中,out_trade_no、transaction_id至少填一个!"."<br>");
+			}elseif($this->parameters["out_refund_no"] == null){
+				throw new SDKRuntimeException("退款申请接口中,缺少必填参数out_refund_no!"."<br>");
+			}elseif($this->parameters["total_fee"] == null){
+				throw new SDKRuntimeException("退款申请接口中,缺少必填参数total_fee!"."<br>");
+			}elseif($this->parameters["refund_fee"] == null){
+				throw new SDKRuntimeException("退款申请接口中,缺少必填参数refund_fee!"."<br>");
+			}elseif($this->parameters["op_user_id"] == null){
+				throw new SDKRuntimeException("退款申请接口中,缺少必填参数op_user_id!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+	/**
+	 * 	作用:获取结果,使用证书通信
+	 */
+	function getResult() 
+	{		
+		$this->postXmlSSL();
+		$this->result = $this->xmlToArray($this->response);
+		return $this->result;
+	}
+	
+}
+
+
+/**
+ * 退款查询接口
+ */
+class RefundQuery_pub extends Wxpay_client_pub
+{
+	
+	function __construct() {
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/pay/refundquery";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;		
+	}
+	
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{		
+		try 
+		{
+			if($this->parameters["out_refund_no"] == null &&
+				$this->parameters["out_trade_no"] == null &&
+				$this->parameters["transaction_id"] == null &&
+				$this->parameters["refund_id "] == null) 
+			{
+				throw new SDKRuntimeException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+
+	/**
+	 * 	作用:获取结果,使用证书通信
+	 */
+	function getResult() 
+	{		
+		$this->postXmlSSL();
+		$this->result = $this->xmlToArray($this->response);
+		return $this->result;
+	}
+
+}
+
+/**
+ * 对账单接口
+ */
+class DownloadBill_pub extends Wxpay_client_pub
+{
+
+	function __construct() 
+	{
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/pay/downloadbill";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;		
+	}
+
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{		
+		try 
+		{
+			if($this->parameters["bill_date"] == null ) 
+			{
+				throw new SDKRuntimeException("对账单接口中,缺少必填参数bill_date!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+	
+	/**
+	 * 	作用:获取结果,默认不使用证书
+	 */
+	function getResult() 
+	{		
+		$this->postXml();
+		$this->result = $this->xmlToArray($this->result_xml);
+		return $this->result;
+	}
+	
+	
+
+}
+
+/**
+ * 短链接转换接口
+ */
+class ShortUrl_pub extends Wxpay_client_pub
+{
+	function __construct() 
+	{
+		//设置接口链接
+		$this->url = "https://api.mch.weixin.qq.com/tools/shorturl";
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;		
+	}
+	
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{		
+		try 
+		{
+			if($this->parameters["long_url"] == null ) 
+			{
+				throw new SDKRuntimeException("短链接转换接口中,缺少必填参数long_url!"."<br>");
+			}
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名
+		    return  $this->arrayToXml($this->parameters);
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+	
+	/**
+	 * 获取prepay_id
+	 */
+	function getShortUrl()
+	{
+		$this->postXml();
+		$prepay_id = $this->result["short_url"];
+		return $prepay_id;
+	}
+	
+}
+
+/**
+ * 响应型接口基类
+ */
+class Wxpay_server_pub extends Common_util_pub 
+{
+	public $data;//接收到的数据,类型为关联数组
+	var $returnParameters;//返回参数,类型为关联数组
+	
+	/**
+	 * 将微信的请求xml转换成关联数组,以方便数据处理
+	 */
+	function saveData($xml)
+	{
+		$this->data = $this->xmlToArray($xml);
+	}
+	
+	function checkSign()
+	{
+		$tmpData = $this->data;
+		unset($tmpData['sign']);
+		$sign = $this->getSign($tmpData);//本地签名
+		if ($this->data['sign'] == $sign) {
+			return TRUE;
+		}
+		return FALSE;
+	}
+	
+	/**
+	 * 获取微信的请求数据
+	 */
+	function getData()
+	{		
+		return $this->data;
+	}
+	
+	/**
+	 * 设置返回微信的xml数据
+	 */
+	function setReturnParameter($parameter, $parameterValue)
+	{
+		$this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
+	}
+	
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{
+		return $this->arrayToXml($this->returnParameters);
+	}
+	
+	/**
+	 * 将xml数据返回微信
+	 */
+	function returnXml()
+	{
+		$returnXml = $this->createXml();
+		return $returnXml;
+	}
+}
+
+
+/**
+ * 通用通知接口
+ */
+class Notify_pub extends Wxpay_server_pub 
+{
+
+}
+
+
+
+
+/**
+ * 请求商家获取商品信息接口
+ */
+class NativeCall_pub extends Wxpay_server_pub
+{
+	/**
+	 * 生成接口参数xml
+	 */
+	function createXml()
+	{
+		if($this->returnParameters["return_code"] == "SUCCESS"){
+		   	$this->returnParameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->returnParameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		    $this->returnParameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->returnParameters["sign"] = $this->getSign($this->returnParameters);//签名
+		}
+		return $this->arrayToXml($this->returnParameters);
+	}
+	
+	/**
+	 * 获取product_id
+	 */
+	function getProductId()
+	{
+		$product_id = $this->data["product_id"];
+		return $product_id;
+	}
+	
+}
+
+/**
+ * 静态链接二维码
+ */
+class NativeLink_pub  extends Common_util_pub
+{
+	var $parameters;//静态链接参数
+	var $url;//静态链接
+
+	function __construct() 
+	{
+	}
+	
+	/**
+	 * 设置参数
+	 */
+	function setParameter($parameter, $parameterValue) 
+	{
+		$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
+	}
+	
+	/**
+	 * 生成Native支付链接二维码
+	 */
+	function createLink()
+	{
+		try 
+		{		
+			if($this->parameters["product_id"] == null) 
+			{
+				throw new SDKRuntimeException("缺少Native支付二维码链接必填参数product_id!"."<br>");
+			}			
+		   	$this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID
+		   	$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号
+		   	$time_stamp = time();
+		   	$this->parameters["time_stamp"] = "$time_stamp";//时间戳
+		    $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
+		    $this->parameters["sign"] = $this->getSign($this->parameters);//签名    		
+			$bizString = $this->formatBizQueryParaMap($this->parameters, false);
+		    $this->url = "weixin://wxpay/bizpayurl?".$bizString;
+		}catch (SDKRuntimeException $e)
+		{
+			die($e->errorMessage());
+		}
+	}
+	
+	/**
+	 * 返回链接
+	 */
+	function getUrl() 
+	{		
+		$this->createLink();
+		return $this->url;
+	}
+}
+
+/**
+* JSAPI支付——H5网页端调起支付接口
+*/
+class JsApi_pub extends Common_util_pub
+{
+	var $code;//code码,用以获取openid
+	var $openid;//用户的openid
+	var $parameters;//jsapi参数,格式为json
+	var $prepay_id;//使用统一支付接口得到的预支付id
+	var $curl_timeout;//curl超时时间
+
+	function __construct() 
+	{
+		//设置curl超时时间
+		$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
+	}
+	
+	/**
+	 * 	作用:生成可以获得code的url
+	 */
+	function createOauthUrlForCode($redirectUrl)
+	{
+		$urlObj["appid"] = WxPayConf_pub::APPID;
+		$urlObj["redirect_uri"] = "$redirectUrl";
+		$urlObj["response_type"] = "code";
+		$urlObj["scope"] = "snsapi_base";
+		$urlObj["state"] = "STATE"."#wechat_redirect";
+		$bizString = $this->formatBizQueryParaMap($urlObj, false);
+		return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
+	}
+
+	/**
+	 * 	作用:生成可以获得openid的url
+	 */
+	function createOauthUrlForOpenid()
+	{
+		$urlObj["appid"] = WxPayConf_pub::APPID;
+		$urlObj["secret"] = WxPayConf_pub::APPSECRET;
+		$urlObj["code"] = $this->code;
+		$urlObj["grant_type"] = "authorization_code";
+		$bizString = $this->formatBizQueryParaMap($urlObj, false);
+		return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
+	}
+	
+	
+	/**
+	 * 	作用:通过curl向微信提交code,以获取openid
+	 */
+	function getOpenid()
+	{
+		$url = $this->createOauthUrlForOpenid();
+        //初始化curl
+       	$ch = curl_init();
+		//设置超时
+		curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
+		curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
+        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
+		curl_setopt($ch, CURLOPT_HEADER, FALSE);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+		//运行curl,结果以jason形式返回
+        $res = curl_exec($ch);
+		curl_close($ch);
+		//取出openid
+		$data = json_decode($res,true);
+		$this->openid = $data['openid'];
+		return $this->openid;
+	}
+
+	/**
+	 * 	作用:设置prepay_id
+	 */
+	function setPrepayId($prepayId)
+	{
+		$this->prepay_id = $prepayId;
+	}
+
+	/**
+	 * 	作用:设置code
+	 */
+	function setCode($code_)
+	{
+		$this->code = $code_;
+	}
+
+	/**
+	 * 	作用:设置jsapi的参数
+	 */
+	public function getParameters()
+	{
+		$jsApiObj["appId"] = WxPayConf_pub::APPID;
+		$timeStamp = time();
+	    $jsApiObj["timeStamp"] = "$timeStamp";
+	    $jsApiObj["nonceStr"] = $this->createNoncestr();
+		$jsApiObj["package"] = "prepay_id=$this->prepay_id";
+	    $jsApiObj["signType"] = "MD5";
+	    $jsApiObj["paySign"] = $this->getSign($jsApiObj);
+	    $this->parameters = json_encode($jsApiObj);
+		
+		return $this->parameters;
+	}
+}
+
+
+
+?>

+ 16 - 0
mapi/api/payment/wxpay/lib/log_.php

@@ -0,0 +1,16 @@
+<?php
+
+class Log_
+{
+	// 打印log
+	function  log_result($file,$word) 
+	{
+	    $fp = fopen($file,"a");
+	    flock($fp, LOCK_EX) ;
+	    fwrite($fp,"执行日期:".strftime("%Y-%m-%d-%H:%M:%S",time())."\n".$word."\n\n");
+	    flock($fp, LOCK_UN);
+	    fclose($fp);
+	}
+}
+
+?>

+ 33 - 0
mapi/api/payment/wxpay/lib/notify_url.log

@@ -0,0 +1,33 @@
+
+
+
+执行日期:2015-02-05-19:%M:%S
+【CODE】:
+0213dce3c7ce7b986cd4bfd27dc77cet
+
+
+执行日期:2015-02-05-19:%M:%S
+【openid】:
+o9cuZuCqJkCzqmnfTWJt2TRlI_sc
+
+
+执行日期:2015-02-05-19:%M:%S
+【CODE】:
+021d77536ae0317ee62d7e077b76dc3H
+
+
+执行日期:2015-02-05-19:%M:%S
+【openid】:
+o9cuZuCqJkCzqmnfTWJt2TRlI_sc
+
+
+执行日期:2015-02-05-19:%M:%S
+【CODE】:
+04153bae0750f79168e71408fde87b6K
+
+
+执行日期:2015-02-05-19:%M:%S
+【openid】:
+o9cuZuCqJkCzqmnfTWJt2TRlI_sc
+
+

+ 68 - 0
mapi/api/payment/wxpay/notify_url.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * 通用通知接口demo
+ * ====================================================
+ * 支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL,
+ * 商户接收回调信息后,根据需要设定相应的处理流程。
+ * 
+ * 这里举例使用log文件形式记录回调信息。
+*/
+	include_once("lib/log_.php");
+	include_once("lib/WxPayPubHelper.php");
+
+    //使用通用通知接口
+	$notify = new Notify_pub();
+
+	//存储微信的回调
+	$xml = $GLOBALS['HTTP_RAW_POST_DATA'];	
+	$notify->saveData($xml);
+	
+	//验证签名,并回应微信。
+	//对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,
+	//微信会通过一定的策略(如30分钟共8次)定期重新发起通知,
+	//尽可能提高通知的成功率,但微信不保证通知最终能成功。
+	if($notify->checkSign() == FALSE){
+		$notify->setReturnParameter("return_code","FAIL");//返回状态码
+		$notify->setReturnParameter("return_msg","签名失败");//返回信息
+	}else{
+		$notify->setReturnParameter("return_code","SUCCESS");//设置返回码
+	}
+	$returnXml = $notify->returnXml();
+	echo $returnXml;
+	
+	//==商户根据实际情况设置相应的处理流程,此处仅作举例=======
+	
+	//以log文件形式记录回调信息
+	$log_ = new Log_();
+	$log_name="./notify_url.log";//log文件路径
+	$log_->log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");
+
+	if($notify->checkSign() == TRUE)
+	{
+		if ($notify->data["return_code"] == "FAIL") {
+			//此处应该更新一下订单状态,商户自行增删操作
+			$log_->log_result($log_name,"【通信出错】:\n".$xml."\n");
+		}
+		elseif($notify->data["result_code"] == "FAIL"){
+			//此处应该更新一下订单状态,商户自行增删操作
+			$log_->log_result($log_name,"【业务出错】:\n".$xml."\n");
+		}
+		else{
+			//此处应该更新一下订单状态,商户自行增删操作
+			$log_->log_result($log_name,"【支付成功】:\n".$xml."\n");
+		}
+		
+		//商户自行增加处理流程,
+		//例如:更新订单状态
+		//例如:数据库操作
+		//例如:推送支付完成信息
+
+		$_GET['act'] = 'payment';
+		$_GET['op']	= 'wxpayreturn';
+		$_GET['payment_code']='wxpay';
+		$_GET['result_code']	= $notify->data["result_code"];
+		$_GET['out_trade_no']	= $notify->data["out_trade_no"];
+		$_GET['transaction_id']	= $notify->data["transaction_id"];
+		require_once(dirname(__FILE__).'/../../../index.php');
+	}
+?>

+ 5 - 0
mapi/api/payment/wxpay/redirect_uri.php

@@ -0,0 +1,5 @@
+<?php
+$_GET['act']	= 'payment';
+$_GET['op']		= 'returnopenid';
+$_GET['payment_code'] = 'wxpay';
+require_once(dirname(__FILE__).'/../../../index.php');

+ 176 - 0
mapi/api/payment/wxpay/wxpay.php

@@ -0,0 +1,176 @@
+<?php
+/**
+ * JS_API支付demo
+ * ====================================================
+ * 在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。
+ * 成功调起支付需要三个步骤:
+ * 步骤1:网页授权获取用户openid
+ * 步骤2:使用统一支付接口,获取prepay_id
+ * 步骤3:使用jsapi调起支付
+ */
+include_once("lib/log_.php");
+include_once("lib/WxPayPubHelper.php");
+
+//使用jsapi接口
+$jsApi = new JsApi_pub();
+//以log文件形式记录回调信息
+$log_ = new Log_();
+$log_name="./notify_url.log";//log文件路径
+
+@$pay_sn = $_GET['pay_sn'];
+@$pay_amount = $_GET['pay_amount'];
+
+/*
+$log_->log_result($log_name,"【get pay_sn】:\n".$pay_sn."\n");
+$log_->log_result($log_name,"【get pay_amount】:\n".$pay_amount."\n");
+
+if(!isset($_COOKIE['pay_sn'])||!isset($_COOKIE['pay_amount']))
+{
+    $expire = time() + 86400; // 设置24小时的有效期
+    setcookie ("pay_sn", $pay_sn, $expire); // 设置一个名字为var_name的cookie,并制定了有效期
+    setcookie ("pay_amount", $pay_amount, $expire); // 再将过期时间设置进cookie以便你能够知道var_name的过期时间
+
+    $pay_sn = $_COOKIE['pay_sn'];
+    $pay_amount =  $_COOKIE['pay_amount'];
+}
+else
+{
+    $pay_sn = $_COOKIE['pay_sn'];
+    $pay_amount =  $_COOKIE['pay_amount'];
+}
+
+$log_->log_result($log_name,"【cookie pay_sn】:\n".$pay_sn."\n");
+$log_->log_result($log_name,"【cookie pay_amount】:\n".$pay_amount."\n");
+
+*/
+
+
+//=========步骤1:网页授权获取用户openid============
+//通过code获得openid
+if (!isset($_GET['code']))
+{
+    if(isset($_COOKIE['pay_sn']))
+    {
+        unset($_COOKIE['pay_sn']);
+    }
+    if(isset($_COOKIE['pay_amount']))
+    {
+        unset($_COOKIE['pay_amount']);
+    }
+    $expire = time() + 120; // 设置2分钟的有效期
+    setcookie ("pay_sn", $pay_sn, $expire); // 设置一个名字为var_name的cookie,并制定了有效期
+    setcookie ("pay_amount", $pay_amount, $expire); // 再将过期时间设置进cookie以便你能够知道var_name的过期时间
+
+    //触发微信返回code码
+    $url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
+    Header("Location: $url");
+}else
+{
+
+
+    if(isset($_COOKIE['pay_sn']))
+    {
+        $pay_sn = $_COOKIE['pay_sn'];
+        unset($_COOKIE['pay_sn']);
+    }
+    if(isset($_COOKIE['pay_amount']))
+    {
+        $pay_amount =  $_COOKIE['pay_amount'];
+        unset($_COOKIE['pay_amount']);
+    }
+
+    //获取code码,以获取openid
+    $code = $_GET['code'];
+    $jsApi->setCode($code);
+    $openid = $jsApi->getOpenId();
+
+    $log_->log_result($log_name,"【CODE】:\n".$code."\n");
+    $log_->log_result($log_name,"【openid】:\n".$openid."\n");
+}
+
+//=========步骤2:使用统一支付接口,获取prepay_id============
+//使用统一支付接口
+$unifiedOrder = new UnifiedOrder_pub();
+
+//设置统一支付接口参数
+//设置必填参数
+//appid已填,商户无需重复填写
+//mch_id已填,商户无需重复填写
+//noncestr已填,商户无需重复填写
+//spbill_create_ip已填,商户无需重复填写
+//sign已填,商户无需重复填写
+
+//自定义订单号,此处仅作举例
+$timeStamp = time();
+$out_trade_no = WxPayConf_pub::APPID."$timeStamp";
+
+$unifiedOrder->setParameter("openid","$openid");//openid描述
+$unifiedOrder->setParameter("body","$pay_sn");//商品描述
+$unifiedOrder->setParameter("out_trade_no","$pay_sn");//商户订单号
+$wx_pay_amount =  floatval($pay_amount)*100;
+$unifiedOrder->setParameter("total_fee","$wx_pay_amount");//总金额
+$unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址
+$unifiedOrder->setParameter("trade_type","JSAPI");//交易类型
+
+//非必填参数,商户可根据实际情况选填
+//$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
+//$unifiedOrder->setParameter("device_info","XXXX");//设备号
+//$unifiedOrder->setParameter("attach","XXXX");//附加数据
+//$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
+//$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
+//$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记
+//$unifiedOrder->setParameter("openid","XXXX");//用户标识
+//$unifiedOrder->setParameter("product_id","$pay_sn");//传入交易内部订单号
+
+$prepay_id = $unifiedOrder->getPrepayId();
+//=========步骤3:使用jsapi调起支付============
+$jsApi->setPrepayId($prepay_id);
+
+$jsApiParameters = $jsApi->getParameters();
+//echo $jsApiParameters;
+?>
+
+<html>
+<head>
+    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
+    <title>微信安全支付</title>
+
+    <script type="text/javascript">
+
+        //调用微信JS api 支付
+        function jsApiCall()
+        {
+            WeixinJSBridge.invoke(
+                'getBrandWCPayRequest',
+                <?php echo $jsApiParameters; ?>,
+                function(res){
+                    WeixinJSBridge.log(res.err_msg);
+                    //alert(res.err_code+res.err_desc+res.err_msg);
+                }
+            );
+        }
+
+        function callpay()
+        {
+            if (typeof WeixinJSBridge == "undefined"){
+                if( document.addEventListener ){
+                    document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
+                }else if (document.attachEvent){
+                    document.attachEvent('WeixinJSBridgeReady', jsApiCall);
+                    document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
+                }
+            }else{
+                jsApiCall();
+            }
+        }
+    </script>
+</head>
+<body onload="callpay();">
+</br></br></br></br>
+<div align="center">
+    <p style="font-size: 32px;">微信交易号:<?php echo $pay_sn; ?></p>
+    <p style="font-size: 32px;">金额:<?php echo $pay_amount; ?>元</p>
+    <button style="width:70%; height:100px; background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:32px;" type="button" onclick="history.back()" >返回订单列表</button>
+</div>
+</body> 
+</html>

+ 10 - 0
mapi/bridge_shr.php

@@ -0,0 +1,10 @@
+<?php
+
+require_once(BASE_HELPER_PATH . '/rbridge/RBridgeFactory.php');
+
+$content = $_SERVER['post_content'];
+$input = json_decode($content,true);
+
+$ret = rbridge\RBridgeFactory::instance()->add('wsd',$input);
+
+echo($ret);

+ 17 - 0
mapi/cmbpay_notify.php

@@ -0,0 +1,17 @@
+<?php
+
+require_once (BASE_ROOT_PATH . "/helper/pay_helper.php");
+
+$data = json_encode($_GET);
+Log::record("cmbpay_notify param: {$data}", Log::DEBUG);
+
+$params = [];
+foreach ($_GET as $key => $value)
+{
+    if($key != 'act' && $key != 'op') {
+        $params[$key] = $value;
+    }
+}
+
+pay_helper::OnNotify($params,pay_helper::CMB_PAYMENT);
+

+ 11 - 0
mapi/cmbpay_sign.php

@@ -0,0 +1,11 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/9/26
+ * Time: 下午3:23
+ */
+
+
+$data = json_encode($_GET);
+Log::record("cmbpay_notify param: {$data}", Log::DEBUG);

+ 3 - 0
mapi/config/config.ini.php

@@ -0,0 +1,3 @@
+<?php
+defined('InShopNC') or exit('Access Invalid!');
+

+ 448 - 0
mapi/control/activity.php

@@ -0,0 +1,448 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2016/10/19
+ * Time: 下午4:45
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/activity_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/special_helper.php');
+
+class act_formater
+{
+    private $mActivities;
+    private $mGoodsActContainer;
+
+    public function __construct($activities)
+    {
+        $this->mActivities = $activities;
+        $this->mGoodsActContainer = [];
+    }
+
+    public function format_acting(bonus\IPriceCalculate $price_calc)
+    {
+        $specials = [];
+        $goods_ids = [];
+
+        $cur_type = -1;
+        foreach ($this->mActivities as $act)
+        {
+            $gids =[];
+            $block = false;
+
+            if(array_key_exists('xianshi_id',$act))
+            {
+                $block = $this->format_limit($act,$gids);
+                if($block != false) {
+                    $time_type = intval($act['xianshi_type']);
+                }
+            }
+            elseif(array_key_exists('groupbuy_id',$act))
+            {
+                $block = $this->format_groupbuy($act,$gids);
+                if($block != false) {
+                    $time_type = intval($act['groupbuy_type']);
+                }
+            }
+            else {
+                $time_type = false;
+                Log::record("an error activity.",Log::ERR);
+            }
+
+            if($block != false)
+            {
+                if($time_type !== false)
+                {
+                    if($cur_type != $time_type)
+                    {
+                        $banners = $this->type_banner($time_type);
+                        if(!empty($banners))
+                        {
+                            foreach ($banners as $banner) {
+                                $specials[] = $banner;
+                            }
+                        }
+                        $cur_type = $time_type;
+                    }
+                }
+
+                $specials[]= $block;
+                self::array_copy($goods_ids,$gids);
+            }
+        }
+
+        $goods_ids = array_unique($goods_ids);
+        if(!empty($goods_ids))
+        {
+            $helper = new goods_helper($price_calc);
+            $ret = $helper->online_summary($goods_ids,$related);
+
+            return array('special_list' => $specials,
+                'summary' => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page(1));
+        }
+        else {
+            return array('special_list' => null,
+                'summary' => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(1));
+        }
+    }
+
+    public function format_unstart(bonus\IPriceCalculate $price_calc)
+    {
+        $specials = [];
+        $goods_ids = [];
+
+        $group_ids = [];
+        $limit_ids = [];
+
+        $cur_type = -1;
+        foreach ($this->mActivities as $act)
+        {
+            $gids = [];
+            $block = false;
+            if(array_key_exists('xianshi_id',$act))
+            {
+                $block = $this->format_limit($act,$gids);
+                if($block != false) {
+                    $limit_ids[] = intval($act['xianshi_id']);
+                    $time_type = intval($act['xianshi_type']);
+                }
+            }
+            elseif(array_key_exists('groupbuy_id',$act))
+            {
+                $block = $this->format_groupbuy($act,$gids);
+                if($block != false) {
+                    $group_ids[] = intval($act['groupbuy_id']);
+                    $time_type = intval($act['groupbuy_type']);
+                }
+            }
+            else {
+                $time_type = false;
+                Log::record("an error activity.",Log::ERR);
+            }
+
+            if($block != false)
+            {
+                if($time_type !== false)
+                {
+                    if($cur_type != $time_type)
+                    {
+                        $banners = $this->type_banner($time_type);
+                        if(!empty($banners))
+                        {
+                            foreach ($banners as $banner) {
+                                $specials[] = $banner;
+                            }
+                        }
+                        $cur_type = $time_type;
+                    }
+                }
+
+                $specials[]= $block;
+                self::array_copy($goods_ids,$gids);
+            }
+        }
+
+        $goods_ids = array_unique($goods_ids);
+        if(!empty($goods_ids))
+        {
+            $helper = new goods_helper($price_calc);
+            $ret = $helper->online_summary($goods_ids,$related);
+
+            $summarys = $ret['summary'];
+            foreach ($summarys as &$summary)
+            {
+                $goods_id = $summary['goods_id'];
+                $act = $this->mGoodsActContainer[$goods_id];
+                $summary['act_id'] = $act['act_id'];
+                $summary['act_type'] = $act['act_type'];
+                if($act['act_type'] == activity_helper::ACTIVITY_GROUPBUY) {
+                    $ret = activity_helper::groupbuy_price($act['act_id'],$price);
+                } else {
+                    $ret = activity_helper::limit_price($act['act_id'],$goods_id,$price);
+                }
+
+                if($ret == true) {
+                    $summary['goods_promotion_price'] = $price;
+                } else {
+                    Log::record("can not get : goods_promotion_price",Log::ERR);
+                }
+            }
+
+            $groups = [];
+            foreach ($group_ids as $group_id)
+            {
+                $item = activity\groupbuy::instance()->get_info($group_id);
+                if($item != false) {
+                    $groups[] = $item;
+                } else {
+                    Log::record("cannot get group id={$group_id}",Log::ERR);
+                }
+            }
+
+            $limits = [];
+            foreach ($limit_ids as $limit_id)
+            {
+                $item = activity\limitime::instance()->get_info($limit_id);
+                if($item != false) {
+                    $limits[] = $item;
+                } else {
+                    Log::record("cannot get group id={$limit_id}",Log::ERR);
+                }
+            }
+
+            return array('special_list' => $specials,
+                'summary' => $summarys,
+                'groupbuy' => $groups,
+                'limitime' => $limits,
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page(1));
+        }
+        else
+        {
+            return array('special_list' => null,
+                'summary' => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(1));
+        }
+    }
+
+    private function type_banner($time_type)
+    {
+        static $stTimeBanner = array(12 => 345,20 => 347,24 => 348);
+        //static $stTimeBanner = array(12 => 60);
+
+        if(array_key_exists($time_type,$stTimeBanner))
+        {
+            $banners = special_manager::instance()->special($stTimeBanner[$time_type],$gids);
+            if(empty($banners))
+                return null;
+            else
+                return $banners;
+        }
+        return null;
+    }
+
+    private function format_limit($limt, &$goods_ids)
+    {
+        $result =[];
+
+        $limt_id = intval($limt['xianshi_id']);
+        $result['item_title'] = strval($limt_id);
+        $result['item_type'] = 'home_limit';
+
+        $goods_ids = activity_helper::limit_goods($limt_id);
+        if(empty($goods_ids)) return false;
+        foreach ($goods_ids as $gid) {
+            $item['type'] = 'goods';
+            $item['data'] = strval($gid);
+            $item['image'] = '';
+            $item['title'] = '';
+            $result['items'][] = $item;
+
+            $this->mGoodsActContainer[$gid] = array('act_id' => $limt_id,
+                'act_type' => activity_helper::ACTIVITY_LIMITTIME);
+        }
+
+        return $result;
+    }
+
+    private function format_groupbuy($group, &$goods_ids)
+    {
+        $result =[];
+
+        $act_id = intval($group['groupbuy_id']);
+        $result['item_title'] = strval($act_id);
+        $result['item_type'] = 'home_group';
+
+        $goods_ids = activity_helper::groupbuy_goods($act_id);
+        if(empty($goods_ids)) return false;
+        foreach ($goods_ids as $gid) {
+            $item['type'] = 'goods';
+            $item['data'] = strval($gid);
+            $item['image'] = '';
+            $item['title'] = '';
+
+            $result['items'][] = $item;
+            $this->mGoodsActContainer[$gid] = array('act_id' => $act_id,
+                'act_type' => activity_helper::ACTIVITY_GROUPBUY,
+                'goods_promotion_price' => $group['promotion_price']);
+        }
+
+        return $result;
+    }
+
+    private static function array_copy(&$dest,$src)
+    {
+        if(empty($src)) return $dest;
+        foreach ($src as $value) {
+            array_push($dest,$value);
+        }
+        return $dest;
+    }
+}
+
+
+class limit_outer
+{
+    const WAIT_START = 0;
+    const WAIT_END = 1;
+
+    private $mAct;
+    private $mType;
+    public function __construct($type,$act)
+    {
+        $this->mAct = $act;
+        $this->mType = $type;
+    }
+
+    public function format(bonus\IPriceCalculate $price_calc)
+    {
+        if(array_key_exists('xianshi_id',$this->mAct)) {
+            $result = $this->format_limit($price_calc);
+        }
+        elseif(array_key_exists('groupbuy_id',$this->mAct)) {
+            $result = $this->format_group($price_calc);
+        }
+        else {
+            $result = false;
+        }
+
+        return $result;
+    }
+    private function format_limit(bonus\IPriceCalculate $price_calc)
+    {
+        $result = [];
+
+        $act = $this->mAct;
+
+        $act_id = $act['xianshi_id'];
+        $gids = activity_helper::limit_goods($act_id);
+        if(empty($gids)) return false;
+
+        $goods_ids = array($gids[0]);
+        $helper = new goods_helper($price_calc);
+        $ret = $helper->online_summary($goods_ids,$related);
+
+        if(!empty($ret['summary']))
+        {
+            $summary = $ret['summary'][0];
+            if($this->mType == limit_outer::WAIT_START) {
+                $result['act_time'] = $act['start_time'];
+            } else {
+                $result['act_time'] = $act['end_time'];
+            }
+
+            $result['goods_name'] = $summary['goods_mobile_name'];
+            $result['goods_price'] = $summary['goods_price'];
+            $result['goods_promotion_price'] = $summary['goods_promotion_price'];
+            $result['goods_image_url'] = $summary['goods_image_url'];
+            $result['local_time'] = time();
+
+            return $result;
+        }
+        else {
+            return false;
+        }
+
+    }
+    private function format_group(bonus\IPriceCalculate $price_calc)
+    {
+        $result = [];
+
+        $act = $this->mAct;
+        $act_id = $act['groupbuy_id'];
+        $gids = activity_helper::groupbuy_goods($act_id);
+        if(empty($gids)) return false;
+
+        $goods_ids = array($gids[0]);
+        $helper = new goods_helper($price_calc);
+        $ret = $helper->online_summary($goods_ids,$related);
+
+        if(!empty($ret['summary']))
+        {
+            $summary = $ret['summary'][0];
+            if($this->mType == limit_outer::WAIT_START) {
+                $result['act_time'] = $act['start_time'];
+            } else {
+                $result['act_time'] = $act['end_time'];
+            }
+
+            $result['goods_name'] = $summary['goods_mobile_name'];
+            $result['goods_price'] = $summary['goods_price'];
+            $result['goods_promotion_price'] = $act['promotion_price'];
+            $result['goods_image_url'] = $summary['goods_image_url'];
+            $result['local_time'] = time();
+
+            return $result;
+        }
+        else {
+            return false;
+        }
+    }
+}
+
+class activityControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function actingOp()
+    {
+        $actings = activity_helper::acting();
+
+        $formater = new act_formater($actings);
+        $result = $formater->format_acting($this->price_calcer());
+
+        return self::outsuccess($result);
+    }
+    public function unstartOp()
+    {
+        $actings = activity_helper::unstart();
+        $formater = new act_formater($actings);
+        $result = $formater->format_unstart($this->price_calcer());
+
+        return self::outsuccess($result);
+    }
+
+    public function limit_entraOp()
+    {
+        $_SESSION['client_type'] = "wap";
+
+        $acts = activity_helper::acting();
+        $price_calcer = $this->price_calcer();
+        if(!empty($acts)) {
+            $act = $acts[0];
+            $outer = new limit_outer(limit_outer::WAIT_END,$act);
+            $result = $outer->format($price_calcer);
+            if($result != false) {
+                return self::outsuccess($result,"activity/limit_entra");
+            }
+        }
+
+        $unstarts = activity_helper::unstart();
+        if(!empty($unstarts)) {
+            $act = $unstarts[0];
+            $outer = new limit_outer(limit_outer::WAIT_START,$act);
+            $result = $outer->format($price_calcer);
+            if($result != false) {
+                return self::outsuccess($result,"activity/limit_entra");
+            }
+        }
+
+        return self::outsuccess(null,"activity/limit_entra");
+    }
+}

File diff suppressed because it is too large
+ 549 - 0
mapi/control/admin_oper.php


+ 152 - 0
mapi/control/app_update.php

@@ -0,0 +1,152 @@
+<?php
+/**
+ * 更新
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/area/area_upgrade.php');
+require_once(BASE_ROOT_PATH . '/helper/area/area_check.php');
+
+class app_updateControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function check_versionOp()
+    {
+        $ver_code = $_GET['ver_code'];
+        if($_SESSION['client_type'] == 'ios')
+        {
+            $cur_ver = $GLOBALS['setting_config']['mobile_ios_version'];
+
+            $cur_ver  = intval($cur_ver * 100 + 0.5);
+            $ver_code = intval($ver_code * 100 + 0.5);
+
+            if($ver_code < $cur_ver) {
+                $url  = $GLOBALS['setting_config']['mobile_ios'];
+                $tips = $GLOBALS['setting_config']['mobile_update_tips'];
+                $artips = explode('#',$tips);
+                $tips = implode("\n",$artips);
+                return self::outsuccess(array("open_url" => $url,'tip' => $tips));
+            } else {
+                return self::outsuccess(null);
+            }
+        }
+        elseif($_SESSION['client_type'] == 'android')
+        {
+            $cur_ver = $GLOBALS['setting_config']['mobile_apk_version'];
+
+            $cur_ver  = intval($cur_ver * 100 + 0.5);
+            $ver_code = intval($ver_code * 100 + 0.5);
+
+            if($ver_code < $cur_ver) {
+                $url  = $GLOBALS['setting_config']['mobile_apk'];
+                $tips = $GLOBALS['setting_config']['mobile_update_tips'];
+                $artips = explode('#',$tips);
+                $tips = implode("\n",$artips);
+
+                $down_url = "{$url}?{$cur_ver}";
+                Log::record("down url = {$down_url}",Log::DEBUG);
+                return self::outsuccess(array("open_url" => $down_url,'tip' => $tips,'force' => false));
+            } else {
+                return self::outsuccess(null);
+            }
+        }
+        else {
+            return self::outerr(errcode::ErrApptype);
+        }
+    }
+
+    public function areaOp()
+    {
+        global $config;
+
+        $ver_code = intval($_GET['version']);
+        if($ver_code < $config['area_version'])
+        {
+            static $data = null;
+            if($data == null)
+            {
+                $items = rcache('area', 'mb_');
+                if(empty($items)) {
+                    $area = new area\area_check();
+                    $data = $area->export();
+                    wcache('area', array('data' => serialize($data)), 'mb_');
+                } else {
+                    $data = unserialize($items['data']);
+                }
+            }
+
+            return self::outsuccess(array('version' => $config['area_version'],'areas' => $data));
+        }
+        else {
+            return self::outsuccess(null);
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function check_verOp()
+    {
+        $ver_code = $_GET['ver_code'];
+        if($_SESSION['client_type'] == 'ios')
+        {
+            $cur_ver = $GLOBALS['setting_config']['mobile_ios_version'];
+            
+            $cur_ver  = intval($cur_ver * 100 + 0.5);
+            $ver_code = intval($ver_code * 100 + 0.5);
+
+            if($ver_code < $cur_ver) {
+                $url  = $GLOBALS['setting_config']['mobile_ios'];
+                $tips = $GLOBALS['setting_config']['mobile_update_tips'];
+                return self::outsuccess(array("open_url" => $url,'tip' => $tips));
+            } else {
+                return self::outsuccess(null);
+            }
+        }
+        elseif($_SESSION['client_type'] == 'android') {
+            return $this->checkVersionOp();
+        }
+        else {
+            return self::outerr(errcode::ErrApptype);
+        }
+    }
+
+    public function checkVersionOp()
+    {
+        $ver_code = $_GET['ver_code'];
+        if($this->android() == false || !isset($ver_code) || empty($ver_code) || intval($ver_code) <= 0) {
+            return self::outerr(errcode::ErrParamter,"需要带入手机及版本信息");
+        }
+
+        $verinfo = rkcache('android_version',true);
+        $result = array();
+        if ($ver_code == $verinfo['ver_code']) {
+            $result['latest'] = 0; //设计协议设计反了,0 表示目前是最新版本,1 表示不是最新版本
+        }
+        else
+        {
+            $result['latest'] = 1;
+            $lowest_compatible_version = intval($verinfo['lowest_compatible_version']);
+            if ($lowest_compatible_version > intval($ver_code)) {
+                $result['force_update'] = 1;
+            } else {
+                $result['force_update'] = 0;
+            }
+
+            $update_info = array();
+            $update_info['ver_code'] = $verinfo['ver_code'];
+            $update_info['app_path'] = $verinfo['app_path'];
+            $update_info['release_note'] = $verinfo['release_note'];
+            $update_info['remind_time']  = $verinfo['remind_time'];
+            $update_info['md5_file'] = $verinfo['md5_file'];
+            $update_info['app_path'] = BASE_SITE_URL . $verinfo['app_path'];
+
+            $result['update_info'] = $update_info;
+        }
+
+        self::outsuccess($result);
+    }
+}

+ 33 - 0
mapi/control/article.php

@@ -0,0 +1,33 @@
+<?php
+/**
+ * 文章 
+ * 好商城V3 - 33HAO.COM
+ * 
+ **/
+
+defined('InShopNC') or exit('Access Invalid!');
+class articleControl extends mobileControl
+{
+	public function __construct() {
+        parent::__construct();
+    }
+
+    public function showOp()
+    {
+        if(!empty($_GET['article_id']) && intval($_GET['article_id']) > 0)
+        {
+            $article_model	= Model('cms_article');
+            $article = $article_model->getOne(array('article_id' => intval($_GET['article_id'])));
+
+			if (empty($article)) {
+				return self::outerr(errcode::ErrParamter,'文章不存在');
+			}
+			else {
+				return self::outsuccess(array('article' => $article),'article/show','wap');
+			}
+        } 
+        else {
+            return self::outerr(errcode::ErrParamter,'文章不存在');
+        }
+    }
+}

+ 462 - 0
mapi/control/bargain.php

@@ -0,0 +1,462 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2018/1/15
+ * Time: 下午12:15
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/room_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/activity_helper.php');
+
+class bargainControl extends mobileControl
+{
+    private $mAccAddr;
+    public function __construct()
+    {
+        parent::__construct();
+        global $config;
+        $this->mAccAddr = $config['access_addr'];
+    }
+
+    public function indexOp()
+    {
+        return self::outsuccess(['tpl' => null],'bargain/bargain_list');
+    }
+
+    public function createOp()
+    {
+        if (!session_helper::logined()) {
+            throw new UnloginException();
+        }
+        $goods_id = intval($_GET['goods_id']);
+        if($goods_id <= 0 || activity\bargain_goods::instance()->isTakepart($goods_id,$act_id) == false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $bargain = activity\bargain_goods::instance()->get_bargain($act_id);
+        if($bargain === false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $mod_bargain = Model('room_bargain');
+        $bargain_params = $mod_bargain->getBargainByUserGoods(session_helper::memberid(),$goods_id);
+        if(empty($bargain_params))
+        {
+            if(!$bargain->started()) {
+                return self::outerr(errcode::ErrParamter,"活动尚未开始");
+            }
+            elseif($bargain->processing())
+            {
+                $ret = room\factory_client::instance()->create_bargain($goods_id,session_helper::memberid(),$bargain->lowest_price(),$bargain->usable_days(),$bargain->random(),$bargain->total_num());
+                if($ret != false) {
+                    $bargain_id = intval($ret['bargain_id']);
+                    return self::outsuccess(['bargain_id' => $bargain_id]);
+                }
+                else {
+                    return self::outerr(errcode::ErrRoom,"砍价创建活动已经结束");
+                }
+            }
+            else {
+                return self::outerr(errcode::ErrParamter,"活动已经结束");
+            }
+        }
+        else
+        {
+            $bargain_id = intval($bargain_params['bargain_id']);
+            return self::outsuccess(['bargain_id' => $bargain_id]);
+        }
+    }
+
+    public function openOp()
+    {
+        $bargain_id = intval($_GET['bargain_id']);
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = author_url::bargain_url($bargain_id);
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        if(!session_helper::logined()) {
+            throw new UnloginException();
+        }
+
+        if(!$this->validate($bargain_id)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        else
+        {
+            $tpl = new tpl_bargain($bargain_id,$this->price_calcer());
+            $ret = room\factory_client::instance()->invite($tpl->room(),session_helper::memberid());
+            if($ret != false) {
+                $ret['addr'] = $this->mAccAddr;
+            }
+            return self::outsuccess(['tpl' => $tpl,'room' => $ret],'bargain/bargain');
+        }
+    }
+
+    public function detailOp()
+    {
+        if (!session_helper::logined()) {
+            throw new UnloginException();
+        }
+
+        $bargain_id = intval($_GET['bargain_id']);
+        if(!$this->validate($bargain_id)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        else {
+            $tpl = new tpl_bargain($bargain_id,$this->price_calcer());
+            $ret = room\factory_client::instance()->invite($tpl->room(),session_helper::memberid());
+            if($ret != false) {
+                $ret['addr'] = $this->mAccAddr;
+            }
+            return self::outsuccess(['tpl' => new tpl_bargain($bargain_id,$this->price_calcer()),'room' => $ret],'bargain/bargain');
+        }
+    }
+
+    public function mine_listOp()
+    {
+        if (!session_helper::logined()) {
+            throw new UnloginException();
+        }
+
+        $mod_bargain = Model('room_bargain');
+        $items  = $mod_bargain->getBargainList(['user_id' => session_helper::memberid()], '*', $this->page_size);
+        $page_count = $mod_bargain->gettotalpage();
+
+        $gids = [];
+        $bargains = [];
+        $details = [];
+        foreach ($items as $item)
+        {
+            $gid = intval($item['goods_id']);
+            $bid = intval($item['bargain_id']);
+
+            if($bid > 0 && $gid > 0) {
+                $gids[] = $gid;
+                $bargains[] = $bid;
+                $bargain = new room\bargain($item);
+                $details[] = $bargain->format();
+            }
+        }
+
+        if(empty($gids))
+        {
+            return self::outsuccess(['special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'bargain_detail' => null,
+                'mobile_page' => mobile_page($page_count)]);
+        }
+        else
+        {
+            $helper = new goods_helper($this->price_calcer());
+            $ret = $helper->online_summary($gids,$related_goods);
+            $block = special_formater::format_bargain($bargains,'我的砍价');
+            $blocks[] = $block;
+
+            $summarys = $this->summary_map($ret['summary']);
+            foreach ($details as &$detail)
+            {
+                $summary = $summarys[$gid];
+                $gid = $detail['goods_id'];
+                $detail['storage'] = $summary['goods_storage'];
+                $detail['share_detail'] = $this->share_detail($detail['bargain_id'],$summary);
+            }
+
+            return self::outsuccess(['special_list' => $blocks,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'bargain'  => $ret['bargain'],
+                'bargain_detail' => $details,
+                'mobile_page' => mobile_page($page_count)]);
+        }
+    }
+
+    private function share_detail($bargain_id,$summary) {
+        $result = [];
+        $result['url'] = url_helper::bargain_open_url($bargain_id);
+        $result['title'] = $summary['goods_mobile_name'];
+        $result['sub_title'] = $summary['goods_mobile_name'];
+        $result['img_url'] = $summary['goods_image_url'];
+
+        return $result;
+    }
+
+    private function summary_map($summarys)
+    {
+        $ret = [];
+        foreach ($summarys as $summary) {
+            $gid = $summary['goods_id'];
+            $ret[$gid] = $summary;
+        }
+        return $ret;
+    }
+
+    private function validate($bargain_id)
+    {
+        if($bargain_id <= 0) return false;
+        $mod_bargain = Model('room_bargain');
+        $ret = $mod_bargain->getBargainById($bargain_id);
+        return !empty($ret);
+    }
+}
+
+class tpl_bargain
+{
+    private $mBargain;
+    private $mSummary;
+    private $mPriceCalculate;
+
+    public function __construct($bargain_id,bonus\IPriceCalculate $priceCalculate)
+    {
+        $this->mPriceCalculate = $priceCalculate;
+        $mod_bargain = Model('room_bargain');
+        $info = $mod_bargain->getBargainById($bargain_id);
+        $this->mBargain = new room\bargain($info);
+        $goods_id = $this->mBargain->goods_id();
+        $helper = new goods_helper($this->mPriceCalculate);
+        $ret = $helper->summary([$goods_id],$related_goods);
+        $this->mSummary = $ret['summary'][0];
+    }
+    public function room()
+    {
+        return $this->mBargain->room();
+    }
+
+    public function show_goods()
+    {
+        $summary = $this->mSummary;
+        $cur_price = $summary['goods_price'] - $this->mBargain->discount();
+        $lowest = $this->mBargain->lowest_price();
+
+        $str = "<div class=\"goods\">
+                    <div class=\"thumbnail\">
+                        <img src=\"{$summary['goods_image_url']}\" alt=\"\">
+                    </div>
+                    <div class=\"introduce\">
+                        <p class=\"goods_name\">{$summary['goods_mobile_name']}</p>
+                        <p class=\"floor_price\" style='margin-bottom: 7px;'>原价{$summary['goods_price']}</p>
+                       
+                        <div class=\"price_describe\">
+                            <div class=\"price_box\">
+                                <span class=\"current_price\" id=\"current_price\">现价¥{$cur_price}</span>
+                                <span class=\"floor_price\">可砍至{$lowest}元</span>
+                                <input type=\"hidden\" value=\"{$summary['goods_price']}\" id=\"goods_price\">
+                                <input type=\"hidden\" value=\"{$lowest}\" id=\"lowest_price\">
+                            </div>
+                        </div>
+                        <div class=\"count_down\">
+                            <p class=\"bargain_over hide\">该砍价已结束</p>
+                            <p class=\"show_count_down\">剩 <span class=\"days time_color\"></span> 天 <span class=\"hours time_color\"></span>:<span class=\"minutes time_color\"></span>:<span class=\"seconds time_color\"></span> 结束</p>
+                        </div>
+                    </div>
+                    <img src=\"". RESOURCE_SITE_URL ."/mobile/bargain/images/stamp.png\" id=\"stamp\" class=\"stamp hide stamp_scale\">
+                </div>";
+        echo $str;
+    }
+
+    private function user_msg()
+    {
+        static $msgs = ['绑架老板打劫福利',
+            '专治各种买不起',
+            '撸起袖子助你一臂之力',
+            '斧头帮伙计来也',
+            '拔刀相助,在所不辞',
+            '砍得多,全靠俺的一声吼',
+            '看我的青龙偃月刀',
+            '花钱买,不如砍价免费拿',
+            '感情深,刀法稳',
+            '关系好不好,一刀见分晓',
+            '放开那价,让我来',
+            '一刀出手往死里砍'];
+        $count = count($msgs);
+        $pos = mt_rand(0,$count - 1);
+        return $msgs[$pos];
+    }
+
+    public function show_friends()
+    {
+        $result = $this->records();
+        if(empty($result)) return;
+
+        $records = $result['records'];
+        $users = $result['users'];
+
+        foreach ($records as $uid => $value)
+        {
+            $user =$users[$uid];
+            $msg = $this->user_msg();
+            $str = "<li>
+                    <div class=\"head_portrait\">
+                         <img src=\"{$user['avatar']}\" alt=\"\">
+                    </div>
+                    <div class=\"user\">
+                         <div class=\"user_name\">{$user['nickname']}</div>
+                              <div class=\"user_msg\">{$msg}</div>
+                         </div>
+                         <div class=\"bargain_msg\">
+                              <span class=\"msg\">砍掉{$value}元</span>
+                         </div>
+               </li>";
+            echo $str;
+        }
+    }
+
+    private function records()
+    {
+        $roomid = $this->mBargain->room();
+        $mod_room = Model('room');
+        $items = $mod_room->getRoomMsg($roomid,room\proto_type::msg_type_bargain);
+        if(empty($items)) return [];
+
+        $uids = [];
+        $records = [];
+        foreach ($items as $record) {
+            $uid = intval($record['member_id']);
+            $data = json_decode($record['msg'],true);
+            $value = $data['value'];
+            $uids[] = $uid;
+            $records[$uid] = $value;
+        }
+
+        $mod_member = Model('member');
+        $mInfos = $mod_member->getMemberList(['member_id' => ['in',$uids]]);
+
+        $users = [];
+        foreach ($mInfos as $info)
+        {
+            try
+            {
+                $minfo = new member_info($info);
+                $uid = $minfo->member_id();
+                $avatar = $minfo->avatar();
+                $users[$uid]['avatar'] = $avatar;
+                $users[$uid]['nickname'] = $minfo->nickname();
+            }
+            catch (Exception $ex)
+            {
+                Log::record(__METHOD__,Log::ERR);
+            }
+        }
+
+        return ['records' => $records,'users' => $users];
+    }
+
+    public function bargained()
+    {
+        $mod_room = Model('room');
+        $items = $mod_room->getUserRoomMsg($this->mBargain->room(),session_helper::memberid(),room\proto_type::msg_type_bargain);
+        return !empty($items);
+    }
+
+    public function left_time()
+    {
+        if($this->mBargain->closed()) {
+            return -1;
+        } else {
+            return $this->mBargain->over_time() - time();
+        }
+    }
+
+    public function show_creator()
+    {
+        try
+        {
+            $minfo = new member_info($this->mBargain->creator());
+            $avatar = $minfo->avatar();
+            $name = $minfo->nickname();
+            $str = "<div class=\"sponsor\">
+                        <img class=\"head_portrait\" src=\"{$avatar}\">
+                    </div>
+                    <header class=\"title\">
+                        <span class=\"sponsor_name\">{$name}</span>
+                    </header>";
+            return $str;
+        }
+        catch (Exception $ex)
+        {
+            Log::record(__METHOD__,Log::ERR);
+            return "";
+        }
+    }
+
+    public function show_button()
+    {
+        if($this->mBargain->closed()) {
+           return "";
+        }
+
+        if(session_helper::memberid() == $this->mBargain->creator())
+        {
+            if($this->bargained()) {
+                $str = '<span class="just_buy" id="just_buy"></span>
+                        <span class="invite_btn" id="invite_btn"></span>';
+            }
+            else {
+                $str = '<span class="mine_bargain_btn" id="mine_bargain_btn"></span>
+                        <span class="just_buy" id="just_buy"></span>
+                        <span class="invite_btn" id="invite_btn"></span>';
+            }
+        }
+        else
+        {
+            if($this->bargained()) {
+                $str = '<span class="join_btn" id="join_btn"></span>
+                        <span class="bargain_btn hide" id="bargain_btn"></span>';
+            }
+            else {
+                $str = '<span class="bargain_btn" id="bargain_btn"></span>
+                        <span class="join_btn hide" id="join_btn"></span>';
+            }
+        }
+
+        return $str;
+    }
+
+    public function show_close_pop()
+    {
+        $str = "";
+//        if($this->mBargain->closed()) {
+//            $str = '<div class="over_pop">
+//                        <div class="bargain_over_bg"></div>
+//                        <span class="start_bargain_btn"></span>
+//                    </div>';
+//        }
+//        else {
+//            $str = '<div class="over_pop hide">
+//                        <div class="bargain_over_bg"></div>
+//                        <span class="start_bargain_btn"></span>
+//                    </div>';;
+//        }
+        return $str;
+    }
+
+    public function share_url()
+    {
+        return url_helper::bargain_open_url($this->mBargain->bargain_id());
+    }
+    public function share_title()
+    {
+        return $this->mSummary['goods_mobile_name'];
+    }
+    public function share_image()
+    {
+        return $this->mSummary['goods_image_url'];
+    }
+    public function share_subtitle()
+    {
+        $price = $this->mBargain->lowest_price();
+        return "帮我砍个价,{$price}元得商品~";
+    }
+}

File diff suppressed because it is too large
+ 1132 - 0
mapi/control/bonusex.php


+ 36 - 0
mapi/control/brand.php

@@ -0,0 +1,36 @@
+<?php
+/**
+ * 品牌获取
+ */
+
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/brand_helper.php');
+
+class brandControl extends mobileHomeControl
+{
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function homeOp()
+    {
+        $blocks = [];
+        $brands = brand_helper::instance()->brandex();
+        $blocks[] = $brands['block'];
+        return self::outsuccess(array("special_list" => $blocks,'mobile_page' => mobile_page(1)));
+    }
+
+    public function alpha_listOp()
+    {
+        $brands = brand_helper::instance()->alpha_list();
+        return self::outsuccess(array("brands" => $brands,'mobile_page' => mobile_page(1)));
+    }
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function indexOp()
+    {
+        $brands = brand_helper::brands();
+        return self::outsuccess(array("brands" => $brands));
+    }
+}

+ 882 - 0
mapi/control/cart.php

@@ -0,0 +1,882 @@
+<?php
+/**
+ * 购物车
+ */
+
+use bonus\account;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/activity_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/algorithm.php');
+require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/fcode.php');
+require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
+class cart_item
+{
+    private $cart_id;
+    private $bl_id;
+    private $goods_id;
+    private $goods_num;
+
+    public function __construct($cart_id,$bl_id,$goods_id,$goods_num)
+    {
+        $this->cart_id = intval($cart_id);
+        $this->bl_id = intval($bl_id);
+        $this->goods_id = intval($goods_id);
+        $this->goods_num = intval($goods_num);
+    }
+
+    public function is_bl() {
+        return $this->bl_id > 0;
+    }
+    public function format() {
+        $cart_item['cart_id']   = $this->cart_id;
+        $cart_item['goods_id']  = $this->goods_id;
+        $cart_item['bl_id']     = $this->bl_id;
+        $cart_item['goods_num'] = $this->goods_num;
+        return $cart_item;
+    }
+    public function goods_ids()
+    {
+        if($this->is_bl()) {
+            return activity_helper::bundling_goods($this->bl_id);
+        }
+        else {
+            return array($this->goods_id);
+        }
+    }
+}
+
+class cartControl extends mobileControl
+{
+    const db_type = 'db';
+    const session_type = 'Session';
+
+    private $mUserFcode;
+    private $mFcodeBannerID;
+
+    public function __construct() {
+        parent::__construct();
+        $this->mUserFcode = null;
+
+        global $config;
+        $this->mFcodeBannerID = $config['autosend_fcodes']['cart_spid'];
+    }
+
+    public function rate_moneyOp()
+    {
+        if($_SESSION['is_login'] == 1)
+        {
+            $pred = new account($_SESSION['member_id'],true);
+            $bonus_rate = $pred->pay_bonus_rates();
+
+            if($bonus_rate != null)
+            {
+                $rates = $bonus_rate->format();
+                $rates_money = [];
+                foreach ($rates as $rate => $money) {
+                    $item['rate']  = $rate;
+                    $item['total'] = $money;
+                    $rates_money[] = $item;
+                }
+            } else {
+                $rates_money = null;
+            }
+
+            if(empty($rates_money)) {
+                $result['bonus_rate'] = null;
+            } else {
+                $result['bonus_rate'] = $rates_money;
+            }
+            return self::outsuccess($result);
+        }
+        else {
+            return self::outsuccess(null);
+        }
+    }
+
+    public function listOp()
+    {
+        $model_cart	= Model('cart');
+        $minest_cartid = intval($_GET['minest_cartid']);
+        if($minest_cartid < 0) $minest_cartid = 0;
+
+        $save_type = $this->save_type();
+        if($_SESSION['is_login'] == 1)
+        {
+            $page_size = $this->page_size();
+            if($minest_cartid > 0) {
+                $condition = array('buyer_id'=>$_SESSION['member_id'],'cart_id' => array('lt',$minest_cartid));
+                $left = $model_cart->getCartListCount($condition);
+                $has_more = $left > $page_size;
+
+                $total = $model_cart->getCartListCount(array('buyer_id'=>$_SESSION['member_id']));
+                $pages = $this->pages($total);
+            } else {
+                $condition = array('buyer_id'=>$_SESSION['member_id']);
+                $total = $model_cart->getCartListCount(array('buyer_id'=>$_SESSION['member_id']));
+                $pages = $this->pages($total);
+                $has_more = $total > $page_size;
+            }
+            $cart_list	= $model_cart->listCart($save_type,$condition,$page_size);
+        }
+        else
+        {
+            $cart_list	= $model_cart->listCart($save_type);
+            $total = count($cart_list);
+            $has_more = false;
+            $pages = 1;
+        }
+
+        $goods_ids = array();
+        $cart_infos = array();
+        foreach ($cart_list as $item) {
+            $cart_item['cart_id'] = intval($item['cart_id']);
+            $cart_item['goods_id'] = intval($item['goods_id']);
+            $cart_item['bl_id'] = intval($item['bl_id']);
+            $cart_item['goods_num'] = intval($item['goods_num']);
+
+            $goods_ids[] = intval($item['goods_id']);
+            $cart_infos[] = $cart_item;
+        }
+
+        $helper = new goods_helper($this->price_calcer(),false);
+        $summaries = $helper->cart_summary($goods_ids,$related_goods);
+        $summary_list = $summaries['summary'];
+        if(!empty($related_goods)) {
+            $related_summary = $helper->cart_summary($related_goods,$x);
+            $summary_list = array_merge($summary_list,$related_summary['summary']);
+        }
+
+        //有可能购物车中的商品被删除....
+        $avables_goods = [];
+        foreach ($summary_list as $summay) {
+            $avables_goods[] = $summay['goods_id'];
+        }
+
+        $err_goods = algorithm::not_in($goods_ids,$avables_goods);
+        $cart_infos = $this->remove_err($cart_infos,$err_goods);
+
+        if($minest_cartid == 0) {
+            $ret['free_info'] = $this->full_send();
+        }
+
+        $ret['cart_count'] = $total;
+        $ret['cart_list']  = $cart_infos;
+        $ret['summary']  = $summary_list;
+        $ret['groupbuy'] = $summaries['groupbuy'];
+        $ret['limitime'] = $summaries['limitime'];
+        $ret['bundling'] = $summaries['bundling'];
+        $ret['mobile_page'] = array('hasmore' => $has_more,'page_total' => $pages);
+
+        return self::outsuccess($ret);
+    }
+
+    public function exgoodsOp()
+    {
+        $mod_fcode = Model('goods_fcode');
+        $mobile = session_helper::mobile();
+        if(empty($mobile))
+        {
+            return self::outsuccess(['special_list' => null,
+                'fcodes' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)]);
+        }
+
+        $items = $mod_fcode->getFcodeList(['mobile' => session_helper::mobile(), 'usable_time' => array('gt',time()),'fc_state' => 0],
+                                          '*','fc_state asc,fc_id asc',$this->page_size());
+        $page_count = $mod_fcode->gettotalpage();
+
+        if($this->page_no() == 1)
+        {
+            if(isset($_SESSION['fcodes'])) {
+                unset($_SESSION['fcodes']);
+            }
+        }
+
+        $fcodes = [];
+        $gids = [];
+
+        foreach ($items as $item)
+        {
+            $fcoder = new fcode\mfcode($item);
+            $fcode = $fcoder->format();
+            if($fcode != false)
+            {
+                $gids[] = intval($fcode['goods_id']);
+                $fcodes[] = $fcode;
+            }
+        }
+
+        if(empty($fcodes))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'fcodes' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_count)));
+        }
+        else
+        {
+            if($this->page_no() == 1 && $this->mFcodeBannerID > 0)
+            {
+                $blocks = special_manager::instance()->special($this->mFcodeBannerID,$unused_gids);
+                $items = $this->format($fcodes);
+                $blocks = array_merge($blocks,$items);
+            }
+            else {
+                $blocks = $this->format($fcodes);
+            }
+
+            $helper = new goods_helper($this->price_calcer(),false);
+            $ret = $helper->cart_summary($gids,$related_goods);
+
+            return self::outsuccess(array('special_list' => $blocks,
+                'fcodes' => $fcodes,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page($page_count)));
+        }
+    }
+
+    private function format($fcodes)
+    {
+        $blocks = [];
+        if(!empty($fcodes)) {
+            $blocks[] = special_formater::def_divider();
+        }
+
+        foreach ($fcodes as $fcode)
+        {
+            $block = [];
+            $block['item_title'] = '';
+            $block['item_type'] = 'home1';
+            $block['scale'] = 3.224299;
+
+            $item['image'] = '';
+            $item['show_type'] = "fcode";
+            $item['show_data'] = strval($fcode['fcode_id']);
+            $item['type'] = "goods";
+            $item['data'] = strval($fcode['goods_id']);;
+            $item['title'] = '';
+
+            $block['items'][] = $item;
+            $blocks[] = $block;
+            $blocks[] = special_formater::def_divider();
+        }
+
+        return $blocks;
+    }
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    private function remove_err($cart_infos,$err_goods)
+    {
+        if(empty($err_goods)) return $cart_infos;
+
+        $result = [];
+        foreach ($cart_infos as $cart)
+        {
+            if($cart['bl_id'] > 0) {
+                $result[] = $cart;
+            }
+            else
+            {
+                if(algorithm::binary_search($err_goods,$cart['goods_id']) == false) {
+                    $result[] = $cart;
+                }
+                else
+                {
+                    $cart_id = intval($cart['cart_id']);
+                    if($cart_id <= 0) continue;
+
+                    $model_cart	= Model('cart');
+                    $model_cart->where(['cart_id' => $cart_id])->delete();
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    private function full_send()
+    {
+        $result = [];
+
+        $rules = activity_helper::fullsent_rules();
+        foreach ($rules as $rule) {
+            $item['title'] = '内买优惠';
+            $item['value'] = $rule;
+            $result[] = $item;
+        }
+
+        $free_ship = activity_helper::free_ship();
+        if($free_ship != false) {
+            $item['title'] = '全场包邮';
+            $item['value'] = $free_ship;
+            $result[] = $item;
+        }
+
+        $item['title'] = '红包抵扣';
+        $item['value'] = "多件商品时,先计算商品天猫总价,再用红包抵扣";
+        $result[] = $item;
+
+        return $result;
+    }
+
+    public function addexOp()
+    {
+        $ret = $this->do_add($err,$ext_info);
+        if($ret === false) {
+            $msg = isset($err['msg']) ? $err['msg'] : '';
+            return self::outerr($err['code'],$msg);
+        }
+        else
+        {
+            $bl_id    = intval($ext_info['bl_id']);
+            $goods_id = intval($ext_info['goods_id']);
+            $cart_id  = intval($ext_info['cart_id']);
+
+            $model_cart = Model('cart');
+            $save_type = $this->save_type();
+            $cart_num  = $model_cart->getCartNum($save_type,array('buyer_id'=>$_SESSION['member_id']));
+            $goods_num = $model_cart->getCartItemNum($save_type,$cart_id);
+            $item = new cart_item($cart_id,$bl_id,$goods_id,$goods_num);
+
+            $result['cart_count'] = $cart_num;
+            $result['cart_list'][] = $item->format();
+
+            $gids = $item->goods_ids();
+            if(empty($gids)) {
+                $result['summary']  = array();
+                $result['groupbuy'] = array();
+                $result['limitime'] = array();
+                $result['bundling'] = array();
+            }
+            else
+            {
+                $helper = new goods_helper($this->price_calcer(),false);
+                $summaries = $helper->cart_summary($gids,$related_goods);
+                $summary_list = $summaries['summary'];
+                if(!empty($related_goods)) {
+                    $related_summary = $helper->cart_summary($related_goods,$x);
+                    $summary_list = array_merge($summary_list,$related_summary['summary']);
+                }
+
+                $result['summary']  = $summary_list;
+                $result['groupbuy'] = $summaries['groupbuy'];
+                $result['limitime'] = $summaries['limitime'];
+                $result['bundling'] = $summaries['bundling'];
+            }
+            return self::outsuccess($result);
+        }
+    }
+
+    public function cart_listOp()
+    {
+        if($_SESSION['is_login'] != 1) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+
+        $page = trim($_GET['page']);
+        $curpage = trim($_GET['curpage']);
+        if (!isset($_GET['page'])) {
+            $page = "100";
+            $curpage = "1";
+            $this->page_size = 100;
+        }
+        $this->initpage($page, $curpage);
+
+        $model_cart = Model('cart');
+        $model_goods = Model('goods');
+
+        $condition  = array('buyer_id' => $_SESSION['member_id']);
+        $cart_list  = $model_cart->getCartList($condition, $this->page_size);
+        $page_count = $model_cart->gettotalpage();
+
+        $model_cart->cls();
+        foreach ($cart_list as $key => $value) {
+            $goods_id = $value['goods_id'];
+            $goods_promotion = $model_goods->getGoodsInfoAndPromotionById($goods_id);
+            $goods_storage = $model_goods->getGoodsStorageById($goods_id);
+            $promotion_type = '';
+            $promotion_price = '0.00';
+            if (!empty($goods_promotion['groupbuy_info'])) {
+                $promotion_type = '抢购';
+                $promotion_price = $goods_promotion['groupbuy_info']['groupbuy_price'];
+            }
+            if (!empty($goods_promotion['xianshi_info'])) {
+                $promotion_type = '限时折扣';
+                $promotion_price = $goods_promotion['xianshi_info']['xianshi_price'];
+            }
+            $goods_spec = unserialize($goods_promotion['goods_spec']);
+            $goods_spec_array = array();
+
+            if(!empty($goods_spec))
+            {
+                foreach ($goods_spec as $val) {
+                    array_push($goods_spec_array, $val);
+                }
+            }
+
+            $cart_list[$key]['goods_storage'] = $goods_storage;
+            $cart_list[$key]['goods_spec'] = implode(',', $goods_spec_array);
+            $cart_list[$key]['promotion_type'] = $promotion_type;
+            $cart_list[$key]['promotion_price'] = $promotion_price;
+            $cart_list[$key]['goods_image_url'] = cthumb($value['goods_image'], $value['store_id']);
+            $cart_list[$key]['goods_sum'] = ncPriceFormat($value['goods_price'] * $value['goods_num']);
+        }
+
+        self::outsuccess(array('cart_list' => $cart_list, 'mobile_page' => mobile_page($page_count)));
+    }
+
+    public function addOp()
+    {
+        $ret = $this->do_add($err,$ext_info);
+        if($ret === false) {
+            $msg = isset($err['msg']) ? $err['msg'] : '';
+            return self::outerr($err['code'],$msg);
+        } else {
+            return self::outsuccess($ret);
+        }
+    }
+
+    public function do_add(&$err,&$ext_info)
+    {
+        if (is_numeric($_GET['goods_id']) && is_numeric($_POST['quantity']))
+        {
+            $goods_id = intval($_POST['goods_id']);
+            $quantity = intval($_POST['quantity']);
+
+            if ($goods_id <= 0 || $quantity <= 0) {
+                $err = array('code' => errcode::ErrInputParam);
+                return false;
+            }
+            $model_goods = Model('goods');
+            $logic_buy_1 = Logic('buy_1');
+            $goods_info = $model_goods->getGoodsOnlineInfoAndPromotionById($goods_id);
+            $logic_buy_1->getGroupbuyInfo($goods_info);
+            $logic_buy_1->getXianshiInfo($goods_info, $quantity);
+
+            if(array_key_exists('ifgroupbuy',$goods_info) && $goods_info['ifgroupbuy'] == true)
+            {
+                if ($_SESSION['is_login'] != 1)
+                {
+                    $err = array('code' => errcode::ErrAddCart,'msg' => "只能登录后,才能向购物车添加抢购商品.");;
+                    return false;
+                }
+            }
+
+            if(array_key_exists('ifxianshi',$goods_info) && $goods_info['ifxianshi'] == true)
+            {
+                if ($_SESSION['is_login'] != 1)
+                {
+                    $err = array('code' => errcode::ErrAddCart,'msg' => "只能登录后,才能向购物车添加限时购商品.");;
+                    return false;
+                }
+            }
+
+            $ret = $this->check_goods($goods_info, $quantity);
+            if(is_array($ret)) {
+                $err = $ret;
+                return false;
+            }
+            $bl_id = 0;
+        }
+        elseif (is_numeric($_GET['bl_id']))
+        {
+            if ($_SESSION['is_login'] != 1) {
+                $err = array('code' => errcode::ErrUnLogin);
+                return false;
+            }
+            $bl_id = intval($_GET['bl_id']);
+            if ($bl_id <= 0) {
+                $err = array('code' => errcode::ErrInputParam);
+                return false;
+            }
+
+            $model_bl = Model('p_bundling');
+            $bl_info = $model_bl->getBundlingInfo(array('bl_id'=>$bl_id));
+            if (empty($bl_info) || $bl_info['bl_state'] == '0') {
+                $err = array('code' => errcode::ErrBLUnExist);
+                return false;
+            }
+
+            $bl_goods_list = $model_bl->getBundlingGoodsList(array('bl_id'=>$bl_id));
+            $goods_id_array = array();
+            $bl_amount = 0;
+            foreach ($bl_goods_list as $goods) {
+                $goods_id_array[] = $goods['goods_id'];
+                $bl_amount += $goods['bl_goods_price'];
+            }
+
+            $model_goods = Model('goods');
+            $goods_list = $model_goods->getGoodsOnlineListAndPromotionByIdArray($goods_id_array);
+            foreach ($goods_list as $goods)
+            {
+                $err = $this->check_goods($goods,1);
+                if($err === true) {
+                    continue;
+                } else {
+                    return false;
+                }
+            }
+
+            //优惠套装作为一条记录插入购物车,图片取套装内的第一个商品图
+            $goods_info    = array();
+            $goods_info['store_id']	= $bl_info['store_id'];
+            $goods_info['goods_id']	= $goods_list[0]['goods_id'];
+            $goods_info['goods_name'] = $bl_info['bl_name'];
+            $goods_info['goods_price'] = $bl_amount;
+            $goods_info['goods_num']   = 1;
+            $goods_info['goods_image'] = $goods_list[0]['goods_image'];
+            $goods_info['store_name'] = $bl_info['store_name'];
+            $goods_info['bl_id'] = $bl_id;
+            $quantity = 1;
+            $goods_id = intval($goods_info['goods_id']);
+        }
+        else
+        {
+            $err = array('code' => errcode::ErrInputParam);
+            return false;
+        }
+        $save_type = $this->save_type();
+        if($_SESSION['member_id']) {
+            $goods_info['buyer_id'] = $_SESSION['member_id'];
+        }
+
+        $model_cart = Model('cart');
+        $insert = $model_cart->addCart($goods_info, $save_type , $quantity);
+
+        if ($insert) {
+            $data = array('result' => 1, 'num' => $model_cart->cart_goods_num, 'amount' => ncPriceFormat($model_cart->cart_all_price));
+            $ext_info = array('bl_id' => $bl_id,'goods_id' => $goods_id,'cart_id' => $insert);
+            return $data;
+        } else {
+            $err = array('code' => errcode::ErrAddCart);
+            return false;
+        }
+    }
+
+    private function check_goods($goods_info, $quantity)
+    {
+        if(empty($quantity)) {
+            return array('code' => errcode::ErrInputParam, 'msg' => errcode::msg(errcode::ErrInputParam));
+        }
+        if(empty($goods_info)) {
+            return array('code' => errcode::ErrGoodsOff, 'msg'=> '商品已下架或不存在');
+        }
+        if ($goods_info['store_id'] == $_SESSION['store_id']) {
+            return array('code' => errcode::ErrCanNotBuyOwn, 'msg'=> errcode::msg(errcode::ErrCanNotBuyOwn));
+        }
+        if(intval($goods_info['goods_storage']) < 1) {
+            return array('code' => errcode::ErrGoodsOutofStock, 'msg' => errcode::msg(errcode::ErrGoodsOutofStock));
+        }
+        if(intval($goods_info['goods_storage']) < $quantity) {
+            return array('code' => errcode::ErrStorageShort, 'msg' => errcode::msg(errcode::ErrStorageShort));
+        }
+        if ($goods_info['is_virtual'] || $goods_info['is_presell']) {
+            return array('code' => errcode::ErrGoodsSpecial, 'msg' => errcode::msg(errcode::ErrGoodsSpecial));
+        }
+        $is_fcode = intval($goods_info['is_fcode']) == 1 ? true : false;
+        if($is_fcode)
+        {
+            if(!session_helper::logined()) {
+                return array('code' => errcode::ErrLogin, 'msg' => 'F码商品,只有在登录后才能添加到购物车');
+            }
+            else
+            {
+                if($this->mUserFcode == null) {
+                    $this->mUserFcode = new user_session\fcode();
+                    $this->mUserFcode->onStatus();
+                }
+                $goods_id = intval($goods_info['goods_id']);
+                $num = $this->mUserFcode->goods_has_code($goods_id,$lock_num);
+                if($num == false)
+                {
+                    if($lock_num > 0) {
+                        return array('code' => errcode::ErrLogin, 'msg' => '等确认收货后该商品的F码才可以使用.');
+                    } else {
+                        return array('code' => errcode::ErrLogin, 'msg' => '您没有该商品F码,请领取F码后再购买.');
+                    }
+                }
+                elseif($num < $quantity) {
+                    return array('code' => errcode::ErrLogin, 'msg' => "该商品F码,只够购买{$num}支.");
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public function cart_editOp()
+    {
+        if($_SESSION['is_login'] != 1) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+
+        $cart_list = explode(',', urldecode($_POST['cart_list']));
+        $new_cart_list = array();
+        if (is_array($cart_list))
+        {
+            foreach ($cart_list as $value) {
+                if (preg_match_all('/^(\d{1,10})\|(\d{1,6})$/', $value, $match)) {
+                    if (intval($match[2][0]) > 0) {
+                        $new_cart_list[$match[1][0]] = $match[2][0];
+                    }
+                }
+            }
+
+            $model_cart = Model('cart');
+            $condition = array('buyer_id' => $_SESSION['member_id']);
+            $original_cart_list = $model_cart->listCart(self::db_type, $condition);
+            $quantity_error = array();
+            foreach ($original_cart_list as $key => $value)
+            {
+                if (array_key_exists($value['cart_id'], $new_cart_list))
+                {
+                    $quantity = intval($new_cart_list[$value['cart_id']]);
+                    if (intval($value['goods_num']) !== $quantity)
+                    {
+                        if (!$this->check_goods_storage($value, $quantity)) {
+                            array_push($quantity_error, array('cart_id' => $value['cart_id'], 'quantity' => $quantity, 'err_info' => '库存不足'));
+                        } else {
+                            $data = array();
+                            $data['goods_num'] = $quantity;
+                            $update = $model_cart->editCart($data, array('cart_id' => $value['cart_id']));
+                            if (!$update) {
+                                return self::outerr(errcode::ErrCart, '购物车修改失败');
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    $delete = $model_cart->delCart(self::db_type, array('cart_id' => $value['cart_id']));
+                    if (!$delete) {
+                        return self::outerr(errcode::ErrCart, '购物车修改失败');
+                    }
+                }
+            }
+
+            if (count($quantity_error) > 0) {
+                self::outsuccess(array('result' => '0', 'quantity_error' => $quantity_error));
+            } else {
+                self::outsuccess(array('result' => '1','quantity_error' => NULL));
+            }
+        }
+        else {
+            return self::outerr(errcode::ErrCart, '购物车列表格式错误');
+        }
+    }
+
+    /**
+     * 购物车更新商品数量
+     */
+    public function editOp()
+    {
+        $cart_id = intval($_POST['cart_id']);
+        $quantity = intval($_POST['quantity']);
+
+        if ($cart_id <= 0 || $quantity < 0) {
+            return self::outerr(errcode::ErrInputParam);
+        }
+
+        if($quantity > 0) {
+            $ret = $this->do_edit(intval(abs($cart_id)),intval($quantity));
+        }
+        else {
+            $ret = $this->do_del($cart_id);
+        }
+
+        if ($ret === true) {
+            $save_type = $this->save_type();
+            $mod_cart = Model('cart');
+            $cart_num  = $mod_cart->getCartNum($save_type,array('buyer_id'=>$_SESSION['member_id']));
+            $goods_num = $mod_cart->getCartItemNum($save_type,$cart_id);
+
+            $result['cart_count'] = $cart_num;
+            $result['cart_id'] = $cart_id;
+            $result['goods_num'] = $goods_num;
+
+            self::outsuccess($result);
+        } else {
+            self::outerr(errcode::ErrAddCart,$ret['err_info']);
+        }
+    }
+
+    public function do_edit($cart_id,$quantity_in)
+    {
+        $model_cart = Model('cart');
+        $model_goods= Model('goods');
+        $logic_buy_1 = logic('buy_1');
+
+        $quantity = $quantity_in;
+
+        //存放返回信息
+        $cart_info = $model_cart->getCartInfo(array('cart_id'=>$cart_id,'buyer_id'=>$_SESSION['member_id']));
+        if ($cart_info['bl_id'] == '0')
+        {
+            //普通商品
+            $goods_id = intval($cart_info['goods_id']);
+            $goods_info	= $logic_buy_1->getGoodsOnlineInfo($goods_id,$quantity);
+            if(empty($goods_info))
+            {
+                if($_SESSION['is_login'] == 1) {
+                    QueueClient::push('delCart', array('buyer_id'=>$_SESSION['member_id'],'cart_ids'=>array($cart_id)));
+                }
+                return array('cart_id' => $cart_id, 'quantity' => $quantity, 'err_info' => '商品已被下架');
+            }
+
+            $logic_buy_1->getGroupbuyInfo($goods_info);
+            $logic_buy_1->getXianshiInfo($goods_info,$quantity);
+            $quantity = $goods_info['goods_num'];
+            if($quantity == $cart_info['goods_num']) {
+                return array('cart_id' => $cart_id, 'quantity' => $quantity, 'err_info' => "该商品只允许抢购{$quantity}件~");
+            }
+            if(intval($goods_info['goods_storage']) < $quantity) {
+                $model_cart->editCart(array('goods_num'=>$goods_info['goods_storage']),array('cart_id'=>$cart_id,'buyer_id'=>$_SESSION['member_id']));
+                return array('cart_id' => $cart_id, 'quantity' => $goods_info['goods_storage'], 'err_info' => '库存不足,已将您购物车更新为库存数量.');
+            }
+        }
+        else
+        {
+            //优惠套装商品
+            $model_bl = Model('p_bundling');
+            $bl_goods_list = $model_bl->getBundlingGoodsList(array('bl_id'=>$cart_info['bl_id']));
+            $goods_id_array = array();
+            foreach ($bl_goods_list as $goods) {
+                $goods_id_array[] = $goods['goods_id'];
+            }
+            $goods_list = $model_goods->getGoodsOnlineListAndPromotionByIdArray($goods_id_array);
+
+            //如果其中有商品下架,删除
+            if (count($goods_list) != count($goods_id_array)) {
+                QueueClient::push('delCart', array('buyer_id'=>$_SESSION['member_id'],'cart_ids'=>array($cart_id)));
+                return array('cart_id' => $cart_id, 'quantity' => 0, 'err_info' => '该优惠套装已经无效,建议您购买单个商品.');
+            }
+
+            //如果有商品库存不足,更新购买数量到目前最大库存
+            foreach ($goods_list as $goods_info)
+            {
+                if ($quantity > $goods_info['goods_storage']) {
+                    $model_cart->editCart(array('goods_num'=>$goods_info['goods_storage']),array('cart_id'=>$cart_id,'buyer_id'=>$_SESSION['member_id']));
+                    return array('cart_id' => $cart_id, 'quantity' => $goods_info['goods_storage'], 'err_info' => '该优惠套装部分商品库存不足,建议您降低购买数量或购买库存足够的单个商品.');
+                }
+            }
+            $goods_info['goods_price'] = $cart_info['goods_price'];
+        }
+
+        $data = array();
+        $data['goods_num'] = $quantity;
+        $data['goods_price'] = $goods_info['goods_price'];
+
+        $update = $model_cart->editCart($data,array('cart_id'=>$cart_id,'buyer_id'=>$_SESSION['member_id']));
+        if ($update) {
+            return true;
+        } else {
+            return array('cart_id' => $cart_id, 'quantity' => 0, 'err_info' => '更新购物车失败.');
+        }
+    }
+
+    private function do_del($cart_id)
+    {
+        $save_type = $this->save_type();
+        $model_cart	= Model('cart');
+        if ($_SESSION['member_id']) {
+            $delete	= $model_cart->delCart($save_type,array('cart_id'=>$cart_id,'buyer_id'=>$_SESSION['member_id']));
+            return $delete;
+        } else {
+            $delete	= $model_cart->delCart($save_type,array('cart_id'=>$cart_id));
+            return $delete;
+        }
+    }
+
+    public function delOp()
+    {
+        $cart_id = intval($_POST['cart_id']);
+        if($cart_id <=0 ) {
+            return self::outerr(errcode::ErrInputParam);
+        }
+
+        $ret = $this->do_del($cart_id);
+        if($ret) {
+            return self::outsuccess(array('result' => '1'));
+        } else {
+            return self::outerr(errcode::ErrCartDelError);
+        }
+    }
+
+    public function cart_delOp()
+    {
+        if($_SESSION['is_login'] != 1) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+
+        $cart_id = intval($_POST['cart_id']);
+        $model_cart = Model('cart');
+        if ($cart_id > 0) {
+            $condition = array();
+            $condition['buyer_id'] = $_SESSION['member_id'];
+            $condition['cart_id'] = $cart_id;
+
+            $model_cart->delCart(self::db_type, $condition);
+        }
+
+        self::outsuccess(array('result' => '1'));
+    }
+
+    private function check_goods_storage($cart_info, $quantity)
+    {
+        $model_goods = Model('goods');
+        $model_bl = Model('p_bundling');
+        $logic_buy_1 = Logic('buy_1');
+
+        if ($cart_info['bl_id'] == '0') {
+            //普通商品
+            $goods_info = $model_goods->getGoodsOnlineInfoAndPromotionById($cart_info['goods_id']);
+            $logic_buy_1->getGroupbuyInfo($goods_info);
+            $logic_buy_1->getXianshiInfo($goods_info, $quantity);
+
+            if (intval($goods_info['goods_storage']) < $quantity) {
+                return false;
+            }
+        }
+        else
+        {
+            //优惠套装商品
+            $bl_goods_list = $model_bl->getBundlingGoodsList(array('bl_id' => $cart_info['bl_id']));
+            $goods_id_array = array();
+            foreach ($bl_goods_list as $goods) {
+                $goods_id_array[] = $goods['goods_id'];
+            }
+            $bl_goods_list = $model_goods->getGoodsOnlineListAndPromotionByIdArray($goods_id_array);
+
+            //如果有商品库存不足,更新购买数量到目前最大库存
+            foreach ($bl_goods_list as $goods_info) {
+                if (intval($goods_info['goods_storage']) < $quantity) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private function save_type()
+    {
+        if ($_SESSION['is_login'] == 1) {
+            $save_type = self::db_type;
+        } else {
+            $save_type = self::session_type;
+        }
+        return $save_type;
+    }
+}

+ 20 - 0
mapi/control/category.php

@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/5/9
+ * Time: 下午9:05
+ */
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/category_helper.php');
+
+class categoryControl extends mobileControl
+{
+    public function indexOp()
+    {
+        $cats = category_helper::instance()->categories();
+        return self::outsuccess(array('items' => $cats));
+    }
+}

+ 58 - 0
mapi/control/config.php

@@ -0,0 +1,58 @@
+<?php
+/**
+ * 更新
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/ugc_helper.php');
+
+class configControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function getconfigexOp()
+    {
+        $result['app_config'] = ['sale_mobile' => '021-64260858',
+            'index_tip' => '登录后会显示您的专属红包价',
+            'login_tip' => '提示: 领到红包用户,可直接用微信登录',
+            'cancel_order_tip' => '取消订单后只退还红包,不退F码,确定要取消订单吗?',
+            'refund_money_tip' => '申请退款后红包与F码均不会退还,确定要申请退款吗?',
+            'cart_unlogin_tip' => '登录后,才能显示总价',
+            'ugc_categories' => ugc_helper::categories()];
+        return self::outsuccess($result);
+    }
+    
+    /**
+     * 获取配置文件
+     * 参数: platform 1:android 2:ios
+     */
+    public function getconfigOp()
+    {
+        $platform = trim($_GET['platform']);
+        $ver_code = trim($_GET['ver_code']);
+        if (!isset($platform) || empty($platform)) {
+            return self::outerr(errcode::ErrInputParam);
+        }
+        if (!isset($ver_code) || empty($ver_code)) {
+            return self::outerr(errcode::ErrInputParam);
+        }
+
+        $result = Model()->table('config')->select();
+        if (empty($result)) {
+            return self::outerr(errcode::ErrGetConfig);
+        }
+        else
+        {
+            $ret = array();
+            foreach ($result as $value) {
+                $ret[$value['name']] = array('value'=>$value['value']);
+            }
+            $ret['feed_back_url'] = array('value'=> BASE_SITE_URL . '/mobile/index.php?act=member_feedback&op=add&client_type=ios');
+        }
+        return self::outsuccess($ret);
+    }
+}

+ 412 - 0
mapi/control/control.php

@@ -0,0 +1,412 @@
+<?php
+declare(strict_types=0);
+/**
+ * mobile父类
+ *
+ *
+ */
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once (BASE_HELPER_PATH . "/statistics_helper.php");
+require_once (BASE_HELPER_PATH . "/session_helper.php");
+require_once (BASE_HELPER_PATH . "/bonus_helper.php");
+
+/********************************** 前台control父类 **********************************************/
+class mobileControl
+{
+    //客户端类型
+    private static $stClienTypes = ['android', 'wap', 'wechat', 'ios', 'ajax', 'web','mini'];
+
+    //列表默认分页数
+    protected $page_size;
+    protected $cur_page;
+
+    //任务开始时间
+    private static $startime = 0;
+
+    public function __construct()
+    {
+        self::$startime = microtime(true);
+        //Language::read('mobile');
+        //分页数处理
+        if (is_numeric($_GET['page']) && intval(trim($_GET['page'])) > 0) {
+            $this->page_size = intval(trim($_GET['page']));
+        } else {
+            $this->page_size = 20;
+        }
+
+        if (is_numeric($_GET['curpage']) && intval(trim($_GET['curpage'])) > 0) {
+            $this->cur_page = intval(trim($_GET['curpage']));
+        } else {
+            $this->cur_page = 1;
+        }
+        $this->initpage($this->page_size, $this->cur_page);
+        $this->check_app_type();
+        $param = $_GET;
+        $param['client_type'] = $_SESSION['client_type'];
+
+        $this->set_relay();
+        statistics_helper::instance()->add_call($param);
+
+        $client_tpe = session_helper::client_type();
+        if($client_tpe == session_helper::device_wap) {
+            $unused = 0;
+        }
+        elseif(session_helper::version_code() > 168) {
+            if(!$this->verify()) {
+                throw new UnSignException();
+            }
+        }
+        else {
+            $unused = 0;
+        }
+    }
+
+    private function verify()
+    {
+        $pub = $this->pubKey();
+        $input = $_GET;
+        $sign = $input['sign'];
+        $input['sign'] = null;
+        $input['from'] = null;
+
+        $data = $this->sign($input);
+        $res = openssl_verify($data,base64_decode($sign),$pub);
+        Log::record("openssl_verify res={$res}",Log::DEBUG);
+
+        return $res == 1;
+    }
+    protected function checkEmpty($value) {
+        if (!isset($value))
+            return true;
+        if ($value === null)
+            return true;
+        if (trim($value) === "")
+            return true;
+
+        return false;
+    }
+
+    private function sign($params)
+    {
+        ksort($params);
+
+        $body = "";
+        $i = 0;
+        foreach ($params as $k => $v)
+        {
+            if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1))
+            {
+                if ($i == 0) {
+                    $body .= "{$k}" . "=" . urlencode($v);
+                } else {
+                    $body .= "&" . "{$k}" . "=" . urlencode($v);
+                }
+                $i++;
+            }
+        }
+        return $body;
+    }
+
+
+    private function record_path()
+    {
+        $record = [];
+        $record['user_session'] = session_helper::session_id();
+        $record['member_id'] = session_helper::memberid();
+        $record['relay_id'] = session_helper::relay_id();
+        $record['add_time'] = time();
+        $record['exec_time'] = intval((microtime(true) - self::$startime) * 1000000);
+        $record['content'] = $_SERVER['post_content'];
+        $record['client_type'] = session_helper::client_type();
+
+        if(!empty($_GET['from'])) {
+            $from = base64_decode($_GET['from']);
+            Log::record("ort={$_GET['from']}",Log::DEBUG);
+            Log::record("from={$from}",Log::DEBUG);
+        }
+        Log::record_path(json_encode($record));
+    }
+
+    public function __destruct()
+    {
+        $this->record_path();
+    }
+
+    private function set_relay()
+    {
+        if(isset($_GET['relay_id'])) {
+            session_helper::set_relay($_GET['relay_id']);
+        }
+        elseif (isset($_COOKIE['relay_id'])) {
+            session_helper::set_relay($_COOKIE['relay_id']);
+        }
+    }
+
+    protected function initpage($page_size,$cur_page)
+    {
+        pagecmd('seteachnum', $page_size);
+        pagecmd('setnowpage', $cur_page);
+    }
+
+    protected function price_calcer()
+    {
+        if(session_helper::logined()) {
+            return new bonus\account(session_helper::memberid(),true);
+        } else {
+            return new bonus\normal_calc();
+        }
+    }
+
+    protected function android()
+    {
+        return $_SESSION['client_type'] == 'android';
+    }
+
+    protected function page_size()
+    {
+        return $this->page_size;
+    }
+
+    protected function page_no()
+    {
+        return $this->cur_page;
+    }
+
+    protected function pages($count)
+    {
+        return intval($count / $this->page_size()) + ($count % $this->page_size() == 0 ? 0 : 1);
+    }
+
+    /**
+     * @throws UnloginException
+     */
+    protected function need_login()
+    {
+        if ($_SESSION['is_login'] != 1) {
+            throw new UnloginException();
+        }
+    }
+
+    private static function eclipse_time()
+    {
+        return (microtime(true) - self::$startime);
+    }
+
+    protected function check_app_type()
+    {
+        $client  = strtolower(trim($_SERVER['HTTP_CLIENT_TYPE']));
+        $version = trim($_SERVER['HTTP_CLIENT_VERSION']);
+        Log::record("HTTP_CLIENT_VERSION:{$version}",Log::DEBUG);
+
+        if (empty($client)) {
+            $client = $_POST['client_type'];
+            Log::record($_POST['client_type'],Log::DEBUG);
+        } else {
+            $_SESSION['is_app'] = true;
+        }
+
+        if (empty($client) || !in_array($client, self::$stClienTypes)) {
+            $_SESSION['client_type'] = 'wap';
+        } else {
+            $_SESSION['client_type'] = $client;
+        }
+
+        if (!empty($version)) {
+            $_SESSION['client_version'] = $version;
+        } else {
+            $_SESSION['client_version'] = '';
+        }
+
+        $version = intval(floatval($version) * 100 + 0.5);
+        if($client == 'ios')
+        {
+            $cur_ver = $GLOBALS['setting_config']['mobile_ios_version'];
+            $lastest_version = intval($cur_ver * 100 + 0.5);
+            if($version >= $lastest_version) {
+                $_SESSION['is_lasted'] = true;
+            } else {
+                $_SESSION['is_lasted'] = false;
+            }
+        }
+        elseif($client == 'android')
+        {
+            $cur_ver = $GLOBALS['setting_config']['mobile_apk_version'];
+            $lastest_version = intval($cur_ver * 100 + 0.5);
+
+            if($version >= $lastest_version) {
+                $_SESSION['is_lasted'] = true;
+            } else {
+                $_SESSION['is_lasted'] = false;
+            }
+        }
+
+        return true;
+    }
+
+    public static function outerr($code, $msg = '', $page = '', $type = NULL)
+    {
+        static $json_clients = ['android', 'ios','mini'];
+
+        if(!empty($type)) {
+            $show_type = $type;
+        } else {
+            $show_type = $_SESSION['client_type'];
+        }
+
+        if (in_array($show_type, $json_clients))
+        {
+            joutput_error($code, $msg);
+        }
+        elseif ($show_type == 'wap')
+        {
+            Tpl::clear();
+            Tpl::output("error", $msg);
+            if (!empty($page)) {
+                Tpl::showpage($page);
+            }
+        }
+        elseif ($show_type == 'ajax')
+        {
+            $callback = $_GET['callback'];
+            if(!isset($callback) || empty($callback)) {
+                joutput_error($code, $msg);
+            } else {
+                echo "{$callback}(";
+                joutput_error($code, $msg);
+                echo ");";
+            }
+        }
+        else
+        {
+            if(empty($msg)) {
+                $msg = errcode::msg($code);
+            }
+            $start = microtime(true);
+            echo joutput_error($code, $msg, 'web') . "<br/>";
+            perfor_period("joutput",$start,"web");
+
+            echo sprintf("eclipse_time = %.6f <br/><br/>", self::eclipse_time());
+            echo "性能关键统计:<br/><br/>";
+            echo perfor_log();
+
+            $sqls = Log::sql_log();
+            echo "sql count = " . count($sqls) . "<br/><br/>";
+            foreach ($sqls as $sql) {
+                echo "{$sql}<br/>";
+            }
+        }
+        return true;
+    }
+
+    public static function outsuccess($data, $page = '', $type = NULL)
+    {
+        static $json_clients = ['android', 'ios','mini'];
+
+        if(!empty($type)) {
+            $show_type = $type;
+        } else {
+            $show_type = $_SESSION['client_type'];
+        }
+
+        if (in_array($show_type, $json_clients))
+        {
+            joutput_data($data);
+        }
+        elseif ($show_type == 'wap')
+        {
+            Tpl::clear();
+            if (is_array($data)) {
+                foreach ($data as $key => $val) {
+                    Tpl::output($key, $val);
+                }
+            }
+            if (!empty($page)) {
+                Tpl::showpage($page);
+            }
+        }
+        elseif ($show_type == 'ajax')
+        {
+            $callback = $_GET['callback'];
+            if(!isset($callback) || empty($callback)) {
+                joutput_data($data);
+            } else {
+                echo "{$callback}(";
+                joutput_data($data);
+                echo ");";
+            }
+        }
+        else
+        {
+            echo 'success: return data=<br/>';
+            $start = microtime(true);
+            joutput_data($data, 'web');
+            perfor_period("joutput",$start,"web");
+
+            echo "<br/><br/>";
+            echo sprintf("eclipse_time = %.6f <br/><br/>", self::eclipse_time());
+            echo "性能关键统计:<br/><br/>";
+            echo perfor_log();
+            $sqls = Log::sql_log();
+            echo "sql count = " . count($sqls) . "<br/><br/>";
+
+            foreach ($sqls as $sql) {
+                echo "{$sql}<br/>";
+            }
+        }
+
+        return true;
+    }
+
+    public function separate_page($items,&$pages)
+    {
+        $arr_items = array_chunk($items,$this->page_size());
+        $pages = count($arr_items);
+        $page_no = $pages >= $this->page_no() ? $this->page_no() : $pages;
+        return ($arr_items[$page_no - 1]);
+    }
+    private function pubKey()
+    {
+        static $pub = null;
+        if($pub == null) {
+            $pub_key = BASE_DATA_PATH . '/api/alipay/key/lrlz_public_key.pem';
+            $key = file_get_contents($pub_key);
+            $pub = openssl_get_publickey($key);
+        }
+
+        return $pub;
+    }
+}
+
+class mobileHomeControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+}
+
+class mbMemberControl extends mobileControl
+{
+    public $err_code = errcode::Success;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        if (!session_helper::logined()) {
+            throw new UnloginException();
+        }
+    }
+}
+
+function bonus_version()
+{
+    return "v=2019012101";
+}
+function shop_version()
+{
+    return "v=2019012101";
+}

+ 177 - 0
mapi/control/convert.php

@@ -0,0 +1,177 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2018/12/12
+ * Time: 10:47 AM
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/fcode/operator.php');
+require_once(BASE_ROOT_PATH . '/helper/fcode/mfcode.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/helper/login_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/openapi/KeyManager.php');
+require_once(BASE_ROOT_PATH . '/helper/openapi/Convertor.php');
+
+class convertControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function userOp()
+    {
+        $fileds = ['appid','appkey','convert_sn','convert_type','time','mobile','return_url'];
+
+        $appid = $_GET['appid'];
+        $convert_sn = $_GET['convert_sn'];
+        $return_url = $_GET['return_url'];
+
+        if($this->check_parmas($_GET,$fileds) === false) {
+            $errmsg = ["title" => "请求参数异常","msg"=> "请不要随意修改参数哦"];
+            goto ErrorHandle;
+        }
+        $convert = new openapi\Convertor($fileds);
+        $fSucc = $convert->verify($_GET);
+        if($fSucc === false) {
+            $errmsg = ["title" => "请求参数异常","msg"=> "请不要随意修改参数哦"];
+            goto ErrorHandle;
+        }
+
+        $convert_type = $_GET['convert_type'];
+        if($convert_type == 'user')
+        {
+            $find = $convert->exist($_GET['convert_sn'],$_GET['appid']);
+            $mobile = $_GET['mobile'];
+            if(!session_helper::logined())
+            {
+                $mobile_loginner = new login\mobile_log($mobile);
+                if($mobile_loginner->ismember()) {
+                    $mobile_loginner->login();
+                } else {
+                    $mobile_loginner->register('',0,$mobile);
+                    $mobile_loginner->login();
+                }
+            }
+            if(!$find) {
+                $convert->add_user($appid,$convert_sn,$mobile);
+                account_helper::add_bonus(30,300,[session_helper::memberid()],"鑫福卡美妆红包",0,60);
+                $mod_member = Model('member');
+                $mod_member->editMember(['member_id' => session_helper::memberid()],['rewared_inviter' => 1]);
+
+                $return_url = $_GET['return_url'];
+                QueueClient::push('OnGoodsConvert',['appid' => $appid,'convert_sn' => $convert_sn,'return_url' => $return_url,'success' => true]);
+            }
+            $url = url_helper::mshop_special(1451);
+            //$url = url_helper::mshop_index();
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+        else {
+            $errmsg = ["title" => "红包兑换","msg"=> "这个业务还没有开启哦"];
+            goto ErrorHandle;
+        }
+
+
+        ErrorHandle:
+
+        QueueClient::push('OnGoodsConvert',['appid' => $appid,'convert_sn' => $convert_sn,'return_url' => $return_url,'success' => false]);
+        return self::outsuccess($errmsg,"convert/error");
+    }
+
+    public function fcodeOp()
+    {
+        $fileds = ['appid','appkey','convert_sn','convert_type','batch_code','commonid','time','mobile','return_url'];
+
+        $fCallBack = true;
+        $appid = $_GET['appid'];
+        $convert_sn = $_GET['convert_sn'];
+        $return_url = $_GET['return_url'];
+
+        if($this->check_parmas($_GET,$fileds) === false) {
+            $errmsg = ["title" => "请求参数异常","msg"=> "请不要随意修改参数哦"];
+            goto ErrorHandle;
+        }
+
+        $convert = new openapi\Convertor($fileds);
+        $fSucc = $convert->verify($_GET);
+        if($fSucc === false) {
+            $errmsg = ["title" => "请求参数异常","msg"=> "请不要随意修改参数哦"];
+            goto ErrorHandle;
+        }
+
+        $convert_type = $_GET['convert_type'];
+        if($convert_type == 'fcode')
+        {
+            $batch_code = $_GET['batch_code'];
+            $common_id  = intval($_GET['commonid']);
+            if(empty($batch_code) || $common_id <= 0) {
+                $errmsg = ["title" => "商品下架","msg"=> "没有找到要兑换的商品哦"];
+                goto ErrorHandle;
+            }
+
+            $find = $convert->exist($_GET['convert_sn'],$_GET['appid']);
+            if($find) {
+                $fCallBack = false;
+                $errmsg = ["title" => "商品下架","msg"=> "没有找到要兑换的商品哦"];
+                goto ErrorHandle;
+            }
+
+            $mobile = $_GET['mobile'];
+            if(!session_helper::logined())
+            {
+                $mobile_loginner = new login\mobile_log($mobile);
+                if($mobile_loginner->ismember()) {
+                    $mobile_loginner->login();
+                } else {
+                    $mobile_loginner->register('',0,$mobile);
+                    $mobile_loginner->login();
+                }
+            }
+
+            $oper = new fcode\operator($common_id,$batch_code,$mobile,'');
+            $fcode = $oper->send();
+            if($fcode == false) {
+                $errmsg = ["title" => "兑换失败","msg"=> "这个商品已经被兑换完了"];
+                goto ErrorHandle;
+            }
+            else {
+                $return_url = $_GET['return_url'];
+                QueueClient::push('OnGoodsConvert',['appid' => $appid,'convert_sn' => $convert_sn,'return_url' => $return_url,'success' => true]);
+                $convert->add_fcode($_GET['appid'],$_GET['convert_sn'],$_GET['batch_code'],$_GET['commonid'],$fcode,$_GET['mobile']);
+
+                return self::outsuccess(["title" => "兑换成功","msg"=> "您已经成功兑换商品"],"convert/success");
+            }
+        }
+        else {
+            $errmsg = ["title" => "红包兑换","msg"=> "这个业务还没有开启哦"];
+            goto ErrorHandle;
+        }
+
+        ErrorHandle:
+        if($fCallBack) {
+            QueueClient::push('OnGoodsConvert',['appid' => $appid,'convert_sn' => $convert_sn,'return_url' => $return_url,'success' => false]);
+        }
+
+        return self::outsuccess($errmsg,"convert/error");
+    }
+
+    private function check_parmas($input,$fields)
+    {
+        foreach ($fields as $key)
+        {
+            if(!array_key_exists($key,$input)) {
+                return false;
+            }
+            else
+            {
+                if(empty($input[$key])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}

+ 47 - 0
mapi/control/crash_log.php

@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class crash_logControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 上传日志接口
+     */
+    public function uploadOp()
+    {
+        $crash_content = $_POST['content'];
+        if (!empty($crash_content))
+        {
+            $platform = $_GET['client'];
+            if (!empty($platform)) {
+                $path = BASE_DATA_PATH . '/log/' . $platform . '/';
+            } else {
+                $path = BASE_DATA_PATH . '/log/default/';
+            }
+
+            if (!is_dir($path)) mkdir($path);
+
+            $version = $_GET['version'];
+            if (!empty($version)) {
+                $path = $path . $version . '/';
+            } else {
+                $path = $path . 'default/';
+            }
+
+            if (!is_dir($path)) mkdir($path);
+            $file_name = date('Ymd', time()) . '-' . random(4) . '.crash.log';
+            file_put_contents($path . $file_name, $crash_content, FILE_APPEND);
+        } else {
+            return joutput_error(errcode::ErrInputParam, '无crash内容');
+        }
+        joutput_data();
+    }
+}

+ 7 - 0
mapi/control/enterprise_certs.php

@@ -0,0 +1,7 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: huangdong
+ * Date: 2018/8/27
+ * Time: 上午11:04
+ */

+ 171 - 0
mapi/control/fcode.php

@@ -0,0 +1,171 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/4/6
+ * Time: 下午1:41
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/fcode/operator.php');
+require_once(BASE_ROOT_PATH . '/helper/fcode/mfcode.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/helper/login_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+
+class fcodeControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $common_id = intval($_GET['common_id']);
+        $batch_code = $_GET['batch_code'];
+        $status = intval($_GET['status']);
+        $mobile = empty(session_helper::mobile()) ? $_GET['mobile'] : session_helper::mobile();
+
+        if(session_helper::need_wechat_author()) {
+            $author = new thrid_author\wxauthor();
+            $url = author_url::fcode_url($common_id,$batch_code);
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        if($common_id <= 0 || empty($batch_code)) {
+            return self::outerr(errcode::ErrParamter,"错误的参数","fcode/error");
+        }
+
+        $oper = new fcode\operator($common_id,$batch_code,$mobile,session_helper::session_id());
+        $fcode = $oper->grabed();
+
+        $goods = $this->goods($common_id);
+        if($fcode == false)
+        {
+            if(empty($goods)) {
+                return self::outsuccess(array('error' => "商品已经下架,请关注其它F码"),"fcode/error",'wap');
+            }
+            elseif($status < 0) {
+                return self::outsuccess(array('error' => "该商品F码已经被抢光~"),"fcode/error",'wap');
+            }
+            else {
+                $name  = $goods['goods_name'];
+                $price = $goods['goods_price'];
+                $image = $goods['goods_image'];
+                $image = cthumb($image, 1280, 6);
+                return self::outsuccess(array('name' => $name,'price' => $price,'image' => $image,
+                    'common_id' => $common_id,'batch_code' => $batch_code), "fcode/index",'wap');
+            }
+        }
+        else
+        {
+            $name  = $goods['goods_name'];
+            $price = $goods['goods_price'];
+            $image = $goods['goods_image'];
+            $image = cthumb($image, 1280, 6);
+
+            $fcoder = new fcode\mfcode($fcode);
+            if($fcoder->binded())
+            {
+                return self::outsuccess(['fcode' => $fcode,'name' => $name,'price' => $price,'image' => $image],
+                    "fcode/success",'wap');
+            }
+            else
+            {
+                if(session_helper::logined())
+                {
+                    $oper->bind($fcode);
+                    $fcode = $oper->grabed();
+
+                    return self::outsuccess(['fcode' => $fcode,'name' => $name,'price' => $price,'image' => $image],
+                        "fcode/success",'wap');
+                } else {
+                    return self::outsuccess(['fcode' => $fcode,'name' => $name,'price' => $price,'image' => $image],
+                        "fcode/bind",'wap');
+                }
+            }
+        }
+    }
+    private function goods($common_id)
+    {
+        $goods_id = commonid_helper::instance()->one_goods($common_id);
+        if($goods_id == false) return [];
+
+        $mod = Model('goods');
+        $goods = $mod->find($goods_id);
+
+        return $goods;
+    }
+
+    public function openOp()
+    {
+        $common_id = intval($_GET['common_id']);
+        $batch_code = $_GET['batch_code'];
+
+        if($common_id <= 0 || empty($batch_code)) {
+            $url = BASE_SITE_URL . "/mobile/index.php?act=fcode&op=index&common_id={$common_id}&batch_code={$batch_code}";
+            return self::outsuccess(['url' => $url]);
+        }
+
+        $oper = new fcode\operator($common_id,$batch_code,session_helper::mobile(),session_helper::session_id());
+        $fcode = $oper->grabed();
+
+        if($fcode == false)
+        {
+            $fcode = $oper->grab();
+            if($fcode == false) {
+                $url = BASE_SITE_URL . "/mobile/index.php?act=fcode&op=index&common_id={$common_id}&batch_code={$batch_code}&status=-1";
+                return self::outsuccess(['url' => $url]);
+            }
+        }
+
+        $url = BASE_SITE_URL . "/mobile/index.php?act=fcode&op=index&common_id={$common_id}&batch_code={$batch_code}";
+        return self::outsuccess(['url' => $url]);
+    }
+
+    public function bindOp()
+    {
+        $common_id = intval($_GET['common_id']);
+        $batch_code = $_GET['batch_code'];
+
+        if($common_id <= 0 || empty($batch_code)) {
+            return self::outerr(errcode::ErrParamter,"错误的参数");
+        }
+
+        $mobile = $_GET['mobile'];
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+
+        $oper = new fcode\operator($common_id,$batch_code,$mobile,session_helper::session_id());
+        $fcode = $oper->grabed();
+        if($fcode == false) {
+            return self::outerr(errcode::ErrParamter, "您没有该批次商品的F码.");
+        }
+
+        $fcoder = new fcode\mfcode($fcode);
+        if($fcoder->binded()) {
+            return self::outsuccess(null);
+        }
+
+        if(!isset($_GET['code']) || empty($_GET['code'])) {
+            return self::outerr(errcode::ErrParamter, "请输入验证码.");
+        }
+        $code = $_GET['code'];
+        $ret = sms_helper::check_code(sms_helper::getfcode,$code,$mobile);
+        if(is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+        else
+        {
+            login_helper::onBinded($mobile,session_helper::relay_id());
+            $oper->bind($fcode);
+            return self::outsuccess(null);
+        }
+    }
+}

+ 657 - 0
mapi/control/festval.php

@@ -0,0 +1,657 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: songlintao
+ * Date: 2017/9/25
+ * Time: 下午3:30
+ */
+defined( 'InShopNC' ) or exit( 'Access Invalid!' );
+
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/fcode/operator.php');
+require_once(BASE_ROOT_PATH . '/helper/room/util.php');
+
+use bonus\account;
+use user_session\storage;
+
+class festvalControl extends mobileControl
+{
+    const RELATIVE_UPLOAD = "/upfile";
+    const UPFILE_PATH = BASE_UPLOAD_PATH . self::RELATIVE_UPLOAD;
+    private $mod_activity_image;
+
+    public function __construct() {
+        parent::__construct();
+        $this->mod_activity_image = Model('activity_image');
+    }
+
+    private $qixiConfig = [
+//        0 => ["common_id"=>2778,"batch_code"=>"HSDX01","goods_name"=>"唇油"],//131
+
+//        0 => ["common_id"=> 1111,"batch_code"=>"QXHD01","goods_name"=>"卸妆水"],
+//        1 => ["common_id"=>3400,"batch_code"=>"HSDX01","goods_name"=>"唇油"],
+
+        0 => ["common_id"=>3725,"batch_code"=>"QXHD03","goods_name"=>"唇油"],//兰芝 水润绚彩染唇油
+        1 => ["common_id"=>4434,"batch_code"=>"QXHD01","goods_name"=>"卸妆水"],//美宝莲 净澈多效卸妆水
+        2 => ["common_id"=>4430,"batch_code"=>"QXHD04","goods_name"=>"喷雾"],// Fa清香亚麻喷雾
+        3 => ["common_id"=>4528,"batch_code"=>"QXHD02","goods_name"=>"香皂"],// 安宝笛 鸢尾花味香皂
+    ];
+
+    public function qixiOp()
+    {
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = BASE_SITE_URL . "/mobile/index.php?act=festval&op=qixi";
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        $begin = strtotime("2018-08-14");
+        $end   = strtotime("2018-08-18");
+
+        if($this->activity_validate($begin,$end)){
+            return self::outsuccess(null,'festival/TanabataFestival/index');
+        }else{
+            return self::outsuccess(null,'festival/end/index');
+        }
+    }
+
+    private $freeCollection = [
+//        "0" => ["common_id"=>819,'goods_id' => 1301, 'need_bonus' => 39.90], //89
+
+//        "0" => ["common_id"=>3445,'goods_id' => 6214, 'need_bonus' => 88.00],//153
+//        "1" => ["common_id"=>3446,'goods_id' => 6215, 'need_bonus' => 88],
+//        "2" => ["common_id"=>3447,'goods_id' => 6216, 'need_bonus' => 88.0],
+
+        "0" => ["common_id"=>4706,'goods_id' => 8310, 'need_bonus' => 600],
+        "1" => ["common_id"=>4707,'goods_id' => 8311, 'need_bonus' => 600],
+        "2" => ["common_id"=>4708,'goods_id' => 8312, 'need_bonus' => 600],
+    ];
+
+    public function freeCollectionOp()
+    {
+        return self::outsuccess(null,'festival/freeCollection/index');
+    }
+
+    public function ajax_freeCollectionOp()
+    {
+        $member = session_helper::memberid();
+        if($member <= 0){
+            return self::outerr(Errcode::ErrUnLogin,"用户未登录");
+        }
+
+        $mod_order    = Model('order_goods');
+
+        $list = [];
+        $items = $this->freeCollection;
+        foreach ($items as $k => $item)
+        {
+            $common_id  = $item['common_id'];
+            $goods_id   = $item['goods_id'];
+            $need_bonus = $item['need_bonus'];
+            $goods_storage = 0;
+
+            //判断查询商品 storeage  状态1  => 不可以点击
+            $helper = new goods_helper($this->price_calcer(),false);
+            $ret = $helper->get_spu($common_id,$goods_id,$err);
+            if($ret == false) {
+                $list[$k] = ["goods" => $goods_id ,"state" => 1 ,"need_bonus"=>$need_bonus,"storage"=>$goods_storage];//商品已下架或不存在 库存清空
+                continue;
+            }
+
+
+            //判断用户是否可以全额用红包购买(只要可以买一份就算) 状态2 / 状态3  => 都可以点击
+            $summary = $ret['summary'];
+            foreach ($summary as $val)
+            {
+                if($goods_id == $val['goods_id']){
+                    $goods_storage = $val['goods_storage'];
+                    if($goods_storage <= 0){
+                        $list[$k] = ["goods" => $goods_id ,"state" => 1 ,"need_bonus"=>$need_bonus,"storage"=>$goods_storage];//商品已下架或不存在 库存清空
+                        continue;
+                    }
+
+                    $gap = $val['discount_gap'];
+                    if(intval($gap * 100 + 0.5) == 0) {
+                        $list[$k] = ["goods" => $goods_id ,"state" => 2, "need_bonus"=>$need_bonus, "storage"=>$goods_storage];//可以点击 去商品详情
+                    } else {
+                        $list[$k] = ["goods" => $goods_id ,"state" => 3, "need_bonus"=>$need_bonus, "storage"=>$goods_storage];//邀请送红包
+                    }
+                }
+            }
+
+            //判断用户是否已经购买过该商品  状态4 => 不可以点击
+            $find = $mod_order->table('order_goods')->where(["goods_id"=>$goods_id, "buyer_id"=>$member])->find();
+            if(!empty($find)){
+                $list[$k] = ["goods" => $goods_id ,"state" => 4,"need_bonus"=>$need_bonus,"storage"=>$goods_storage];
+            }
+        }
+
+        $ret = [
+            "goods_list"   => $list
+        ];
+        return self::outsuccess($ret);
+        //下单处需要添加补丁:  控制每人每个商品 能且仅能购买一单 (每单不限数量)
+    }
+
+
+
+    private function activity_validate($begin,$end)
+    {
+        $now = time();
+        return ($now >= $begin && $now < $end);
+    }
+
+    public function getAwardOp()
+    {
+        $memberid = session_helper::memberid();
+        if($memberid<=0) {
+            return self::outerr(errcode::ErrUnLogin,"用户需要登陆");
+        };
+
+        $minfo = new member_info($memberid);
+        $moblie = $minfo->mobile();
+        $sid = session_helper::session_id();
+        $get = false;
+        $grabed = false;
+        $name = "";
+
+        $qixiConf = $this->qixiConfig;
+        foreach ($qixiConf as $key => $item)
+        {
+            $command_id = $item['common_id'];
+            $batch_code = $item['batch_code'];
+            $goods_name = $item['goods_name'];
+
+            $oper = new fcode\operator($command_id,$batch_code,$moblie,$sid);
+            $fcode = $oper->grabed();
+            if($fcode) {
+                $grabed = true;
+                $name = $goods_name;
+                $get    = true;
+                break;
+            }
+
+            $fcode = $oper->grab();
+            if($fcode)
+            {
+                $res = $oper->bind($fcode);
+                if($res){
+                    $name = $goods_name;
+                    $get = true;
+                    break;
+                }
+            }
+        }
+
+        if($get) {
+            return self::outsuccess(["grabed"=>$grabed,"goods_name"=>$name]);
+        } else {
+            return self::outerr(errcode::ErrGoodsOutofStock,"七夕活动的奖品已被抽完咯,关注熊猫不要错过下次哦");
+        }
+    }
+
+    public function indexOp()
+    {
+        $this->topup();
+        $url = BASE_SITE_URL . "/hfive/festval/index.html";
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+        }
+
+        return self::outsuccess(['direct_uri' => $url],"redirect");
+    }
+
+    private function from_base64($base_input, &$file_name)
+    {
+        if(empty($base_input)) {
+            return false;
+        }
+
+        $regx = '/^(data:\s*image\/(\w+);base64,)/';
+        if (preg_match($regx, $base_input, $result))
+        {
+            $file_type = $result[2];
+            $content = str_replace( $result[1], '', $base_input);
+            $file_name = md5($content) .'.'. $file_type;
+            return base64_decode($content);
+        } else {
+            return false;
+        }
+    }
+
+    function add_imageOp()
+    {
+        $image_content = $this->from_base64($_POST['image_data'],$file_name);
+        $act_id = intval($_POST['act_id']);
+
+        if ($image_content == false || $act_id <= 0) {
+            return self::outerr( errcode::ErrParamter, "参数错误", "festval/error" );
+        }
+        $file_path = self::UPFILE_PATH . "/{$file_name}";
+        if(file_put_contents($file_path,$image_content) == false) {
+            return self::outerr( errcode::ErrParamter, "保存文件失败", "festval/error" );
+        }
+
+        $datas = [];
+        {
+            if(session_helper::logined()) {
+                $datas['member_id'] = session_helper::memberid();
+            } else {
+                $datas['member_id'] = 0;
+            }
+
+            if(session_helper::unionid() != false) {
+                $datas['unionid'] = session_helper::unionid();
+            } else {
+                $datas['unionid'] = "";
+            }
+            $datas['act_id']     = $act_id;
+            $datas['image_path'] = self::RELATIVE_UPLOAD . "/" . $file_name;
+            $datas['add_time']   = time();
+            $datas['likes']      = 0;
+        }
+        $ret = $this->mod_activity_image->insert($datas);
+        if($ret > 0) {
+            return self::outsuccess(null);
+        } else {
+            return self::outerr( errcode::ErrParamter, "保存文件失败", "festval/error" );
+        }
+    }
+
+    function likeOp()
+    {
+        $act_id   = $_GET['act_id'];
+        $image_id = $_GET['image_id'];
+
+        if($act_id < 0 || $image_id < 0) {
+            return self::outerr(errcode::ErrParamter,"参数错误");
+        }
+
+        $supporter = new festval_support($act_id,$image_id);
+        if($supporter->supported()) {
+            $supporter->unsupport();
+            $supported = false;
+        } else {
+            $supporter->support();
+            $supported = true;
+        }
+
+        $ret = $this->mod_activity_image->likes($image_id,true);
+        return self::outsuccess(['supported' => $supported,'likes' => intval($ret['likes'])]);
+    }
+
+    function listOp()
+    {
+        $act_id = intval($_POST['act_id']);
+        if ($act_id <= 0) {
+            return self::outerr( errcode::ErrParamter, "参数错误", "festval/error" );
+        }
+        $items = $this->mod_activity_image->image_list(['act_id' => $act_id],'*',$this->page_size());
+        $pages = $this->mod_activity_image->gettotalpage();
+
+        $result = [];
+        foreach ($items as $item) {
+            $result[] = $this->format($item);
+        }
+        return self::outsuccess(['blocks' => $result,'mobile_page' => mobile_page($pages)]);
+    }
+
+    private function format($item)
+    {
+        $result = [];
+        $image_id = intval($item['image_id']);
+        $act_id   = intval($item['act_id']);
+
+        $result['image_id'] = $image_id;
+        $supporter = new festval_support($act_id,$image_id);
+        $result['supported'] = $supporter->supported();
+        $result['act_id'] = $item['act_id'];
+        $result['member_id'] = $item['member_id'];
+        $result['image'] = $this->img_url($item['image_path']);
+
+        $result['likes'] = intval($item['likes']);
+        $result['add_time'] = intval($item['add_time']);
+
+        return $result;
+    }
+
+    private function img_url($path)
+    {
+        if(util::ishttp($path)) {
+            $url = $path;
+        } else {
+            $url = UPLOAD_SITE_URL . $path;
+        }
+        return $url;
+    }
+    private function topup()
+    {
+        if(session_helper::logined()) {
+            $pred = new account($_SESSION['member_id'],true);
+            $pred->topup_bonus($_SESSION['member_mobile']);
+        }
+    }
+
+
+    //不需要登录 点击里面的按钮需要登录
+    public function double11_stepsOp()
+    {
+        $from = strtotime("2018-12-02");//2018-12-03
+        $to   = strtotime("2019-12-11");//2018-12-10
+        $userSteps = $this->userSteps_ranking($from,$to);
+        $mine_steps = $this->mine_steps_info($userSteps);
+
+        $user_first = $user_second = $user_third = $user_list = [];
+        $last_steps = 0;
+        for($i=1;$i<=20;$i++)
+        {
+            if($i == 1) {
+                $user_first  = isset($userSteps[$i-1]) ? $userSteps[$i-1] : $this->fake_user($i-1);
+                $last_steps = $user_first["steps"];
+            }elseif($i == 2) {
+                $user_second = isset($userSteps[$i-1]) ? $userSteps[$i-1] : $this->fake_user($i-1,$last_steps);
+                $last_steps = $user_second["steps"];
+            }elseif($i == 3) {
+                $user_third  = isset($userSteps[$i-1]) ? $userSteps[$i-1] : $this->fake_user($i-1,$last_steps);
+                $last_steps = $user_third["steps"];
+            }else{
+                $user_item = isset($userSteps[$i-1]) ? $userSteps[$i-1] : $this->fake_user($i-1,$last_steps);
+                $last_steps = $user_item["steps"];
+                $user_list[] =$user_item;
+            }
+        }
+
+        if(session_helper::isapp()) {
+            $url = schema_helper::openurl("我的捐步" ,BASE_SITE_URL."/mobile/index.php?act=member_talk&op=steps_detail");
+        } else {
+            $url = BASE_SITE_URL."/mobile/index.php?act=member_talk&op=steps_detail";
+        }
+
+        return self::outsuccess([
+            "mine_steps" =>$mine_steps,
+            "user_first" =>$user_first,
+            "user_second"=>$user_second,
+            "user_third" =>$user_third,
+            "user_steps" =>$user_list,
+            "steps_url"  =>$url
+        ],'festival/double11/steps');
+    }
+
+    public function new_yearOp()
+    {
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = BASE_SITE_URL . "/mobile/index.php?act=festval&op=new_year";
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+        return self::outsuccess(null,'festival/newYear/index');
+    }
+
+    public function ajax_new_yearOp()
+    {
+        $member_id = session_helper::memberid();
+        if($member_id <= 0) {
+            return self::outerr(errcode::ErrUnLogin,"请先登录");
+        }
+
+        $act_id    = 3;
+        $act_info = Model()->table('activity')->where(["activity_id" => $act_id])->find();
+        if(empty($act_info)) {
+            return self::outerr(errcode::ErrParamter,"活动未设置");
+        }
+
+        $cond = ["activity_id" => $act_id,"item_id" => $member_id];
+        $detail = Model()->table('activity_detail')->where($cond)->find();
+
+        $bestWish = empty($detail) ? 0 : intval($detail["store_name"]);
+        $member_info = new member_info($member_id);
+
+        return self::outsuccess(["nickname"=>$member_info->nickname(),"bestWish"=>$bestWish]);
+    }
+
+    public function bestWishOp()
+    {
+        $val = intval($_GET["bestWish"]);
+        if($val <= 0 || $val > 9) {
+            return self::outerr(errcode::ErrParamter,"错误的请求参数");
+        }
+
+        $member_id = session_helper::memberid();
+        if($member_id <= 0) {
+            return self::outerr(errcode::ErrUnLogin,"请先登录");
+        }
+
+        $model = Model();
+        $act_id = 3;
+        $cond = ["activity_id" => $act_id,"item_id" => $member_id];
+        $detail = $model->table('activity_detail')->where($cond)->find();
+        if(!empty($detail)) {
+            return self::outsuccess(["bestWish" => $val]);
+        } else {
+            $datas = $cond;
+            $datas["item_name"] = "2019元旦活动-锦鲤神签";
+            $datas["store_id"] = time();
+            $datas["store_name"] = $val;
+            $res = $model->table('activity_detail')->insert($datas);
+            if(!$res) return self::outerr(errcode::ErrDB,"网络错误");
+        }
+
+        return self::outsuccess(["bestWish" => $val]);
+    }
+
+    private function mine_steps_info($userSteps)
+    {
+        $member_id = session_helper::memberid();
+        $is_login  = false;
+
+        $steps = 0;
+        $rank  = 0;
+        $name  = "";
+        if($member_id > 0)
+        {
+            $is_login = true;
+
+            if(!empty($userSteps)) {
+                foreach ($userSteps as $k => $sort_item)
+                {
+                    if($member_id == $sort_item['userid']) {
+                        $rank  = $k + 1;
+                        $steps = $sort_item['steps'];
+                        $name  = $sort_item['nickname'];
+                    }
+                }
+
+                if($rank == 0) $rank = count($userSteps) + 3000;
+            } else {
+                if($rank == 0) $rank = 486;
+            }
+
+            if(empty($name)) {
+                $uinfo = new member_info($member_id);
+                $name =  $uinfo->nickname();
+            }
+        }
+
+        return ["is_login" => $is_login,"rank" => $rank ,"steps" => $steps ,"nickname"=> $name];
+    }
+
+
+    private function userSteps_ranking($from,$to)
+    {
+        $mod = Model('room');
+        $items = $mod->roomSteps(["date_stamp"=>[['gt',$from],['lt',$to]]],"*",false);
+
+        $uids = [];
+        foreach ($items as $item)
+        {
+            $uids[] = $item['member_id'];
+        }
+        $uids = array_unique($uids,SORT_NUMERIC);
+
+        if(!empty($uids)) {
+            $members = Model('member')->getMemberList(['member_id' => ['in',$uids]]);
+        } else {
+            $members = [];
+        }
+
+        $uid_infos = [];
+        foreach ($members as $member)
+        {
+            $uinfo = new member_info($member);
+            $user = $uinfo->member_id();
+            $nickname = empty($member_nick[$user]) ? $uinfo->nickname() : $member_nick[$user];
+            $item = ['avatar' => $uinfo->avatar(),'nickname' => $nickname,'userid' => $uinfo->member_id(),"steps"=> 0];
+            $uid_infos[$user] = $item;
+        }
+
+        if(!empty($uid_infos))
+        {
+            foreach ($items as $item)
+            {
+                $uid = $item['member_id'];
+                if(array_key_exists($uid,$uid_infos))
+                {
+                    $uid_infos[$uid]["steps"] =  $uid_infos[$uid]["steps"] + $item['steps'];
+                }
+            }
+
+            usort($uid_infos,['room\sorter','steps_desc']);
+        }
+
+        return $uid_infos;
+    }
+
+    private function fake_user($index,$last_steps=1000000)
+    {
+        $man = RESOURCE_SITE_URL . '/mobile/defimg/male.png';
+        $feman = RESOURCE_SITE_URL . '/mobile/defimg/female.png';
+
+        $arr = [
+            0 =>['avatar' => $feman,'nickname' => "暴躁的熊猫",'userid' => 0,"steps"=> 52121],
+            1 =>['avatar' => $feman,'nickname' => "Elaine",'userid' => 0,"steps"=> 46363],
+            2 =>['avatar' => $man,'nickname' => "辣椒葩葩",'userid' => 0,"steps"=> 33567],
+            3 =>['avatar' => $man,'nickname' => "我是静静",'userid' => 0,"steps"=> 24511],
+            4 =>['avatar' => $feman,'nickname' => "戈壁女侠",'userid' => 0,"steps"=> 17764],
+            5 =>['avatar' => $feman,'nickname' => "Amy_Sun",'userid' => 0,"steps"=> 12678],
+            6 =>['avatar' => $man,'nickname' => "会飞的胖纸",'userid' => 0,"steps"=> 9689],
+            7 =>['avatar' => $feman,'nickname' => "睡不着咕噜咕噜",'userid' => 0,"steps"=> 7791],
+            8 =>['avatar' => $feman,'nickname' => "楼下的喜欢我",'userid' => 0,"steps"=> 5566],
+            9 =>['avatar' => $feman,'nickname' => "小鱼干",'userid' => 0,"steps"=> 4758],
+            10 =>['avatar' => $feman,'nickname' => "JinKeLa",'userid' => 0,"steps"=> 3190],
+            11 =>['avatar' => $feman,'nickname' => "薛定谔的猫",'userid' => 0,"steps"=> 2478],
+            12 =>['avatar' => $feman,'nickname' => "bulingbuling",'userid' => 0,"steps"=> 1864],
+            13 =>['avatar' => $feman,'nickname' => "Hay",'userid' => 0,"steps"=> 1275],
+            14 =>['avatar' => $feman,'nickname' => "卡西莫拉",'userid' => 0,"steps"=> 941],
+            15 =>['avatar' => $feman,'nickname' => "吃可爱长大的",'userid' => 0,"steps"=> 666],
+            16 =>['avatar' => $feman,'nickname' => "教主夫人",'userid' => 0,"steps"=> 431],
+            17 =>['avatar' => $feman,'nickname' => "波波C",'userid' => 0,"steps"=> 259],
+            18 =>['avatar' => $feman,'nickname' => "老蔡",'userid' => 0,"steps"=> 86],
+            19 =>['avatar' => $feman,'nickname' => "阿哥吧打卤",'userid' => 0,"steps"=> 15],
+        ];
+
+        if($last_steps < $arr[$index]["steps"]) {
+            $arr[$index]["steps"] = intval($last_steps / 4 * 3)+1;
+        }
+        return $arr[$index];
+    }
+}
+
+class festval_support extends storage
+{
+    private $act_id;
+    private $image_id;
+
+    public function __construct($act_id, $image_id)
+    {
+        $this->act_id = intval($act_id);
+        $this->image_id = intval($image_id);
+        parent::__construct();
+    }
+
+    public function is_act() {
+        return ($this->act_id > 0 && $this->image_id <= 0);
+    }
+
+    public function limit_type()
+    {
+        return storage::NORMAL_SUPPORT;
+    }
+    public function storage_tag()
+    {
+        if($this->is_act()) {
+            return "festval_support";
+        } else {
+            return "festval_image_{$this->act_id}";
+        }
+    }
+    public function supported()
+    {
+        if($this->is_act()) {
+            return parent::base_supported($this->act_id);
+        } else {
+            return parent::base_supported($this->image_id);
+        }
+    }
+    public function support()
+    {
+        if($this->is_act())
+        {
+            $ret = parent::base_support($this->act_id);
+            if($ret) {
+                $this->add_act_likes();
+            }
+        }
+        else
+        {
+            $ret = parent::base_support($this->image_id);
+            if($ret) {
+                $this->add_image_likes();
+            }
+        }
+        return $ret;
+    }
+    public function unsupport()
+    {
+        if($this->is_act())
+        {
+            $ret = parent::base_unsupport($this->act_id);
+            if($ret) {
+                $this->sub_act_likes();
+            }
+        }
+        else
+        {
+            $ret = parent::base_unsupport($this->image_id);
+            if($ret) {
+                $this->sub_image_likes();
+            }
+        }
+        return $ret;
+    }
+
+    private function add_act_likes()
+    {
+
+    }
+    private function sub_act_likes()
+    {
+
+    }
+    private function add_image_likes()
+    {
+        $mod_image = Model('activity_image');
+        $mod_image->where(['image_id' => $this->image_id])->update([ 'likes' => ['exp', 'likes + 1'] ]);
+    }
+    private function sub_image_likes()
+    {
+        $mod_image = Model('activity_image');
+        $mod_image->where(['image_id' => $this->image_id])->update([ 'likes' => ['exp', 'likes - 1'] ]);
+    }
+}

+ 78 - 0
mapi/control/game.php

@@ -0,0 +1,78 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2016/10/28
+ * Time: 下午6:50
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/room/factory_client.php');
+require_once(BASE_ROOT_PATH . '/helper/room/proto_type.php');
+require_once(BASE_ROOT_PATH . '/helper/room/author.php');
+
+class gameControl extends mbMemberControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function shakeOp()
+    {
+        global $config;
+        $room_id = $config['special_rooms']['shake_bonus'];
+        $webaddr = $config['access_addr'];
+        $userid = session_helper::memberid();
+
+        $creator = self::shake_creator($room_id);
+        $ret = room\factory_client::instance()->invite($room_id,$creator,[$userid]);
+
+        $result = [];
+        if($ret != false) {
+            $result['addr'] = $webaddr;
+            $result['token'] = room\author::sign_web($room_id,$userid);
+            $result['room'] = intval($room_id);
+            $result['user'] = $userid;
+        }
+
+        return self::outsuccess($result,"game/shake_bonus");
+    }
+
+    public function test_shakeOp()
+    {
+        global $config;
+        $room_id = $config['special_rooms']['shake_bonus'];
+        $webaddr = $config['access_addr'];
+        $creator = self::shake_creator($room_id);
+        $ret = room\factory_client::instance()->invite($room_id,$creator,[session_helper::memberid()]);
+
+        Log::record("ret={$ret}",Log::DEBUG);
+        $result = [];
+        if($ret != false) {
+            $result['addr'] = $webaddr;
+            $result['token'] = room\author::sign_web($room_id,session_helper::memberid());
+            $result['room'] = intval($room_id);
+            $result['user'] = session_helper::memberid();
+        }
+
+        $_SESSION['client_type'] = "wap";
+        return self::outsuccess($result,"game/test_shake");
+    }
+
+    static private function shake_creator($room_id)
+    {
+        static $stCreator = 0;
+
+        if($stCreator == 0) {
+            $mod_room = Model('room');
+            $params = $mod_room->getRoom($room_id);
+            $rinfo = new room\room_info($params);
+            $stCreator = $rinfo->creator();
+        }
+
+        return $stCreator;
+    }
+}

+ 39 - 0
mapi/control/goods.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/3/18
+ * Time: 下午10:11
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class goodsControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function detailOp()
+    {
+        $commonid = 0;
+        $goods_id = intval($_GET['goods_id']);
+        if (empty($_GET['goods_id']) || $goods_id <= 0) {
+            if (!empty($_GET['goods_commonid'])) {
+                $commonid = intval($_GET['goods_commonid']);
+            }
+        } else {
+            $info = Model('goods')->getGoodsInfoByID($goods_id, 'goods_commonid');
+            $commonid = intval($info['goods_commonid']);
+        }
+
+        if ($commonid > 0) {
+            $items = Model()->table('goods_common')->field('goods_body')->where(array('goods_commonid' => $commonid))->select();
+            if (!empty($items) && count($items) > 0) {
+                Tpl::output('goods_body', $items[0]['goods_body']);
+            }
+        }
+        Tpl::showpage('goods_detail');
+    }
+}

+ 342 - 0
mapi/control/goods_common.php

@@ -0,0 +1,342 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/8/24
+ * Time: 下午10:49
+ */
+
+require_once (BASE_ROOT_PATH . "/helper/goods_helper.php");
+require_once (BASE_ROOT_PATH . "/helper/activity_helper.php");
+require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/fcode.php');
+
+class goods_commonControl extends mobileControl
+{
+    const pic_path = '/data/upload/shop/member';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $common_id = intval($_GET['goods_commonid']);
+        $goods_id  = intval($_GET['goods_id']);
+
+        if($common_id <= 0) {
+            $common_id = commonid_helper::instance()->common_id($goods_id);
+        }
+
+        if($goods_id > 0 && $common_id > 0)
+        {
+            if(!empty($_SESSION['member_id'])) {
+                Model('goods_browse')->addViewedGoods($goods_id,$_SESSION['member_id'],$_SESSION['store_id']);
+            }
+
+            $helper = new goods_helper($this->price_calcer(),false);
+            $ret = $helper->get_spu($common_id,$goods_id,$err);
+            if($ret == false) {
+                return self::outerr($err['code'],$err['msg']);
+            }
+            else
+            {
+                $mod_eva = Model('evaluate_goods');
+                $order = "geval_scores desc,geval_id desc";
+//                $condi = ['geval_scores'=>['gt',2]];
+                $items = $mod_eva->getGoodsCommonEvaluateList($common_id,1,$this->page_size(),$order,$condi);
+
+                if(empty($items)) {
+                    $ret['comment'] = null;
+                } else {
+                    $comments = $this->format_comment($items,3);
+                    $ret['comments'] = $comments;
+                    $ret['comment']  = $comments[0];//兼容旧版
+                }
+                return self::outsuccess($ret,"shop/goods_detail");
+            }
+        }
+        else {
+            return self::outerr(errcode::ErrParamter,"请输入正确的参数.");
+        }
+    }
+
+    //商品评论
+    private function format_image($member_id,$image)
+    {
+        if(empty($image)) return array();
+        $images = explode(',',$image);
+        if(empty($images)) {
+            return array();
+        }
+
+        $result = [];
+        foreach ($images as $img) {
+            $path = BASE_SITE_URL . self::pic_path . "/{$member_id}/" . $img;
+            $result[] = $path;
+        }
+
+        return $result;
+    }
+
+    private function format_comment($items,$cnt=0)
+    {
+        $comments = [];
+
+        $i = 0;
+        foreach ($items as $item)
+        {
+            $i++;
+            if($cnt>0 && $i >=$cnt) break;
+
+            //$val = [];
+            $val['geval_id'] = intval($item['geval_id']);
+            $val['common_id'] = intval($item['geval_commonid']);
+            $val['goods_id'] = intval($item['geval_goodsid']);
+            $val['goods_name'] = $item['geval_goodsname'];
+            $val['scores'] = intval($item['geval_scores']);
+            $val['anonymous'] = empty($item['geval_isanonymous']) ? 0 : 1;
+            $val['content'] = empty($item['geval_content']) ? "" : $item['geval_content'];
+            $val['addtime'] = intval($item['geval_addtime']);
+            $val['storeid'] = intval($item['geval_storeid']);
+            $val['goods_image'] = util::goods_thumb_image($item['geval_goodsimage'],$val['storeid']);
+            $val['storename'] = $item['geval_storename'];
+            $member_id = intval($item['geval_frommemberid']);
+            $val['explain'] = $item['geval_explain'];
+            $val['images'] = $this->format_image($member_id,$item['geval_image']);
+
+            $val['member_avatar'] = util::member_avatar($item['member_avatar']);
+            $val['goods_spec'] = util::goods_spec($item['goods_spec']);
+            $val['nickname'] = util::nickname($item['member_nickname'],$item['member_mobile'],$item['frommembername']);
+
+            $comments[] = $val;
+        }
+
+        return $comments;
+    }
+
+    public function detailOp()
+    {
+        $commonid = 0;
+        $goods_id = intval($_GET['goods_id']);
+        if (empty($_GET['goods_id']) || $goods_id <= 0) {
+            if (!empty($_GET['goods_commonid'])) {
+                $commonid = intval($_GET['goods_commonid']);
+            }
+        } else {
+            $info = Model('goods')->getGoodsInfoByID($goods_id, 'goods_commonid');
+            $commonid = intval($info['goods_commonid']);
+        }
+
+        if ($commonid > 0) {
+            $items = Model()->table('goods_common')->field('goods_body')->where(array('goods_commonid' => $commonid))->select();
+            if (!empty($items) && count($items) > 0) {
+                Tpl::output('goods_body', $items[0]['goods_body']);
+            }
+        }
+        Tpl::showpage('goods_detail');
+    }
+
+    public function detail_ajaxOp()
+    {
+        $commonid = 0;
+        $goods_id = intval($_GET['goods_id']);
+        if (empty($_GET['goods_id']) || $goods_id <= 0) {
+            if (!empty($_GET['goods_commonid'])) {
+                $commonid = intval($_GET['goods_commonid']);
+            }
+        } else {
+            $info = Model('goods')->getGoodsInfoByID($goods_id, 'goods_commonid');
+            $commonid = intval($info['goods_commonid']);
+        }
+
+        if ($commonid > 0) {
+            $items = Model()->table('goods_common')->field('goods_body')->where(array('goods_commonid' => $commonid))->select();
+            if (!empty($items) && count($items) > 0) {
+                return self::outsuccess(['body' => $items[0]['goods_body']]);
+            }
+        }
+
+        return self::outsuccess(null);
+    }
+
+    public function commentsOp()
+    {
+        $common_id = intval($_GET['goods_commonid']);
+        if($common_id <= 0) {
+            return self::outerr(errcode::ErrParamter,"参数信息错误");
+        }
+
+        $mod_eva = Model('evaluate_goods');
+        $order = "geval_scores desc,geval_id desc";
+        $condi = ['geval_scores'=>['gt',2]];
+        $items = $mod_eva->getGoodsCommonEvaluateList($common_id,0,$this->page_size(),$order,$condi);
+        $page_count = $mod_eva->gettotalpage();
+        $result = $this->format_comment($items);
+
+        return self::outsuccess(array('comments' => $result,'mobile_page' =>mobile_page($page_count)));
+    }
+}
+
+class tpl_detail
+{
+    private $out_put;
+    private $common_info;
+    private $summary;
+
+    public function __construct($out_put)
+    {
+        $this->out_put = $out_put;
+        $this->common_info = $this->out_put['common_info'];
+        $this->summary = $this->out_put['summary'];
+    }
+
+    public function ads_baner()
+    {
+        $images = $this->common_info['images'];
+
+        if(!is_array($images)) return;
+
+        foreach ($images as $val)
+        {
+            echo "<div class=\"swiper-slide\"><img src=\"{$val}\"></div>";
+        }
+    }
+    public function search_show_id() {
+        $show_goods = $this->common_info['show_goods'];
+        return $show_goods;
+    }
+    public function show_summary($goods_id)
+    {
+        $summ = $this->summary;
+        $arr['goods_id']=$goods_id;
+        $goods_key = 0;
+        foreach ($summ as $key => $su) {
+            if (array_intersect_key($su, $arr)) {
+                $goods_key = $key;
+            }
+        }
+        $goods_info = $summ[$goods_key];
+
+        echo "<div class=\"content-padded\">";
+        echo  "<div class=\"products_name\" id=\"products_name\">{$goods_info['goods_mobile_name']}</div>
+                <div class=\"action\">{$goods_info['goods_jingle']}</div>
+                <div class=\"price_stock\">
+                    <span class=\"this_price t\">¥{$goods_info['goods_price']}</span>
+                    <span class=\"old_price o\">{$goods_info['goods_market_price']}</span>
+                    <span class=\"stock\">库存{$goods_info['goods_storage']}件 / 已售{$goods_info['goods_salenum']}件</span>
+                </div>
+                <div class=\"item_size_box\">
+                    <div class=\"item_title\">选择{$this->common_info['spec_name']}</div>
+                    <div class=\"item-size\">";
+
+                    if ($goods_info['goods_storage'] > 0)
+                    {
+                        echo "<a href=\"javascript:void(0)\" class=\"active\" data-goods-id=\"$goods_id\">{$goods_info['goods_spec']}</a>";
+                    }
+                    unset($summ[$goods_key]);
+                    if(isset($summ) && is_array($summ))
+                    {
+                        foreach($summ as $su)
+                        {
+                            $goods_spec = $su['goods_spec'];
+                            $goods_id = $su['goods_id'];
+
+                            if ($su['goods_storage'] > 0) {
+                                echo "<a href=\"javascript:void(0)\"  data-goods-id=\"$goods_id\">{$goods_spec}</a>";
+                            } else {
+                                echo "<a href=\"javascript:void(0)\" class=\"null\" data-goods-id=\"$goods_id\">{$goods_spec}</a>";
+                            }
+                        }
+                    }
+
+
+        echo        "</div>
+                    <span class=\"icon icon-right pull-right\"></span>
+                </div>
+            </div>";
+    }
+
+    public function show_pop($goods_id)
+    {
+        $summ = $this->summary;
+        $arr['goods_id']=$goods_id;
+        $goods_key = 0;
+        foreach ($summ as $key => $su) {
+            if (array_intersect_key($su, $arr)) {
+                $goods_key = $key;
+            }
+        }
+        $goods_info = $summ[$goods_key];
+        echo " <ul>
+                <li class=\"item-content products_content\">
+                    <div class=\"item-inner row\">
+                        <div class=\"col-33\"></div>
+                        <div class=\"col-60\">
+                            <div>
+                                <span class=\"this_price t\">¥{$goods_info['goods_price']}</span>
+                            </div>
+                            <div>
+                                <span class=\"stock\">库存{$goods_info['goods_storage']}件 / 已售{$goods_info['goods_salenum']}件</span>
+                            </div>
+                        </div>
+                    </div>
+                </li>
+                <li class=\"item-content\">
+                    <div class=\"item-title\">{$this->common_info['spec_name']}</div>
+                </li>
+                <li class=\"color_check_box specs\">
+                    <div class=\"specs_box\">";
+
+                if ($goods_info['goods_storage'] > 0)
+                {
+                    echo "<a href=\"javascript:void(0)\" class=\"active\" data-goods-id=\"{$goods_id}\">{$goods_info['goods_spec']}</a>";
+                }
+                unset($summ[$goods_key]);
+                if(isset($summ) && is_array($summ))
+                {
+                    foreach($summ as $su) {
+                        $goods_spec = $su['goods_spec'];
+                        $goods_id = $su['goods_id'];
+                        if ($su['goods_storage'] > 0) {
+                            echo "<a href=\"javascript:void(0)\"  data-goods-id=\"$goods_id\">{$goods_spec}</a>";
+                        } else {
+                            echo "<a href=\"javascript:void(0)\" class=\"null\" data-goods-id=\"$goods_id\">{$goods_spec}</a>";
+                        }
+                    }
+                }
+        echo"            </div>
+                </li>
+                <li class=\"item-content number\">
+                    <div class=\"item-inner\">
+                        <div class=\"item-title\">数量</div>
+                        <div class=\"item-after choose_box\"><span class=\"icon_number\" id=\"minus\">-</span><span
+                                id=\"goods_storage\">1</span><span class=\"icon_number\" id=\"add\">+</span></div>
+                    </div>
+                </li>
+            </ul>";
+    }
+    public function show_attrs()
+    {
+        $attrs = $this->common_info['attrs'];
+        if(isset($attrs) && is_array($attrs))
+        {
+            foreach ($attrs as $val)
+            {
+                $name = $val['name'];
+                $value = $val['value'];
+
+                echo "<li class=\"item-content\">
+                        <div class=\"item-inner\">
+                            <div class=\"item-title\">{$name}</div>
+                            <div class=\"item-after\">{$value}</div>
+                        </div>
+                    </li>";
+
+            }
+        }
+    }
+}

+ 27 - 0
mapi/control/home.php

@@ -0,0 +1,27 @@
+<?php
+/**
+ * cms首页
+ *
+ *
+ *
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once (BASE_ROOT_PATH . '/helper/util_helper.php');
+
+class homeControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function memnoOp()
+    {
+        $mem_no = util::mem_no();
+        return self::outsuccess(array('mem_no' => $mem_no));
+    }
+}

+ 297 - 0
mapi/control/index.php

@@ -0,0 +1,297 @@
+<?php
+/**
+ * cms首页
+ *
+ *
+ *
+ */
+
+
+use bonus\activity_bonus;
+use mcard\user_mcards;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/mobile/control/special.php');
+
+require_once(BASE_HELPER_PATH . '/goods_helper.php');
+require_once(BASE_HELPER_PATH . '/special_helper.php');
+require_once(BASE_HELPER_PATH . '/index_tab.php');
+require_once(BASE_HELPER_PATH . '/util_helper.php');
+require_once(BASE_HELPER_PATH . '/third_author/wxauthor.php');
+require_once(BASE_HELPER_PATH . '/third_author/wxauthor.php');
+require_once(BASE_HELPER_PATH . '/session_helper.php');
+require_once(BASE_HELPER_PATH . '/url_helper.php');
+require_once(BASE_HELPER_PATH . '/room/tpl_group_home.php');
+require_once(BASE_HELPER_PATH . '/room/tpl_chatwo_home.php');
+require_once(BASE_HELPER_PATH . '/mcard/mcard.php');
+require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
+
+
+class indexControl extends specialControl
+{
+    const HomeSpecialID = 0;
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function mini_indexOp()
+    {
+        global $config;
+        $setting = $config['client_setting'];
+        if(empty($setting)) {
+            $_GET['special_id'] = 0;
+        }
+        else
+        {
+            $version = session_helper::version_code();
+            $running = $setting['running'];
+            $spid = $setting['home'];
+
+            if($version > $running) {
+                $_GET['special_id'] = $spid;
+            }
+            else {
+                $_GET['special_id'] = 0;
+            }
+        }
+
+        return parent::indexOp();
+    }
+
+    public function wap_indexOp()
+    {
+        global $config;
+        $setting = $config['client_setting'];
+        if(empty($setting)) {
+            $spid = 0;
+        }
+        else
+        {
+            $version = session_helper::version_code();
+            $running = $setting['running'];
+            $spid = $setting['home'];
+
+            if($version <= $running) {
+                $spid = 0;
+            }
+        }
+
+        return self::outsuccess(['special_id' => $spid]);
+    }
+
+    public function tabsOp()
+    {
+        $client_tpe = session_helper::client_type();
+        if($client_tpe == session_helper::device_mini || $client_tpe == session_helper::device_wap) {
+            $tabs = [];
+//            $tabs[] = ['special_id' => 1039,'name' => '推荐'];
+//            $tabs[] = ['special_id' => 1122,'name' => '品牌'];
+//            $tabs[] = ['special_id' => 1025,'name' => '护肤'];
+//            $tabs[] = ['special_id' => 1035,'name' => '彩妆'];
+//            $tabs[] = ['special_id' => 1036,'name' => '洗护'];
+//            $tabs[] = ['special_id' => 886,'name' => '男士'];
+        }
+        else {
+            $tabs = index_tab::instance()->tabs();
+        }
+
+        $daliy_bonus = activity_bonus::daliy_bonus_url();
+        return self::outsuccess(['tabs' => $tabs,'daliy_bonus' =>$daliy_bonus]);
+    }
+
+    public function splashOp()
+    {
+        $sig = $_GET['sig'];
+        $ret = $this->pub_special($this->splash_id());
+        if(empty($ret['special_list'])) {
+            return self::outsuccess(null);
+        }
+        $block = $ret['special_list'][0];
+        if(empty($block) || empty($block['items'])) {
+            return self::outsuccess(null);
+        }
+
+        $image = $block['items'][0]['image'];
+        if(empty($sig) || $sig != md5($image)) {
+            return self::outsuccess(['sig' => md5($image),'url' => $image]);
+        } else {
+            return self::outsuccess(null);
+        }
+    }
+
+    private function splash_id()
+    {
+        global $config;
+        $special_id = $config['splash_page']['special_id'];
+        return $special_id;
+    }
+
+    public function inoherbOp()
+    {
+        return self::outsuccess(['direct_uri' => BASE_SITE_URL . '/hfive/inoherb/index.html?2'],"redirect");
+    }
+
+    /**
+     * 会话详情页 talk_type:room/chatwo   talk_id:room_id/user
+     * 回话详情@ app打开
+     * 群详情@ 微信扫码进入
+     */
+    public function room_indexOp()
+    {
+        $talk_type = trim($_GET['talk_type']);
+        $talk_id = intval($_GET['talk_id']);
+        $relay_id = intval($_GET['relay_id']);
+        $open_talk = intval($_GET['open_talk']);
+
+        if($talk_id <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        //微信内打开使用授权判断
+        if(session_helper::need_wechat_author()) {
+            $author = new thrid_author\wxauthor();
+            $url = url_helper::room_detail_url($talk_type,$talk_id,$relay_id);
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        $is_app = intval(session_helper::isapp());
+        $user = session_helper::memberid();
+        $param = ["talk_type" => $talk_type, "talk_id" => $talk_id , "member_id" => $user,"room_name" => "","room_avatar" => "","relay_id" => $relay_id,
+            "is_app" => $is_app,
+            "open_talk" => $open_talk];
+
+        if(!session_helper::logined())
+        {
+            if($talk_type == "room") {
+                return self::outsuccess(['tpl' => null,"param" => $param],'talk/homepage_room');
+            } elseif($talk_type == 'chatwo') {
+                return self::outsuccess(['tpl' => null,"param" => $param],'talk/homepage_chatwo');
+            } else {
+                return self::outerr(errcode::ErrParamter);
+            }
+        }
+
+        if($talk_type == "room")
+        {
+            try {
+                $room_id = $talk_id;
+                $tpl = new room\tpl_group_home($user,$talk_id,$relay_id);
+                $param["room_name"] = $tpl->get_room_info()->name();
+                $param["room_avatar"] = $tpl->get_room_info()->avatar();
+                return self::outsuccess(['tpl' => $tpl,"param" => $param],'talk/homepage_room');
+            } catch (Exception $ex) {
+                Log::record("member_talk.room_detail error: room_id={$room_id} user={$user}",Log::ERR);
+                return self::outerr(errcode::ErrParamter);
+            }
+        }
+        elseif($talk_type == 'chatwo')
+        {
+            try {
+                $other = $talk_id;
+                $tpl = new room\tpl_chatwo_home($user,$other);
+                return self::outsuccess(['tpl' => $tpl,"param"=>$param],'talk/homepage_chatwo');
+            } catch (Exception $ex) {
+                Log::record("member_talk.room_detail error: other={$other} user={$user}",Log::ERR);
+                return self::outerr(errcode::ErrParamter);
+            }
+        }
+        else
+        {
+            return self::outerr(errcode::ErrParamter);
+        }
+    }
+
+    ///获取充值卡的数据接口.
+    public function card_goodsOp()
+    {
+        $page_type = $_GET['page_type']; //oil or phone page.
+        if(empty($page_type)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $calctor = new CalcPrice(session_helper::memberid());
+        $goods = $this->card_goods($page_type,$calctor);
+        $ret = [];
+
+        if(session_helper::memberid() > 0)
+        {
+            $card_list =  mtopcard\priority_cards(session_helper::memberid(),$page_type);
+            $ret['cards'] = mtopcard\topcard_format($card_list);
+        }
+        else {
+            $ret['cards'] = [];
+        }
+
+        $ret['tips'] = $calctor->calc_tips();
+        foreach ($goods as $item)
+        {
+            [$tip,$show_invite] = $calctor->inviter_tips($item['goods_id']);
+
+            $ret['goods_inviter_tips'][] = [
+                'goods_id' => $item['goods_id'],
+                'tip' => $tip,
+                'show_invite' => $show_invite];
+        }
+        $ret['inviter_tips'] = empty($ret['goods_inviter_tips']) ? '' : $ret['goods_inviter_tips'][0]['tip'];
+        $ret['goods'] = $goods;
+        $ret['member_mobile'] = session_helper::mobile();
+        $ret['special_id'] = $this->paysuccess_special();
+
+        return self::outsuccess($ret);
+    }
+
+    private function paysuccess_special()
+    {
+        global $config;
+        return $config['special_pay_success'];
+    }
+
+    private function card_goods($card_type,$calctor)
+    {
+        global $config;
+        $card_commids = $config['card_commonid'];
+        if(empty($card_commids)) {
+            return [];
+        }
+
+        $commonid = intval($card_commids[$card_type]);
+        Log::record("card_type = {$card_type} commonid={$commonid}",Log::DEBUG);
+
+        if($commonid > 0)
+        {
+            $mod_goods = Model('goods');
+            $goods_list = $mod_goods->getGoodsOnlineList(['goods_commonid' => $commonid]);
+            $helper = new goods_helper(new bonus\normal_calc());
+            $goods_list = $helper->summary($goods_list, $related_goods,[$calctor,'calc_vgoods_price']);
+
+            $summarys = &$goods_list['summary'];
+            usort($summarys,[__CLASS__,'comp_goods']);
+
+            return $summarys;
+        }
+        else {
+            return [];
+        }
+    }
+    public static function comp_goods($left,$right)
+    {
+        $t_l = intval($left['goods_spec']);
+        $t_r = intval($right['goods_spec']);
+
+        if($t_l > $t_r) {
+            return 1;
+        }
+        elseif($t_l == $t_r)
+        {
+            return 0;
+        }
+        else {
+            return -1;
+        }
+    }
+}

+ 306 - 0
mapi/control/inoherb.php

@@ -0,0 +1,306 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/6/9
+ * Time: 上午11:57
+ */
+
+require_once (BASE_ROOT_PATH . '/helper/algorithm.php');
+require_once (BASE_ROOT_PATH . '/helper/login_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/sms_helper.php');
+
+class inoherbControl extends mobileControl
+{
+    private $mModInoherb;
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->mModInoherb = Model('inoherb');
+    }
+
+    public function indexOp()
+    {
+        $inoherb_id = intval($_GET['inoherb_id']);
+        if($inoherb_id > 0) {
+            $url = BASE_SITE_URL . "/hfive/inoherb/index.html?#/share?inoherb_id={$inoherb_id}";
+        }
+        else {
+            $url = BASE_SITE_URL . "/hfive/inoherb/index.html?2";
+        }
+        return self::outsuccess(['direct_uri' => $url],"redirect");
+    }
+
+    public function listOp()
+    {
+        $items = $this->items($this->page_size(),false);
+        $count = $this->mModInoherb->gettotalpage();
+        if(empty($items)) {
+            return self::outsuccess(['articles' => null,
+                'mobile_page' => mobile_page(0)]);
+        } else {
+            $articles = $this->format($items);
+            return self::outsuccess(['articles' => $articles,
+                'mobile_page' => mobile_page($count)]);
+        }
+    }
+    public function addOp()
+    {
+        $content = $_GET['content'];
+        if(empty($content)) {
+            return self::outerr(errcode::ErrParamter,"填写的内容不能为空.");
+        }
+        $flower_type = intval($_GET['flower_type']);
+
+        $url = BASE_SITE_URL . "/mobile/index.php?act=inoherb&op=add&content={$content}&flower_type={$flower_type}";
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        $content = urldecode($content);
+        $trans = new trans_wapper($this->mModInoherb,__METHOD__);
+        try
+        {
+            if(!$this->exists())
+            {
+                $flower_type = intval($_GET['flower_type']);
+                $data['content'] = $content;
+                $data['flower_type'] = $flower_type;
+                $data['unionid'] = session_helper::unionid();
+                $data['content'] = $content;
+                $data['likes'] = 0;
+                $data['avatar'] = session_helper::avatar();
+                $data['nickname'] = session_helper::nickname();
+
+                if(session_helper::logined()) {
+                    $data['member_id'] = session_helper::memberid();
+                    $data['mobile'] = session_helper::mobile();
+                } else {
+                    $data['member_id'] = 0;
+                }
+                $this->mModInoherb->insert($data);
+            }
+            else
+            {
+                $data['content'] = $content;
+                $this->mModInoherb->where(['unionid' => session_helper::unionid()])->update($data);
+            }
+
+            $trans->commit();
+        } catch (Exception $ex) {
+            $trans->rollback();
+        }
+
+        return self::outsuccess(null);
+    }
+
+    public function supportOp()
+    {
+        $inoherb_id = intval($_GET['inoherb_id']);
+        if($inoherb_id < 0) {
+            return self::outerr(errcode::ErrParamter,'错误的文章序列号.');
+        }
+
+        if($this->supported($inoherb_id)) {
+            $supported = false;
+            $supports = $this->unsupport($inoherb_id);
+        } else {
+            $supported = true;
+            $supports = $this->support($inoherb_id);
+        }
+
+        return self::outsuccess(['likes' => $supports,'supported' => $supported,'inoherb_id' => $inoherb_id]);
+    }
+
+    private function supported($inoherb_id)
+    {
+        $time = strtotime(date('Y-m-d',time()));
+        if(!isset($_SESSION['inoherb'])) {
+            $_SESSION['inoherb'] = [];
+        }
+        if(!isset($_SESSION['inoherb'][$time])) {
+            $_SESSION['inoherb'][$time] = [];
+        }
+
+        $inoherb = &$_SESSION['inoherb'][$time];
+        if(algorithm::binary_search($inoherb,$inoherb_id)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private function support($inoherb_id)
+    {
+        $time = strtotime(date('Y-m-d',time()));
+        if(!isset($_SESSION['inoherb'])) {
+            $_SESSION['inoherb'] = [];
+        }
+        if(!isset($_SESSION['inoherb'][$time])) {
+            $_SESSION['inoherb'][$time] = [];
+        }
+
+        $inoherb = &$_SESSION['inoherb'][$time];
+        if(algorithm::binary_search($inoherb,$inoherb_id) == false) {
+            $pos = algorithm::lower_bonud($inoherb,$inoherb_id);
+            algorithm::array_insert($inoherb,$pos,$inoherb_id);
+            $ret = $this->mModInoherb->where(['inoherb_id' => $inoherb_id])->update(['likes' => ['exp', 'likes + 1']]);
+        }
+        return $this->likes($inoherb_id);
+    }
+
+    private function unsupport($inoherb_id)
+    {
+        $time = strtotime(date('Y-m-d',time()));
+        if(!isset($_SESSION['inoherb'])) {
+            $_SESSION['inoherb'] = [];
+        }
+        if(!isset($_SESSION['inoherb'][$time])) {
+            $_SESSION['inoherb'][$time] = [];
+        }
+
+        $inoherb = &$_SESSION['inoherb'][$time];
+        if(algorithm::binary_search($inoherb,$inoherb_id) == true) {
+            $pos = algorithm::lower_bonud($inoherb,$inoherb_id);
+            algorithm::array_erase($inoherb,$pos);
+            $ret = $this->mModInoherb->where(['inoherb_id' => $inoherb_id])->update(['likes' => ['exp', 'likes - 1']]);
+        }
+
+        return $this->likes($inoherb_id);
+    }
+
+    public function mineOp()
+    {
+        $inoherb_id = intval($_GET['inoherb_id']);
+        if($inoherb_id < 0) {
+            return self::outerr(errcode::ErrParamter,'错误的文章序列号.');
+        }
+        if(empty(session_helper::unionid()))
+        {
+            return self::outsuccess(['articles' => null,
+                'mobile_page' => mobile_page(0)]);
+        }
+
+        $item = $this->item(['unionid' => session_helper::unionid()],true);
+        if(empty($item)) {
+            return self::outsuccess(['articles' => null,
+                'mobile_page' => mobile_page(0)]);
+        }
+        else
+        {
+            $articles = $this->format($item);
+            return self::outsuccess(['articles' => $articles,
+                'mobile_page' => mobile_page(1)]);
+        }
+    }
+
+    public function infoOp()
+    {
+        $inoherb_id = intval($_GET['inoherb_id']);
+        if($inoherb_id < 0) {
+            return self::outerr(errcode::ErrParamter,'错误的文章序列号.');
+        }
+        $item = $this->item(['inoherb_id' => $inoherb_id]);
+
+        if(empty($item)) {
+            return self::outsuccess(['articles' => null, 'mobile_page' => mobile_page(0)]);
+        } else {
+            $articles = $this->format($item);
+            return self::outsuccess(['articles' => $articles, 'mobile_page' => mobile_page(1)]);
+        }
+    }
+
+    public function loginedOp()
+    {
+        $logined = session_helper::logined();
+        return self::outsuccess(['logined' => $logined]);
+    }
+
+    public function bindOp()
+    {
+        $mobile = $_GET['mobile'];
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+
+        if(!isset($_GET['code']) || empty($_GET['code'])) {
+            return self::outerr(errcode::ErrParamter, "请输入验证码.");
+        }
+        $code = $_GET['code'];
+        $ret = sms_helper::check_code(sms_helper::getbonus,$code,$mobile);
+
+        if(is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        } else {
+            login_helper::onBinded($mobile,session_helper::relay_id());
+            $member_id = session_helper::memberid();
+            $nickname = session_helper::nickname();
+
+            $this->mModInoherb->where(['unionid' => session_helper::unionid()])->update(['mobile' => $mobile,'member_id' => $member_id,'nickname' => $nickname]);
+            return self::outsuccess(null);
+        }
+    }
+
+    private function exists()
+    {
+        $unionid = session_helper::unionid();
+        if(empty($unionid)) return true;
+
+        $items = $this->mModInoherb->field('*')->where(['unionid' => $unionid])->select();
+        if(empty($items)) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private function likes($inoherb_id)
+    {
+        $items = $this->mModInoherb->field('likes')->where(['inoherb_id' => $inoherb_id])->lock(true)->select();
+        if(empty($items)) {
+            return 0;
+        } else {
+            return intval($items[0]['likes']);
+        }
+    }
+
+    private function item($condition,$lock = false)
+    {
+        return $this->mModInoherb->field('*')->where($condition)->lock($lock)->select();
+    }
+
+    private function items($page = 0,$lock = false)
+    {
+        return $this->mModInoherb->field('*')->order('likes desc,inoherb_id desc')->page($page)->lock($lock)->select();
+    }
+
+    private function format($items)
+    {
+        $result = [];
+        foreach ($items as $item)
+        {
+            $val = [];
+            $val['inoherb_id'] = intval($item['inoherb_id']);
+            $val['avatar'] = $item['avatar'];
+            $val['flower_type'] = intval($item['flower_type']);
+            $val['content'] = $item['content'];
+            $val['likes'] = $item['likes'];
+            $val['supported'] = $this->supported($val['inoherb_id']);
+            $val['nickname'] = $item['nickname'];
+
+
+            $result[] = $val;
+        }
+
+        return $result;
+    }
+}

+ 348 - 0
mapi/control/invite_friend.php

@@ -0,0 +1,348 @@
+<?php
+
+require_once(BASE_HELPER_PATH . '/algorithm.php');
+require_once(BASE_HELPER_PATH . '/login_helper.php');
+require_once(BASE_HELPER_PATH . '/session_helper.php');
+require_once(BASE_HELPER_PATH . '/sms_helper.php');
+require_once(BASE_HELPER_PATH . '/url_helper.php');
+require_once(BASE_HELPER_PATH . '/model_helper.php');
+require_once(BASE_HELPER_PATH . '/invite_helper.php');
+require_once(BASE_HELPER_PATH . '/third_author/wxauthor.php');
+require_once(BASE_HELPER_PATH . '/user_session/storage.php');
+
+class invite_friendControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $user = intval($_GET['curuser']);
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = author_url::inviter_url($user);
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        if($user <= 0)
+        {
+            if(session_helper::logined()) {
+                $user = session_helper::memberid();
+            }
+        }
+
+        $type_sn = account_helper::invite_bonus(session_helper::share_id());
+        if($user > 0) {
+            return self::outsuccess(['tpl' => new tpl_invite_friend($user,$type_sn)],"invite_friend/invite",'wap');
+        }
+        else {
+            return self::outerr(errcode::ErrParamter);
+        }
+    }
+
+    public function call_userOp()
+    {
+        if(!session_helper::logined()) {
+            return self::outerr(errcode::ErrUnLogin,"召唤操作有可能会骚扰用户,只有在登录时才可以操作");
+        }
+        $user = intval($_GET['user']);
+        if($user > 0)
+        {
+            $mod_member = Model('member');
+            $minfo = $mod_member->getMemberInfo(['inviter_id' => session_helper::memberid(),'member_id' => $user]);
+            if(!empty($minfo)) {
+                $caller = new user_session\friend_caller();
+                $caller->call($user);
+                push_helper::call_friends(session_helper::memberid(),$user);
+                return self::outsuccess(null);
+            }
+
+        }
+        return self::outerr(errcode::ErrParamter);
+    }
+}
+
+class friend_caller extends user_session\storage
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+    public function limit_type()
+    {
+        return user_session\storage::DAILY_SUPPORT;;
+    }
+    public function storage_tag()
+    {
+        return 'friend_caller';
+    }
+    public function called($user) {
+        return $this->base_supported($user);
+    }
+    public function call($user) {
+        parent::base_support($user);
+    }
+}
+
+class tpl_invite_friend
+{
+    private $mUser;
+    private $mRewardedInvites;
+    private $mRewardingInvites;
+
+    private $mUserInfo;
+    private $mShareInfo;
+    private $mTypesn;
+    private $mMineInfo;
+    private $mRank;
+    private $mMine;
+    private $mCaller;
+
+    public function __construct($user,$type_sn)
+    {
+        $this->mUser = $user;
+        $this->mRewardedInvites = [];
+        $this->mRewardingInvites = [];
+
+        $this->init($user);
+        $this->mShareInfo = invite_helper::share_info(session_helper::share_id());
+        $this->mTypesn = $type_sn;
+        $this->mMine = (session_helper::memberid() == $user);
+        $this->mCaller = new user_session\friend_caller();
+    }
+
+    private function init($user)
+    {
+        if($user <= 0) return false;
+        $mod_member = Model('member');
+        $items = $mod_member->getMemberList(['member_id|inviter_id' => ['_multi' => true,$user,$user]],'*', 0, 'reward_amount desc');
+
+        $cur_user = session_helper::memberid();
+
+        $index = 0;
+        foreach ($items as $item)
+        {
+            $user_info = new member_info($item);
+            $uid = $user_info->member_id();
+            if($uid == $user) {
+                $this->mUserInfo = $user_info;
+            }
+            elseif ($uid == $cur_user) {
+                $this->mMineInfo = $user_info;
+                $this->mRank = $index + 1;
+            }
+            elseif($user_info->rewared_inviter()) {
+                $this->mRewardedInvites[] = $user_info;
+            }
+            else {
+                $this->mRewardingInvites[] = $user_info;
+            }
+            $index++;
+        }
+    }
+
+    public function show()
+    {
+
+//        if(!empty($this->mTypesn)) {
+//            $this->show_bonus();
+//        }
+        $rewared = $this->show_rewared();
+        $rewarding = $this->show_rewarding();
+
+        $relay = $this->show_relay();
+//        if($rewared == false && $rewarding == false) {
+//            $this->show_noinvitee();
+//        }
+        $prompt = $this->show_prompt();
+
+        echo $relay.$rewared.$rewarding.$prompt;
+    }
+
+    private function show_noinvitee()
+    {
+        echo "<div class=\"bonus_list\">";
+        echo "<span class=\"invite_null\">TA尚未邀请好友</span>";
+        echo "</div>";
+    }
+
+    private function show_relay()
+    {
+        $minfo = $this->mUserInfo;
+
+        $total_cnt = $this->reward_member_cnt + $this->rewarding_member_cnt;
+        if($total_cnt > 0) {
+            $str = "<div class=\"text_center mt14\">
+                    <p class=\"l_ht42 f30 col333\">已邀请 <span class=\"colDD4545\">{$total_cnt}</span> 名好友,共获得 <span class=\"colDD4545\">{$minfo->reward_amount()}</span> 元红包</p>
+                </div>";
+        }else{
+            $str = "<div class=\"text_center mt14\">
+                    <p class=\"l_ht42 f30 col333\">您尚未邀请好友</p>
+                </div>";
+        }
+        return $str;
+    }
+
+//    private function show_bonus()
+//    {
+//        echo "<div class=\"open_bonus_link\">
+//                    <div class=\"bonus\">
+//                        <div class=\"bonus_top\"></div>
+//                        <div class=\"bonus_center\"></div>
+//                        <div class=\"bonus_bg\">
+//                            <span id=\"coin\" class=\"open_bonus_btn gold_coin\"></span>
+//                        </div>
+//                    </div>
+//              </div>";
+//    }
+
+    private $reward_member_cnt = 0;
+    private function show_rewared()
+    {
+        $html = "";
+        if(empty($this->mMineInfo) && empty($this->mRewardedInvites)) {
+            return $html;
+        }
+
+        if(!empty($this->mMineInfo) && $this->mMineInfo->rewared_inviter()) {
+            $count = count($this->mRewardedInvites) + 1;
+        } else {
+            $count = count($this->mRewardedInvites);
+        }
+
+        $this->reward_member_cnt = $count;
+
+        $html .= "<div class=\"bonus_list\">";
+
+        if(!empty($this->mMineInfo) && $this->mMineInfo->rewared_inviter()) {
+            $html .= $this->show_invitee($this->mMineInfo);
+        }
+        foreach ($this->mRewardedInvites as $minfo) {
+            $html .= $this->show_invitee($minfo);
+        }
+        $html .= "</div>";
+
+        return $html;
+    }
+
+    private $rewarding_member_cnt = 0;
+    private function show_rewarding()
+    {
+        $html = "";
+        if(empty($this->mMineInfo) && empty($this->mRewardingInvites)) {
+            return $html;
+        }
+
+        if(!empty($this->mMineInfo) && $this->mMineInfo->rewared_inviter() == false) {
+            $count = count($this->mRewardingInvites) + 1;
+        } else {
+            $count = count($this->mRewardingInvites);
+        }
+
+        $this->rewarding_member_cnt = $count;
+
+        $html .= "<div class=\"bonus_list\">";
+
+        if(!empty($this->mMineInfo) && $this->mMineInfo->rewared_inviter() == false) {
+            $html .= $this->show_invitee($this->mMineInfo);
+        }
+        foreach ($this->mRewardingInvites as $minfo) {
+            $html .= $this->show_invitee($minfo);
+        }
+        $html .= "</div>";
+
+        return $html;
+    }
+
+    private function show_prompt()
+    {
+        $str = "<div class=\"prompt\">
+                    <div class=\"prompt_label\">
+                        <span class=\"title\">活动规则</span>
+                    </div>
+                    <div class=\"gifts_tips_list\">
+                        <div class=\"gifts_tips_item\"><span class=\"tips_count\">1</span>当您分享红包给新人好友,领取成功后双方均可获得相应奖励(30元个人红包)。</div>
+                        <div class=\"gifts_tips_item mt4\"><span class=\"tips_count\">2</span>成功领取:通过您发出的红包链接,新人好友通过页面注册下载APP、微信授权/登录账号后,即为成功领取。</div>
+                        <div class=\"gifts_tips_item mt4\"><span class=\"tips_count\">3</span>通过不正当手段(包括但不限于侵犯第三人合法权益,作弊,扰乱系统,实施网络工具,批量注册,用机器注册账户,用机器模拟客户端)获得奖励,熊猫美妆有权撤销奖励以及相关订单。</div>
+                    </div>
+                </div>
+                <div class=\"briefing_address\"></div>";
+        return $str;
+    }
+
+    private function show_invitee($minfo)
+    {
+        if(empty($minfo)) return "";
+        $user = $minfo->member_id();
+        $called = $this->mCaller->called($user);
+
+        $str = "<div class=\"item\">
+                            <div class=\"user_img\">
+                            <img src=\"{$minfo->avatar()}\">
+                            </div>
+                            <div class=\"user_name text-overflow\">
+                              <p class=\"text-overflow\"> {$minfo->nickname()}</p>
+                              <p class=\"invite_msg\">邀请{$minfo->invitees()}人,收益<span class=\"price\">{$minfo->reward_amount()}</span>元</p>
+                            </div>";
+        if($this->mMine == false)
+        {
+            $str        .= "<div class=\"look_btn\">
+                               <span class=\"arrow\"></span>
+                            </div>";
+        }
+
+        if($this->mMine)
+        {
+            if($called) {
+                $str .=     "<span class=\"call_btn called\" data-user=\"{$user}\">召唤TA</span>";
+            } else {
+                $str .=     "<span class=\"call_btn\" data-user=\"{$user}\">召唤TA</span>";
+            }
+        }
+        $str .= "</div>";
+        return $str;
+    }
+
+    public function show_open()
+    {
+        if(!session_helper::isapp())
+        {
+            echo "<div class=\"fixed_bottom\">
+                        <span class=\"logo\"></span>
+                        <div class=\"label\">
+                            <p>熊猫美妆</p>
+                            <p>下载APP即可得更多奖励</p>
+                        </div>
+                        <a href=\"#\"  class=\"download_app_btn\" id=\"download_app\">打开APP</a>
+                  </div>";
+        }
+    }
+
+    public function bonus_url() {
+        return url_helper::bonus_open_url($this->mTypesn);
+    }
+    public function share_url()
+    {
+        return url_helper::bonus_open_url($this->mTypesn);
+    }
+    public function share_path()
+    {
+        return url_helper::bonus_open_path($this->mTypesn);
+    }
+    public function share_title()
+    {
+        return $this->mShareInfo['title'];
+    }
+    public function share_image()
+    {
+        return $this->mShareInfo['img'];;
+    }
+    public function share_subtitle()
+    {
+        return $this->mShareInfo['sub_title'];;
+    }
+}

+ 124 - 0
mapi/control/log.php

@@ -0,0 +1,124 @@
+<?php
+//以下为日志
+
+interface ILogHandler
+{
+	public function write($msg);
+}
+
+class CLogFileHandler implements ILogHandler
+{
+	private $handle = null;
+	
+	public function __construct($file = '')
+	{
+		$this->handle = fopen($file,'a');
+	}
+	
+	public function write($msg)
+	{
+		fwrite($this->handle, $msg, 4096);
+	}
+	
+	public function __destruct()
+	{
+		fclose($this->handle);
+	}
+}
+
+class wxLog
+{
+	private $handler = null;
+	private $level = 15;
+
+	private static $instance = null;
+
+	private function __construct(){}
+
+	private function __clone(){}
+
+	public static function Init($handler = null,$level = 15)
+	{
+		if(!self::$instance instanceof self)
+		{
+			self::$instance = new self();
+			self::$instance->__setHandle($handler);
+			self::$instance->__setLevel($level);
+		}
+		return self::$instance;
+	}
+
+
+	private function __setHandle($handler){
+		$this->handler = $handler;
+	}
+
+	private function __setLevel($level)
+	{
+		$this->level = $level;
+	}
+
+	public static function DEBUG($msg)
+	{
+		self::$instance->write(1, $msg);
+	}
+
+	public static function WARN($msg)
+	{
+		self::$instance->write(4, $msg);
+	}
+
+	public static function ERROR($msg)
+	{
+		$debugInfo = debug_backtrace();
+		$stack = "[";
+		foreach($debugInfo as $key => $val){
+			if(array_key_exists("file", $val)){
+				$stack .= ",file:" . $val["file"];
+			}
+			if(array_key_exists("line", $val)){
+				$stack .= ",line:" . $val["line"];
+			}
+			if(array_key_exists("function", $val)){
+				$stack .= ",function:" . $val["function"];
+			}
+		}
+		$stack .= "]";
+		self::$instance->write(8, $stack . $msg);
+	}
+
+	public static function INFO($msg)
+	{
+		self::$instance->write(2, $msg);
+	}
+
+	private function getLevelStr($level)
+	{
+		switch ($level)
+		{
+		case 1:
+			return 'debug';
+		break;
+		case 2:
+			return 'info';
+		break;
+		case 4:
+			return 'warn';
+		break;
+		case 8:
+			return 'error';
+		break;
+		default:
+
+		}
+	}
+
+	protected function write($level,$msg)
+	{
+		if(($level & $this->level) == $level )
+		{
+			$msg = '['.date('Y-m-d H:i:s').']['.$this->getLevelStr($level).'] '.$msg."\n";
+			$this->handler->write($msg);
+		}
+	}
+}

+ 858 - 0
mapi/control/login.php

@@ -0,0 +1,858 @@
+<?php
+/**
+ * 用户身份认证相关操作
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_DATA_PATH . '/model/member.model.php');
+require_once(BASE_CORE_PATH . '/framework/libraries/sms.php');
+require_once(BASE_CORE_PATH . '/framework/function/core.php');
+
+require_once(BASE_HELPER_PATH . '/sms_helper.php');
+require_once(BASE_HELPER_PATH . '/field_helper.php');
+require_once(BASE_HELPER_PATH . '/session_helper.php');
+require_once(BASE_HELPER_PATH . '/relation_helper.php');
+require_once(BASE_HELPER_PATH . '/account_helper.php');
+require_once(BASE_HELPER_PATH . '/session.php');
+require_once(BASE_HELPER_PATH . '/login_helper.php');
+
+//登录,获取验证码,注册
+class loginControl extends mobileHomeControl
+{
+    const mobile_login = 1;
+    const wxopen_login = 2;
+    const wxunion_login = 3;
+
+    //客户登录身份类型
+    protected $client_login_type_array = [0, 1, 2];
+    private static $fields = 'member_id,member_mobile,member_wxunionid,member_wxopenid,member_name,member_truename,member_signname,' .
+    'member_nickname,member_avatar,member_sex,member_birthday,member_passwd,member_paypwd,member_email,member_mobile_bind,member_state';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function statusOp()
+    {
+        if (session_helper::logined()) {
+            session::instance()->set_cookie(session_helper::session_id());
+            account_helper::onStatus(session_helper::memberid());
+            return self::outsuccess($this->ret_value());
+        } else {
+            $fcode = new user_session\fcode();
+            $fcode->onStatus();
+            return self::outsuccess($this->ret_value());
+        }
+    }
+
+    private function ret_value()
+    {
+        $has_mobile = empty($_SESSION['member_mobile']) ? false : true;
+        if (!$has_mobile) {
+            $has_mobile = session_helper::has_regmobile();
+        }
+
+        $has_author = empty($_SESSION['member_wxunionid']) ? false : true;
+        if (!$has_author) {
+            $has_author = wechat_helper::has_userinfo();
+        }
+
+        $ret = ['ismember' => $has_mobile, 'isauthor' => $has_author, //for前向兼容
+                'hasmobile' => $has_mobile, 'hasauthor' => $has_author,
+                'member_id' => session_helper::memberid(),
+                'userinfo' => $this->userinfo()];
+        return $ret;
+    }
+
+    private function userinfo()
+    {
+        $result = [];
+        $result['member_avatar'] = session_helper::avatar();
+        $result['member_mobile'] = session_helper::mobile();
+        $result['member_nickname'] = session_helper::nickname();
+        $result['member_sex'] = session_helper::sex();
+        $result['qrcode'] = session_helper::qrcode();
+
+        return $result;
+    }
+
+    public function wxauthorOp()
+    {
+        if (session_helper::logined()) {
+            return self::outsuccess($this->ret_value());
+        }
+
+        $user_info = $_GET['user_info'];
+        if (empty($user_info)) {
+            return self::outerr(errcode::ErrParamter, "上传的用户信息为空.");
+        }
+
+        $user_info = json_decode($user_info, true);
+        if (empty($user_info)) {
+            return self::outerr(errcode::ErrParamter, "上传的用户信息为空.");
+        }
+
+        //cur-> wx
+        $unionid_loginner = new login\open_userinfo_log($user_info);
+        if ($unionid_loginner->ismember())
+        {
+            if ($unionid_loginner->binded_mobile())
+            {
+                //pre-> mobile
+                if (session_helper::has_regmobile()) {
+                    $mobile = session_helper::get_regmobile();
+
+                    $mobile_loginner = new login\mobile_log($mobile);
+                    if ($mobile_loginner->ismember()) {
+                        $mobile_loginner->bind($user_info, $mobile);
+                        $mobile_loginner->login();
+                    } else {
+                        $unionid_loginner->bind($user_info, $mobile); //前向兼容很久前用openid登录情况。
+                        $unionid_loginner->login();
+                    }
+                } else {
+                    $unionid_loginner->bind($user_info);
+                    $unionid_loginner->login();
+                }
+                account_helper::onLogin(session_helper::memberid());
+            }
+            elseif (session_helper::has_regmobile())
+            {   //pre-> mobile
+                $mobile = session_helper::get_regmobile();
+
+                $mobile_loginner = new login\mobile_log($mobile);
+                if ($mobile_loginner->ismember()) {
+                    $mobile_loginner->bind($user_info, $mobile);
+                    $mobile_loginner->login();
+                } else {
+                    $unionid_loginner->bind($user_info, $mobile); //前向兼容很久前用openid登录情况。
+                    $unionid_loginner->login();
+                }
+
+                account_helper::onLogin(session_helper::memberid());
+                session_helper::clear_regmobile();
+                wechat_helper::clear_userinfo();
+            }
+            else {
+                wechat_helper::set_userinfo($user_info);
+            }
+        }
+        elseif (session_helper::has_regmobile())
+        {
+            $mobile = session_helper::get_regmobile();
+            $mobile_loginner = new login\mobile_log($mobile);
+
+            if ($mobile_loginner->ismember()) {
+                $mobile_loginner->bind($user_info);
+                $mobile_loginner->login();
+            } else {
+                $unionid_loginner->register($user_info, session_helper::relay_id(), $mobile);
+                $unionid_loginner->login();
+                account_helper::onRegister(session_helper::memberid(), session_helper::relay_id());
+                session_helper::clear_regmobile();
+                wechat_helper::clear_userinfo();
+            }
+            account_helper::onLogin(session_helper::memberid());
+        }
+        else {
+            wechat_helper::set_userinfo($user_info);
+        }
+
+        return self::outsuccess($this->ret_value());
+    }
+
+    public function skipOp()
+    {
+        if (session_helper::has_regmobile()) {
+            $mobile = session_helper::get_regmobile();
+            session_helper::clear_regmobile();
+        }
+        if (wechat_helper::has_userinfo()) {
+            $user_info = wechat_helper::get_userinfo();
+            wechat_helper::clear_userinfo();
+        }
+
+        if (!empty($mobile)) {
+            $loginner = new login\mobile_log($mobile);
+            if ($loginner->ismember()) {
+                $loginner->login();
+            } else {
+                $loginner->register([], session_helper::relay_id(), $mobile);
+                $loginner->login();
+                account_helper::onRegister(session_helper::memberid(), session_helper::relay_id());
+            }
+        }
+
+        if (!empty($user_info)) {
+            $loginner = new login\open_userinfo_log($user_info);
+            if ($loginner->ismember()) {
+                $loginner->login();
+            } else {
+                $loginner->register($user_info, session_helper::relay_id(), '');
+                $loginner->login();
+                account_helper::onRegister(session_helper::memberid(), session_helper::relay_id());
+            }
+        }
+
+        return self::outsuccess($this->ret_value());
+    }
+
+    private function decrypt($sesskey, $input, $iv)
+    {
+        $aesKey = base64_decode($sesskey);
+        $aesIV = base64_decode($iv);
+        $aesCipher = base64_decode($input);
+        $decrypt = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
+        $data = json_decode($decrypt, true);
+
+        $appid = MiniPay\WxPayConfig::APPID;
+        if (empty($data) || $data['watermark']['appid'] != $appid) {
+            return false;
+        } else {
+            return $data;
+        }
+    }
+
+    private function decrypt_userinfo($sesskey, $input, $iv)
+    {
+        $data = $this->decrypt($sesskey, $input, $iv);
+        if ($data !== false) {
+            $result = [];
+            $result['nickname'] = $data['nickName'];
+            $result['unionid'] = $data['unionId'];
+            $result['openid'] = $data['openId'];
+            $result['headimgurl'] = $data['avatarUrl'];
+            $result['sex'] = $data['gender'];
+            return $result;
+        } else {
+            return false;
+        }
+    }
+
+    private function cast_userinfo($input)
+    {
+        if (!empty($input)) {
+            $result = [];
+            $result['nickname'] = $input['nickname'];
+            $result['unionid'] = $input['unionid'];
+            $result['openid'] = $input['openid'];
+            $result['headimgurl'] = $input['avatarUrl'];
+            $result['sex'] = $input['gender'];
+            return $result;
+        } else {
+            return false;
+        }
+    }
+
+    private function decrypt_phone($sesskey, $input, $iv)
+    {
+        $data = $this->decrypt($sesskey, $input, $iv);
+        if ($data !== false) {
+            return [$data['countryCode'], $data['purePhoneNumber']];
+        } else {
+            return ['', ''];
+        }
+    }
+
+    //给迷你小程序使用add
+    public function wxauthenOp()
+    {
+        if(session_helper::client_type() == session_helper::device_mini && session_helper::version_code() > 168) {
+            $user_info = $_GET['user_info'];
+            $user_info  = urldecode(base64_decode($user_info));
+            Log::record("{$user_info}",Log::DEBUG);
+            $phone_info = '';
+        }
+        else {
+            $user_info  = $_GET['user_info'];
+            $phone_info = $_GET['phone_info'];
+        }
+
+        $channel = intval($_GET['channel']);
+        if (empty($user_info)) {
+            return self::outerr(errcode::ErrParamter, "上传的用户信息为空.");
+        }
+
+        Log::record("userinfo={$user_info}", Log::DEBUG);
+        $user_info = json_decode($user_info, true);
+        if (empty($user_info)) {
+            $err = json_last_error_msg();
+            Log::record("{$err}",Log::ERR);
+            return self::outerr(errcode::ErrParamter, "上传的用户信息为空.");
+        }
+
+        if (!array_key_exists('unionid', $user_info)) {
+            $sesskey = wechat_helper::mini_sesskey();
+            Log::record("sesskey={$sesskey}", Log::DEBUG);
+            $user_info = $this->decrypt_userinfo($sesskey, $user_info['encryptedData'], $user_info['iv']);
+            if ($user_info == false) {
+                return self::outerr(errcode::ErrParamter, "上传的用户信息为空.");
+            }
+        }
+        else {
+            $user_info = $this->cast_userinfo($user_info);
+        }
+
+        $phone = '';
+        if (!empty($phone_info)) {
+            $phone_info = json_decode($phone_info, true);
+            $sesskey = wechat_helper::mini_sesskey();
+            [$country_code, $phone] = $this->decrypt_phone($sesskey, $phone_info['encryptedData'], $phone_info['iv']);
+        }
+
+        $uid_login = new login\open_userinfo_log($user_info);
+        if (session_helper::logined()) {
+            $mid_login = new login\memberid_log(session_helper::memberid());
+            $mid_login->bind($user_info, $phone);
+            $mid_login->login();
+            account_helper::onLogin(session_helper::memberid());
+        }
+        elseif ($uid_login->ismember()) {
+            $uid_login->bind($user_info,$phone);
+            $uid_login->login();
+            account_helper::onLogin(session_helper::memberid());
+        }
+        else {
+            $uid_login->register($user_info, session_helper::relay_id(), session_helper::mobile(),$channel);
+            $uid_login->login();
+            account_helper::onRegister(session_helper::memberid(), session_helper::relay_id(),$channel);
+            session_helper::clear_regmobile();
+            wechat_helper::clear_userinfo();
+        }
+
+        return self::outsuccess($this->ret_value());
+    }
+
+    public function wxbind_phoneOp()
+    {
+        $phone_info = $_GET['phone_info'];
+        if(session_helper::client_type() == session_helper::device_mini && session_helper::version_code() > 168) {
+            $phone_info = urldecode(base64_decode($phone_info));
+        }
+        Log::record("phone_info:{$phone_info}",Log::DEBUG);
+
+        if(session_helper::logined())
+        {
+            if (!empty($phone_info)) {
+                $phone_info = json_decode($phone_info, true);
+                $sesskey = wechat_helper::mini_sesskey();
+                [$country_code, $phone] = $this->decrypt_phone($sesskey, $phone_info['encryptedData'], $phone_info['iv']);
+                Log::record("{$country_code}:{$phone}",Log::DEBUG);
+
+                $mid_login = new login\memberid_log(session_helper::memberid());
+                $mid_login->bind('', $phone);
+                $mid_login->login();
+                account_helper::onLogin(session_helper::memberid());
+                return self::outsuccess($this->ret_value());
+            }
+        }
+        else {
+            session::instance()->destroy();
+            return self::outsuccess(NULL);
+        }
+    }
+
+    public function ministartOp()
+    {
+        $code = $_GET['code'];
+        if (empty($code)) return self::outerr(errcode::ErrParamter);
+
+        $appid = MiniPay\WxPayConfig::APPID;
+        $app_secret = MiniPay\WxPayConfig::APPSECRET;
+
+        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$app_secret}&js_code={$code}&grant_type=authorization_code";
+        $resp = http_request($url);
+
+        if ($resp == false) {
+            return self::outerr(errcode::ErrLogin);
+        }
+        else
+        {
+            $body = json_decode($resp, true);
+            Log::record("{$resp}", Log::DEBUG);
+            if (isset($body['errcode'])) {
+                return self::outerr(errcode::ErrApptype, "获取appid失败");
+            }
+            else
+            {
+                if (array_key_exists('session_key', $body)) {
+                    wechat_helper::setmini_sesskey($body['session_key']);
+                    Log::record("session_key = {$body['session_key']}");
+                }
+                $share = $this->mini_share();
+                $body['share_title'] = $share['share_title'];
+                $body['share_image'] = $share['share_image'];
+
+                session::instance()->set_cookie($_SESSION['MPHPSESSID']);
+                $body['HPHPSESSID'] = $_SESSION['MPHPSESSID'];
+                return self::outsuccess($body);
+            }
+        }
+    }
+
+    private function mini_share()
+    {
+        $title = '我刚在这里充值了,平台直接优惠了40元,很不错,你也试试.';
+        $image = RESOURCE_SITE_URL . "/mobile/xyz/xyzshare.png";
+
+        return ['share_title' => $title, 'share_image' => $image];
+    }
+
+    private function is_special($mobile, $code)
+    {
+        if ($mobile == '13700000000' && $code == '1111') {
+            return true;
+        } elseif ($mobile == '13800000000' && $code == '1111') {
+            return true;
+        } elseif ($mobile == '13900000000' && $code == '1111') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public function login_codeOp()
+    {
+
+    }
+
+    public function bind_mobilexOp()
+    {
+        if (session_helper::logined()) {
+            return self::outsuccess($this->ret_value());
+        }
+
+        $mobile = trim($_GET['mobile']);
+        $code   = trim($_GET['code']);
+
+        //一些平台测试账户,特殊处理
+        if ($this->is_special($mobile, $code)) {
+            if (login_helper::onBinded($mobile, 0)) {
+                return self::outsuccess($this->ret_value());
+            }
+        }
+
+        // 输入内容判断
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $validator->setValidate(Validator::verify_smscode($code));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrInputParam, $err);
+        }
+        // 校验验证码
+        $ret = sms_helper::check_code(sms_helper::register, $code, $mobile);
+        if (is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        //绑定逻辑,以微信Unionid优先级为高。
+        //cur-> mobile
+        $mobile_loginner = new login\mobile_log($mobile);
+        if ($mobile_loginner->ismember())
+        {
+            if ($mobile_loginner->binded_wechat())
+            {
+                //pre->wx
+                if (wechat_helper::has_userinfo())
+                {
+                    $user_info = wechat_helper::get_userinfo();
+
+                    $union_logginer = new login\open_userinfo_log($user_info);
+                    if ($union_logginer->ismember()) {
+                        $union_logginer->bind([], $mobile);
+                        $union_logginer->login();
+                    } else {
+                        $mobile_loginner->bind(wechat_helper::get_userinfo());
+                        $mobile_loginner->login();
+                    }
+                    session_helper::clear_regmobile();
+                    wechat_helper::clear_userinfo();
+                } else {
+                    $mobile_loginner->login();
+                }
+                account_helper::onLogin(session_helper::memberid());
+            }
+            elseif (wechat_helper::has_userinfo())
+            {
+                $user_info = wechat_helper::get_userinfo();
+                $union_logginer = new login\open_userinfo_log($user_info);
+                if ($union_logginer->ismember()) {
+                    $union_logginer->bind([], $mobile);
+                    $union_logginer->login();
+                } else {
+                    $mobile_loginner->bind(wechat_helper::get_userinfo());
+                    $mobile_loginner->login();
+                }
+
+                account_helper::onLogin(session_helper::memberid());
+                session_helper::clear_regmobile();
+                wechat_helper::clear_userinfo();
+            }
+            else {
+                session_helper::set_regmobile($mobile);
+            }
+        }
+        elseif (wechat_helper::has_userinfo()) //pre->wx
+        {
+            $user_info = wechat_helper::get_userinfo();
+
+            $union_logginer = new login\open_userinfo_log($user_info);
+            if ($union_logginer->ismember()) {
+                $union_logginer->bind([], $mobile);
+                $union_logginer->login();
+            } else {
+                $mobile_loginner->register($user_info, session_helper::relay_id(), $mobile);
+                $mobile_loginner->login();
+                account_helper::onRegister($mobile_loginner->memberid(), session_helper::relay_id());
+            }
+
+            account_helper::onLogin(session_helper::memberid());
+            session_helper::clear_regmobile();
+            wechat_helper::clear_userinfo();
+        }
+        else {
+            session_helper::set_regmobile($mobile);
+        }
+
+        return self::outsuccess($this->ret_value());
+    }
+
+    public function bind_mobileOp()
+    {
+        $mobile = trim($_GET['mobile']);
+        $code = trim($_GET['code']);
+
+        if ($this->is_special($mobile, $code)) {
+            if (login_helper::onBinded($mobile, 0)) {
+                return self::outsuccess($this->ret_value());
+            }
+        }
+
+        // 输入内容判断
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $validator->setValidate(Validator::verify_smscode($code));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrInputParam, $err);
+        }
+
+        // 校验验证码
+        $ret = sms_helper::check_code(sms_helper::register, $code, $mobile);
+        if (is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        if (login_helper::onBinded($mobile, session_helper::relay_id())) {
+            return self::outsuccess($this->ret_value());
+        } else {
+            return self::outerr(errcode::ErrDB, "对不起,系统出现错误:(");
+        }
+    }
+
+    public function getcodexOp()
+    {
+        if (empty(session_helper::session_id())) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        if (session_helper::isapp() == false && util::from_wechat() == false) {
+            if ($_POST['escape'] !== 'code') {
+                return self::outerr(errcode::ErrParamter);
+            }
+        }
+
+        $mobile = trim($_POST['mobile']);
+        $type = trim($_POST['type']);
+
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+
+        $sms = new sms_helper();
+        $ret = $sms->send($mobile, $type);
+
+        if ($ret['code'] == 200) {
+            $items = Model('member')->getBindedMemberByMobile($mobile);
+            if (empty($items)) {
+                $isMember = false;
+            } else {
+                $isMember = true;
+            }
+            return self::outsuccess(['is_member' => $isMember]);
+        } else {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function loginOp()
+    {
+        if ($_SESSION['is_login'] == '1') { //检查是否已经登录
+            return self::outsuccess(['member_id' => $_SESSION['member_id'], 'HPHPSESSID' => $_SESSION['MPHPSESSID']]);
+        }
+
+        $type = intval(trim($_POST['type']));
+        if (!isset($type) || !in_array($type, $this->client_login_type_array)) {
+            return self::outerr(errcode::ErrParamter, 'type error.');
+        } else {
+            $_SESSION['login_type'] = $type;
+        }
+
+        $validate = new Validator();
+        if ($type == self::mobile_login) {
+            $openid = trim($_POST['mobile']);
+            $password = trim($_POST['passwd']);
+            $validate->setValidate(Validator::verify_mobile($openid));
+            $validate->setValidate(Validator::verify_password($password));
+        } else {
+            $openid = trim($_POST['openid']);
+            $validate->setValidate(Validator::verify_openid($openid));
+        }
+
+        $error = $validate->validate();
+        if ($error != '') {
+            return self::outerr(errcode::ErrParamter, $error);
+        }
+
+        $model_member = Model('member');
+        $member_info = $this->getMemberInfoEx($model_member, $openid, $type, $password);
+
+        if (is_array($member_info) and !empty($member_info))
+        {
+            if (!$member_info['member_state']) {
+                return self::outerr(errcode::ErrAccountStop);
+            }
+        }
+        elseif ($type == self::wxopen_login) { //如果是开放平台帐号,此处先需要注册
+            return self::outerr(errcode::ErrWxNotExist);
+        } else {
+            return self::outerr(errcode::ErrUserOrPass, "该手机号码未注册或者密码错误");
+        }
+
+        $model_member->createSession($member_info);
+        Model('cart')->mergecart($member_info, $_SESSION['store_id']);
+        Model('goods_browse')->mergebrowse($_SESSION['member_id'], $_SESSION['store_id']);
+
+        account_helper::onLogin($_SESSION['member_id']);
+        session::instance()->set_cookie($_SESSION['MPHPSESSID']);
+        return self::outsuccess(['member_id' => $_SESSION['member_id'], 'HPHPSESSID' => $_SESSION['MPHPSESSID']]);
+    }
+
+    private function getMemberInfoEx($model_member, $openid, $type, $passwd = '')
+    {
+        $conditions = [];
+        if ($type == self::mobile_login) {
+            $conditions['member_mobile'] = $openid;
+            $conditions['member_passwd'] = md5($passwd);
+        } elseif ($type == self::wxopen_login) {
+            $conditions['member_wxopenid'] = $openid;
+        } else {
+            return NULL;
+        }
+
+        $ret = $model_member->getMemberInfo($conditions, self::$fields);
+        $member_info = session_helper::filter_member_info($ret, $openid);
+
+        return $member_info;
+    }
+
+    public function getcodeOp()
+    {
+        if (empty(session_helper::session_id())) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $mobile = trim($_POST['mobile']);
+        $type = trim($_POST['type']);
+
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+
+        $sms = new sms_helper();
+        $ret = $sms->send_code($mobile, $type);
+
+        if ($ret['code'] == 200) {
+            return self::outsuccess(NULL);
+        } else {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function registerOp()
+    {
+        if ($_SESSION['is_login'] == 1) {
+            return self::outerr(errcode::ErrHasLogined, '登录后,不能注册新用户.');
+        }
+
+        $mobile = trim($_POST['mobile']);
+        $password = trim($_POST['passwd']);
+        $code = trim($_POST['code']);
+
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $validator->setValidate(Validator::verify_password($password));
+        $validator->setValidate(Validator::verify_smscode($code));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+        $ret = sms_helper::check_code(sms_helper::register, $code, $mobile);
+        if (is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        $model = Model('member');
+        $ret = $model->getBindedMemberByMobile($mobile);
+        if (!empty($ret)) {
+            return self::outerr(errcode::ErrUserExisted, "用户已经存在.");
+        } else {
+            $member_info = ['member_mobile' => $mobile,
+                'member_type' => self::mobile_login,
+                'member_passwd' => $password,
+                'member_sex' => 0,
+                'member_name' => $mobile,
+                'member_nickname' => substr_replace($mobile, '****', 3, 4),
+                'member_mobile_bind' => 1];
+
+            $insert_id = $model->addMember($member_info);
+            if ($insert_id == false) {
+                return self::outerr(errcode::ErrRegister);
+            } else {
+                $member_info = $model->getMemberInfoByID($insert_id);
+
+                $model->createSession($member_info);
+                Model('cart')->mergecart($member_info, $_SESSION['store_id']);
+                Model('goods_browse')->mergebrowse($_SESSION['member_id'], $_SESSION['store_id']);
+                account_helper::onRegister($_SESSION['member_id'], session_helper::relay_id());
+                session::instance()->set_cookie($_SESSION['MPHPSESSID']);
+                return self::outsuccess(['member_id' => $_SESSION['member_id'], 'HPHPSESSID' => $_SESSION['MPHPSESSID']]);
+            }
+        }
+    }
+
+    public function resetpassOp()
+    {
+        $mobile = trim($_POST['mobile']);
+        $password = trim($_POST['passwd']);
+        $code = trim($_POST['code']);
+
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $validator->setValidate(Validator::verify_password($password));
+        $validator->setValidate(Validator::verify_smscode($code));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrParamter, $err);
+        }
+
+        $ret = sms_helper::check_code(sms_helper::resetpass, $code, $mobile);
+        if (is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        $model = Model('member');
+        $ret = $model->editMember(['member_mobile' => $mobile], ['member_passwd' => md5($password)]);
+        if ($ret == false || $model->affected_rows() <= 0) {
+            $ret = $model->getBindedMemberByMobile($mobile);
+            if (empty($ret)) {
+                return self::outerr(errcode::ErrMemberNotExist, "该手机号未注册");
+            }
+        }
+
+        return self::outsuccess(NULL);
+    }
+
+    /**
+     * 微信注册登录
+     * wx_openid 微信id
+     * user_info: 用户信息
+     * mobile: 手机号
+     * code: 验证码
+     */
+    public function bindOp()
+    {
+        $wx_openid = trim($_GET['wx_openid']);
+        $mobile = trim($_GET['mobile']);
+        $code = trim($_GET['code']);
+
+        // 输入内容判断
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($mobile));
+        $validator->setValidate(Validator::verify_openid($wx_openid));
+        $validator->setValidate(Validator::verify_smscode($code));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrInputParam, $err);
+        }
+
+        // 校验验证码
+        $ret = sms_helper::check_code(sms_helper::register, $code, $mobile);
+        if (is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        // 判断是否处理
+        $model = Model('member');
+        $ret = $model->getBindedMemberByMobile($mobile);
+        if (empty($ret))
+        {
+            $passwd = $_POST['passwd'];
+            $validator = new Validator();
+            $validator->setValidate(Validator::verify_password($passwd));
+            $err = $validator->validate();
+            if ($err != '') {
+                return self::outerr(errcode::ErrInputParam, $err);
+            }
+            $member_info = ['member_mobile' => $mobile,
+                'member_type' => self::mobile_login,
+                'member_passwd' => $passwd,
+                'member_sex' => 0,
+                'member_name' => $mobile,
+                'member_nickname' => substr_replace($mobile, '****', 3, 4),
+                'member_mobile_bind' => 1];
+            $member_id = $model->addMember($member_info);
+
+            if (!isset($member_id) || $member_id == false) {
+                return self::outerr(errcode::ErrMemberNotExist);
+            } else {
+                account_helper::onRegister($member_id, session_helper::relay_id());
+            }
+        }
+        else {
+            $member_id = $ret['member_id'];
+        }
+
+        $update_arr = [];
+        $info = session_helper::parase_wxinfo($_GET['user_info']);
+        if ($info == false) {
+            $update_arr['member_wxopenid'] = $wx_openid;
+        } else {
+            $update_arr['member_wxopenid'] = $wx_openid;
+            $update_arr = array_merge($update_arr, $info);
+        }
+
+        $ret = $model->editMember(['member_id' => $member_id], $update_arr);
+        if (!$ret) {
+            return self::outerr(errcode::ErrDB);
+        } else {
+            $info = $model->getMemberInfoByID($member_id);
+            $model->createSession($info);
+            Model('cart')->mergecart($info, $_SESSION['store_id']);
+            Model('goods_browse')->mergebrowse($_SESSION['member_id'], $_SESSION['store_id']);
+            session::instance()->set_cookie($_SESSION['MPHPSESSID']);
+            return self::outsuccess(['member_id' => $_SESSION['member_id'], 'HPHPSESSID' => $_SESSION['MPHPSESSID']]);
+        }
+    }
+}

+ 391 - 0
mapi/control/member_address.php

@@ -0,0 +1,391 @@
+<?php
+/**
+ * 我的地址
+ *
+ *
+ *
+ *
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+
+
+class member_addressControl extends mbMemberControl
+{
+    const MAX_ADDRESS_COUNT = 50;
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function address_listOp()
+    {
+        $model_address = Model('address');
+        $address_list = $model_address->getAddressList(['member_id' => $_SESSION['member_id']]);
+        self::outsuccess(['address_list' => $address_list], 'shop/choose_address');
+    }
+    public function address_infoOp()
+    {
+        $address_id = intval($_POST['address_id']);
+        if (empty($_POST['address_id']) || $address_id < 0) {
+            return self::outerr(errcode::ErrParamter, "address_id = {$address_id}. must > 0.");
+        }
+
+        $model_address = Model('address');
+        $address_info = $model_address->getAddressInfo(['address_id' => $address_id,'member_id' => $_SESSION['member_id']]);
+        if (!empty($address_info)) {
+            self::outsuccess($address_info, 'shop/update_address');
+        } else {
+            return self::outerr(errcode::ErrAddress, '地址不存在');
+        }
+    }
+
+    public function address_delOp()
+    {
+        $address_id = intval($_POST['address_id']);
+        if (empty($_POST['address_id']) || $address_id < 0) {
+            return self::outerr(errcode::ErrParamter, "address_id = {$address_id}. must > 0.");
+        }
+
+        $model_address = Model('address');
+        $model_address->delAddress(['address_id' => $address_id,'member_id' => $_SESSION['member_id']]);
+        session_helper::clear_addr();
+        $default_address_info = $model_address->getDefaultAddressInfo(['member_id' => $_SESSION['member_id']]);
+        if (intval($default_address_info['is_default']) === 0) {
+            $this->_set_default($default_address_info['address_id'], 1);
+        }
+        self::outsuccess(['result' => '1']);
+    }
+
+    /**
+     * 新增地址
+     */
+    public function address_addOp()
+    {
+        $model_address = Model('address');
+        $address_info = $this->_address_valid($err, $err_code);
+        if ($err != '') {
+            return self::outerr($err_code, $err);
+        }
+
+        $addr_acount = $model_address->getAddressCount(['member_id' => $_SESSION['member_id']]);
+        if ($addr_acount >= self::MAX_ADDRESS_COUNT) {
+            return self::outerr(errcode::ErrAddress, '地址数量已达上限');
+        }
+
+        $result = $model_address->addAddress($address_info);
+        if ($result)
+        {
+            session_helper::clear_addr();
+            $addr_acount = $model_address->getAddressCount(['member_id' => $_SESSION['member_id']]);
+            if (intval($addr_acount) === 1) {
+                $this->_set_default($result, 1);
+            }
+            self::outsuccess(['address_id' => $result]);
+        } else {
+            return self::outerr(errcode::ErrAddress, '保存失败');
+        }
+    }
+
+    /**
+     * 编辑地址
+     */
+    public function address_editOp()
+    {
+        $address_id = intval($_POST['address_id']);
+        if (empty($_POST['address_id']) || $address_id < 0) {
+            return self::outerr(errcode::ErrParamter, "address_id = {$address_id}. must > 0.");
+        }
+
+        $model_address = Model('address');
+        $address_info = $model_address->getOneAddress($address_id);
+        //验证地址是否为本人
+        if ($address_info['member_id'] != $_SESSION['member_id']) {
+            return self::outerr(errcode::ErrAddress, '参数错误');
+        }
+        else
+        {
+            $address_info = $this->_address_valid($err, $errcode);
+            if(empty($address_info)) {
+                self::outerr($errcode,$err);
+            }
+            else
+            {
+                $result = $model_address->editAddress($address_info, ['address_id' => $address_id]);
+                if ($result) {
+                    session_helper::clear_addr();
+                    self::outsuccess(['result' => '1']);
+                } else {
+                    return self::outerr(errcode::ErrAddress, '保存失败');
+                }
+            }
+        }
+    }
+
+    /**
+     * 验证地址数据
+     */
+    private function _address_valid(&$err, &$errcode)
+    {
+        $obj_validate = new Validator();
+        $obj_validate->validateparam = [
+            ["input" => $_POST["true_name"], "require" => "true", "message" => '姓名不能为空'],
+            ["input" => $_POST["address"], "require" => "true", "message" => '地址不能为空'],
+            Validator::verify_mobile($_POST['mob_phone'])
+        ];
+
+        $err = $obj_validate->validate();
+        if ($err != '') {
+            $errcode = errcode::ErrAddress;
+            return NULL;
+        }
+
+        $area_id = intval($_POST['area_id']);
+        $area = search\search_client::instance()->get_area($area_id);
+        if ($area == false || $area['result'] == false) {
+            $errcode = errcode::ErrAddress;
+            return NULL;
+        }
+
+        $data = [];
+        $data['member_id'] = $_SESSION['member_id'];
+        $data['true_name'] = urldecode($_POST['true_name']);
+
+        $data['area_id'] = intval($area['country']['area_id']);
+        $data['city_id'] = intval($area['city']['area_id']);
+        $data['area_info'] = "{$area['province']['area_name']}\t{$area['city']['area_name']}\t{$area['country']['area_name']}";
+
+        $data['address'] = urldecode($_POST['address']);
+        $data['tel_phone'] = '';
+        $data['mob_phone'] = $_POST['mob_phone'];
+
+        return $data;
+    }
+
+    /**
+     * 编辑地址
+     */
+    public function set_defaultOp()
+    {
+        $address_id = intval($_POST['address_id']);
+        $is_default = intval($_POST['is_default']);
+
+        $model_address = Model('address');
+        //验证地址是否为本人
+        $address_info = $model_address->getOneAddress($address_id);
+        if ($address_info['member_id'] != $_SESSION['member_id']) {
+            return self::outerr(errcode::ErrAddress, '参数错误');
+        }
+        else
+        {
+            $ret = $this->_set_default($address_id, $is_default);
+            if ($ret) {
+                return self::outsuccess(['result' => '1']);
+            } else {
+                return self::outerr($ret['code'], $ret['msg']);
+            }
+        }
+    }
+
+    private function _set_default($address_id, $is_default)
+    {
+        $member_id = $_SESSION['member_id'];
+        $model = Model('address');
+        if ($is_default === 1)
+        {
+            if ($model->editAddress(['is_default' => '0'], ['member_id' => $member_id]) &&
+                $model->editAddress(['is_default' => '1'], ['address_id' => $address_id])) {
+                return true;
+            } else {
+                return ['code' => errcode::ErrAddress, 'msg' => '保存失败'];
+            }
+        }
+        else {
+            $area = $model->editAddress(['is_default' => '0'], ['address_id' => $address_id]);
+        }
+
+        if ($area) {
+            return true;
+        } else {
+            return ['code' => errcode::ErrAddress, 'msg' => '保存失败'];
+        }
+    }
+
+    /**
+     * 地区列表
+     */
+    public function area_listOp()
+    {
+        $prefix = "mb_";
+
+        $area_id = intval($_POST['area_id']);
+        if ($area_id > 0) {
+            $key = "area_parent_id_{$area_id}";
+        } else {
+            $key = "area_deep_1";
+        }
+
+        $from = $_POST['from'];
+        if($from === 'app') {
+            $key = "app_{$key}";
+        }
+
+        $ret = rcache($key,$prefix);
+        if(empty($ret))
+        {
+            $model_area = Model('area');
+
+            if ($from === 'app') {
+                $area_list = $this->get_area_list($area_id);
+            }
+            else
+            {
+                $condition = [];
+                if ($area_id > 0) {
+                    $condition['area_parent_id'] = $area_id;
+                } else {
+                    $condition['area_deep'] = 1;
+                }
+                $area_list = $model_area->getAreaList($condition, 'area_id,area_name');
+            }
+            wcache($key, ["area_list" => serialize($area_list)],$prefix);
+        }
+        else {
+            $area_list = unserialize($ret['area_list']);
+        }
+
+        self::outsuccess(['area_list' => $area_list]);
+    }
+
+    private function get_area_list($area_id)
+    {
+        $model_area = Model('area');
+        $condition = [];
+        if ($area_id > 0) {
+            $condition['area_parent_id'] = $area_id;
+        } else {
+            $condition['area_deep'] = 1;
+        }
+        $area_list = $model_area->getAreaList($condition, 'area_id,area_name');
+        foreach ($area_list as $k => $area) {
+            $area_list_by_id = $this->get_area_list($area['area_id']);
+            if (count($area_list_by_id) > 0) {
+                $area_list[$k]['area_list'] = $area_list_by_id;
+            }
+        }
+        return $area_list;
+    }
+}
+
+class tpl_address
+{
+    private $out_put;
+    private $address;
+    private $address_list;
+    public function __construct($out_put)
+    {
+        $this->out_put = $out_put;
+        $this->address = $this->out_put['address'];
+        $this->address_list = $this->out_put['address_list'];
+    }
+
+    public function show_address_list()
+    {
+        $goods_id = cookie('goods_id');
+        $number = cookie('number');
+        $card_id = $goods_id."|".$number;
+        foreach ($this->address_list as $key => $adlist)
+        {
+            if ($adlist['is_default']=='1') {
+                $address_id = $adlist['address_id'];
+                $herf_edit  = MOBILE_SITE_URL . '/index.php?act=member_address&op=address_info&address_id='.$adlist['address_id'];
+                $herf_first = MOBILE_SITE_URL.'/index.php?client_type=wap&act=member_buy&op=step_first'.'&cart_id='.$card_id
+                    .'&address_id='.$address_id.'&goods_id='.$goods_id.'&number='.$number;
+                echo "<div class=\"item-content default_address\">
+                      <a href='{$herf_first}' external><div class=\"row item-top\">                
+                        <div class=\"col-50\">{$adlist['true_name']}</div>
+                        <div class=\"col-50\">{$adlist['mob_phone']}</div>
+                    </div>
+                    <div class=\"row item\">
+                        <div class=\"col-80\">
+                            <span class=\"default_title\">[默认地址]</span>{$adlist['area_info']}{$adlist['address']}
+                        </div>
+                    </div></a>                               
+                    <a href=\"{$herf_edit}\" class=\"pull-right external\">
+                        <span class=\"icon icon-rev\"></span>
+                    </a>
+                </div>";
+                unset($this->address_list[$key]);
+            }
+        }
+
+        foreach ($this->address_list as $adlist) {
+            $address_id = $adlist['address_id'];
+            $herf_edit = MOBILE_SITE_URL . '/index.php?act=member_address&op=address_info&address_id='.$adlist['address_id'];
+            $herf_first = MOBILE_SITE_URL.'/index.php?client_type=wap&act=member_buy&op=step_first'.'&cart_id='.$card_id
+            .'&address_id='.$address_id.'&goods_id='.$goods_id.'&number='.$number;
+
+            echo "  <div class=\"item-content\">
+                 <a href='{$herf_first}' external><div class=\"row item-top\">
+                    <div class=\"col-50\">{$adlist['true_name']}</div>
+                    <div class=\"col-50\">{$adlist['mob_phone']}</div>
+                </div>
+                <div class=\"row\">
+                    <div class=\"col-80\">
+                        {$adlist['area_info']}{$adlist['address']}
+                    </div>
+                </div>
+                </a> 
+                <span class=\"pull-right icon icon-rev\"></span>
+                <a href=\"{$herf_edit}\" class=\"pull-right external\">
+                    <span class=\"icon icon-rev\"></span>
+                </a>
+            </div>";
+        }
+    }
+    public function show_edit()
+    {
+        echo
+            "<div class=\"list-block\">
+                <ul>
+                    <li class=\"item-content\">
+                        <div class=\"item-inner list_padding_left row\">
+                            <div class=\"col-25\"><label for=\"username\">收件人姓名</label></div>
+                            <div class=\"col-75\"><input type=\"text\" value=\"{$this->single_info['true_name']}\" name=\"true_name\" id=\"username\"/></div>
+                        </div>
+                    </li>
+                    <li class=\"item-content\">
+                        <div class=\"item-inner list_padding_left row\">
+                            <div class=\"col-25\"><label for=\"telphone\">手机号码</label></div>
+                            <div class=\"col-75\"><input type=\"text\" value=\"{$this->single_info['mob_name']}\" name=\"mob_phone\" id=\"telphone\"/></div>
+                        </div>
+                    </li>
+                    <li class=\"item-content\">
+                        <div class=\"item-inner list_padding_left row\">
+                            <div class=\"col-25\"><label for=\"city-picker\">所在区域</label></div>
+                            <div class=\"col-75\"><input type=\"text\" value=\"{$this->single_info['area_info']}\" name=\"area_info\" id=\"city-picker\"/></div>
+                        </div>
+                    </li>
+                    <li class=\"item-content\">
+                        <div class=\"item-inner list_padding_left row\">
+                            <div class=\"col-25\"><label for=\"address\">详细地址</label></div>
+                            <div class=\"col-75\"><input type=\"text\" value=\"{$this->single_info['address']}\" name=\"address\" id=\"address\"/></div>
+                        </div>
+                    </li>
+                </ul>
+            </div>";
+
+        echo
+            "<div class=\"default_btn\">
+                <label><input class=\"icon_check\" type=\"checkbox\" value=\"1\" name=\"default_id\"/>设置为默认地址</label>
+            </div>";
+
+    }
+
+}

File diff suppressed because it is too large
+ 1548 - 0
mapi/control/member_bonus.php


+ 514 - 0
mapi/control/member_buy.php

@@ -0,0 +1,514 @@
+<?php
+/**
+ * 购买
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_HELPER_PATH . '/bonus_helper.php');
+require_once(BASE_HELPER_PATH . '/buy_first.php');
+require_once(BASE_HELPER_PATH . '/pay_helper.php');
+require_once(BASE_HELPER_PATH . '/fcode/operator.php');
+require_once(BASE_HELPER_PATH . '/fcode/send_manager.php');
+require_once(BASE_HELPER_PATH . '/user_session/fcode.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
+
+
+class member_buyControl extends mbMemberControl
+{
+    private $mFcodeBannerID;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        global $config;
+        $this->mFcodeBannerID = $config['autosend_fcodes']['payconfirm_spid'];
+    }
+
+    public function calc_cashOp()
+    {
+        $cart_ids = explode(',', urldecode($_POST['cart_id']));
+        if (empty($cart_ids))
+        {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $logic_buy = Logic('buy');
+        $id_num = $this->pay_goods($cart_ids);
+        //得到购买数据
+        $result = $logic_buy->buyStep1($id_num, $_POST['ifcart'], $_SESSION['member_id'], $_SESSION['store_id']);
+        if (!$result['state'])
+        {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        }
+        else
+        {
+            $result = $result['data'];
+        }
+
+        $buy_helper = new buy_first($result, $this->price_calcer());
+        if ($buy_helper->check_fcode($error) == false)
+        {
+            return self::outerr(errcode::ErrPayment, $error);
+        }
+        else
+        {
+            $result = $buy_helper->format();
+            $cash_amount = $result['payinfo']['pay_car_pred'];
+            $total_amonut = $result['payinfo']['pay_car_nopred'];
+
+            return self::outsuccess(['cash_amount' => $cash_amount, 'goods_amount' => $total_amonut, 'payinfo' => $result['payinfo']]);
+        }
+    }
+
+    public function step_firstOp()
+    {
+        $cart_ids = explode(',', urldecode($_POST['cart_id']));
+        if (empty($cart_ids))
+        {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $virtual_goods = $this->virtual_goods($_POST, $cart_ids);
+        if ($virtual_goods == false) {
+            $logic_buy = Logic('buy');
+            $id_num = $this->pay_goods($cart_ids);
+            $result = $logic_buy->buyStep1($id_num, $_POST['ifcart'], session_helper::memberid(), $_SESSION['store_id']);
+            $fVirual = false;
+        }
+        else {
+            #虚拟商品
+            $logic_buy = Logic('buy_virtual');
+            $result = $logic_buy->getBuyStep2Data($virtual_goods['goods_id'], $virtual_goods['num'], session_helper::memberid());
+            $fVirual = true;
+        }
+
+        if (!$result['state']) {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        }
+        else {
+            $result = $result['data'];
+        }
+
+        if ($fVirual) {
+            $buy_helper = new buyv_first($result, $this->price_calcer());
+        }
+        else {
+            $buy_helper = new buy_first($result, $this->price_calcer());
+        }
+
+        if ($buy_helper->check_fcode($error) == false) {
+            return self::outerr(errcode::ErrPayment, $error);
+        }
+        else {
+            $result = $buy_helper->format();
+            return self::outsuccess($result);
+        }
+    }
+
+    private function virtual_goods($input, $cart_id)
+    {
+        if (boolval($input['ifcart']) == true) return false;
+
+        //存放所购商品ID和数量组成的键值对
+        $buy_items = [];
+        if (is_array($cart_id))
+        {
+            foreach ($cart_id as $value)
+            {
+                if (preg_match_all('/^(\d{1,10})\|(\d{1,6})$/', $value, $match))
+                {
+                    if (intval($match[2][0]) > 0) {
+                        $buy_items[$match[1][0]] = $match[2][0];
+                    }
+                }
+            }
+        }
+        if (count($buy_items) != 1) return false;
+
+        foreach ($buy_items as $key => $val) {
+            $goods_id = intval($key);
+            $num = intval($val);
+        }
+
+        $mod_goods = Model('goods');
+        $info = $mod_goods->getGoodsInfoByID($goods_id);
+        if ($info['is_virtual'] != 1) return false;
+
+        return ['goods_id' => $goods_id, 'num' => $num];
+    }
+
+    public function step_secondOp()
+    {
+        $cart_ids = explode(',', urldecode($_POST['cart_id']));
+        if (empty($cart_ids)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $param = [];
+        $param['ifcart'] = $_POST['ifcart'];
+        $param['cart_id'] = $this->pay_goods($cart_ids);
+        $param['address_id'] = $_POST['address_id'];
+        $param['invoice_id'] = $_POST['invoice_id'];
+        $param['vat_hash'] = $_POST['vat_hash'];
+        $param['offpay_hash'] = $_POST['offpay_hash'];
+        $param['offpay_hash_batch'] = $_POST['offpay_hash_batch'];
+
+        $param['voucher'] = [];
+        $param['pd_pay'] = 0;
+        $param['rcb_pay'] = 0;
+        $param['password'] = "";
+        $param['fcode'] = "";
+        $param['order_from'] = 2; //从手机来
+        $param['pay_name'] = "online";
+        $param['usebonus'] = $_POST['usebonus'];
+        $param['pd_pay'] = empty($_POST['usepred']) ? 0 : 1;
+        $param['room_id'] = $_POST['room_id'];
+
+        $logic_buy = Logic('buy');
+        $result = $logic_buy->buyStep2($param, $_SESSION['member_id'], $_SESSION['member_name'], $_SESSION['member_email']);
+        if (!$result['state']) {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        }
+        else
+        {
+            $pay_sn = $result['data']['pay_sn'];
+            $payment = $_POST['payment'];
+
+            $payer = new pay_helper($pay_sn);
+            $out_put = $payer->pay($payment, $err);
+
+            if ($out_put == false)  {
+                return self::outerr($err['code'], $err['msg']);
+            }
+            else {
+                $out_put['payment'] = $payment;
+                $out_put['pay_sn'] = $pay_sn;
+
+                return self::outsuccess($out_put);
+            }
+        }
+    }
+
+    private function check_time()
+    {
+        $start_tm = localtime(strtotime('2020-09-28'),true);
+        $end_tm = localtime(strtotime('2020-10-08'),true);
+        $tm = localtime(time(), true);
+
+//        return ($tm['tm_hour'] > 8 && $tm['tm_hour'] < 21) && ($tm['tm_yday'] < $start_tm['tm_yday'] || $tm['tm_yday'] > $end_tm['tm_yday']);
+        return ($tm['tm_hour'] > 8 && $tm['tm_hour'] < 21 && $tm['tm_wday'] > 0 && $tm['tm_wday'] < 6);
+    }
+
+    public function step_vsecondOp()
+    {
+        if(!$this->check_time()) {
+            return self::outerr(errcode::ErrInputParam, '目前充值时间段为9:00--21:00,本周六周日运营商系统维护,请下周再来~');
+//            return self::outerr(errcode::ErrInputParam, '国庆节期间系统维护,其余充值时间段为9:00--21:00~');
+//            return self::outerr(errcode::ErrInputParam, '系统正在维护,请稍后再试~');
+        }
+        $cart_ids = explode(',', urldecode($_POST['cart_id']));
+        $virtual_goods = $this->virtual_goods($_POST, $cart_ids);
+
+        $logic_buy_virtual = Logic('buy_virtual');
+        $input = [];
+        $input['goods_id'] = $virtual_goods['goods_id'];
+        $input['quantity'] = $virtual_goods['num'];
+
+        $input['buyer_phone'] = $_POST['buyer_phone'] ?? session_helper::mobile();
+        $input['buyer_name'] = $_POST['buyer_name'] ?? session_helper::nickname();
+        $input['buyer_msg'] = $_POST['buyer_msg'] ?? '';
+
+        [$fExtra, $extra_info, $order_check] = $this->extra_info($input['goods_id'], $_POST);
+        if (!$fExtra) {
+            Log::record("step_vsecond error", Log::ERR);
+            return self::outerr(errcode::ErrInputParam, '缺少虚拟商品额外指定参数.');
+        }
+        if(array_key_exists('phone_no',$extra_info['input']) && empty($extra_info['input']['phone_no'])) {
+            return self::outerr(errcode::ErrInputParam, '一个手机号只能绑定一张油卡,请换卡.');
+        }
+
+        if(!empty($order_check))
+        {
+            $logic = Logic('queue');
+            $ret = $logic->$order_check(['extra_info' => $extra_info,'goods_id' => $input['goods_id']]);
+
+            if(!$ret['state']) {
+                return self::outerr(errcode::ErrInputParam, $ret['msg']);
+            }
+        }
+
+        $input['order_from'] = 2;
+        $calctor = new CalcPrice(session_helper::memberid());
+        $result = $logic_buy_virtual->buyStep3($input, session_helper::memberid(),[$calctor,'calc_vorder_amount']);
+        if (!$result['state']) {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        }
+        else
+        {
+            $calctor->deduct_order($result['data']['order_id']);
+
+            $payment = $_POST['payment'];
+            $order_sn = $result['data']['order_sn'];
+
+            $payer = new pay_helper($order_sn);
+            $out_put = $payer->pay($payment, $err);
+
+            if ($out_put == false) {
+                return self::outerr($err['code'], $err['msg']);
+            }
+            else
+            {
+                $out_put['payment'] = $payment;
+                $out_put['pay_sn'] = $order_sn;
+
+                if (!empty($extra_info)) {
+                    Model('vr_order')->editOrder(['extra_info' => json_encode($extra_info, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)], ['order_sn' => $order_sn]);
+                }
+
+                QueueClient::push('OnVrOrderSuccess', ['order_sn' => $order_sn]);
+                return self::outsuccess($out_put);
+            }
+        }
+    }
+
+    public function extra_info($goods_id, $input)
+    {
+        global $config;
+        $handlers = $config['vgoods_handlers'];
+        if (array_key_exists($goods_id, $handlers))
+        {
+            $handler = $handlers[$goods_id];
+
+            $extra = [];
+            $types = $handler['input_params'];
+            foreach ($types as $item)
+            {
+                if (isset($input[$item])) {
+                    $extra['input'][$item] = $input[$item];
+                }
+                elseif(session_helper::version_code() <= 171 && $item == "phone_no") {
+                    $extra['input'][$item] = "";
+                }
+                else {
+                    Log::record("{$goods_id}号商品,在提交订单中,缺少{$item}字段.", Log::ERR);
+                    return [false, [], ''];
+                }
+            }
+
+            if (!empty($handler['additional'])) {
+                $extra['additional'] = $handler['additional'];
+            }
+
+            if(array_key_exists('phone_no',$extra['input'])) {
+                $phone_no = $this->check_oilmobile($extra['input']);
+                $extra['input']['phone_no'] = $phone_no;
+            }
+
+            return [true, $extra, $handler['order_check']];
+        }
+        return [true, [], ''];
+    }
+
+    private function check_oilmobile($params)
+    {
+        $phone_no = $params['phone_no'];
+        $card_no  = $params['card_no'];
+        if(empty($card_no)) {
+            return "";
+        }
+
+        $find_card = function ($topcard,$card_no) {
+            $items = $topcard->table('topcard')->field('*')->where(['card_no' => $card_no])->select();
+            if(empty($items)) {
+                return "";
+            } else {
+                return $items[0]['bind_phone'];
+            }
+        };
+        $find_phone = function ($topcard,$phone_no) {
+            $items = $topcard->table('topcard')->field('*')->where(['bind_phone' => $phone_no])->select();
+            if(empty($items)) {
+                return "";
+            } else {
+                return $items[0]['card_no'];
+            }
+        };
+
+        $topcard = Model('topcard');
+        $phone = $find_card($topcard,$card_no);
+        if(!empty($phone)) {
+            return $phone;
+        }
+
+        $card = $find_phone($topcard,$phone_no);
+        if(empty($card)) {
+            return $phone_no;
+        }
+        else {
+            return "";
+        }
+    }
+
+    public function pay_confirmOp()
+    {
+        $pay_sn = $_GET['pay_sn'];
+        if (empty($pay_sn)) {
+            return self::outerr(errcode::ErrParamter, "支付号或者支付类型错误");
+        }
+        $payer = new pay_helper($pay_sn);
+        $paied = $payer->confirm($err, $amount, $fcode_state);
+
+        if ($paied == false) {
+            return self::outerr($err['code'], $err['msg']);
+        }
+        else
+        {
+            session_helper::add_order();
+            if ($fcode_state == 1) {
+                return self::outsuccess(['special_list' => null, 'summary' => null, 'groupbuy' => null, 'limitime' => null, 'bundling' => null, 'mobile_page' => mobile_page(1)]);
+            }
+            else
+            {
+                $result = fcode\send_manager::instance()->fetch($amount, $pay_sn, session_helper::mobile(), session_helper::session_id());
+                if ($result != false)
+                {
+                    $order_pay = Model('order_pay');
+                    $order_pay->where(['pay_sn' => $pay_sn])->update(['fcode_state' => 1]);
+
+                    $fcode = new user_session\fcode();
+                    $fcode->onStatus();
+
+                    if ($this->mFcodeBannerID > 0) {
+                        $blocks = special_manager::instance()->special($this->mFcodeBannerID, $unused_gids);
+                    }
+                    else {
+                        $blocks = [];
+                    }
+
+                    foreach ($result['banner'] as $block) {
+                        $blocks[] = $block;
+                    }
+
+                    $fcodes = [];
+                    $gids = [];
+                    foreach ($result['fcode'] as $item)
+                    {
+                        $fcoder = new fcode\mfcode($item);
+                        $fcode = $fcoder->format();
+                        if ($fcode != false) {
+                            $gids[] = intval($fcode['goods_id']);
+                            $fcodes[] = $fcode;
+                        }
+                    }
+
+                    $fcode_blocks = $this->fcode_blocks($fcodes);
+                    foreach ($fcode_blocks as $fblock) {
+                        $blocks[] = $fblock;
+                    }
+
+                    $helper = new goods_helper($this->price_calcer(), false);
+                    $ret = $helper->cart_summary($gids, $related_goods);
+
+                    return self::outsuccess(['special_list' => $blocks, 'fcodes' => $fcodes, 'summary' => $ret['summary'], 'groupbuy' => $ret['groupbuy'], 'limitime' => $ret['limitime'], 'bundling' => $ret['bundling'], 'mobile_page' => mobile_page(1)]);
+                }
+                else
+                {
+                    return self::outsuccess(['special_list' => null, 'summary' => null, 'groupbuy' => null, 'limitime' => null, 'bundling' => null, 'mobile_page' => mobile_page(1)]);
+                }
+            }
+        }
+    }
+
+    private function fcode_blocks($fcodes)
+    {
+        $blocks = [];
+        foreach ($fcodes as $fcode)
+        {
+            $block = [];
+            $block['item_title'] = '';
+            $block['item_type'] = 'home1';
+            $block['scale'] = 3.224299;
+
+            $item['image'] = '';
+            $item['show_type'] = "fcode";
+            $item['show_data'] = strval($fcode['fcode_id']);
+            $item['type'] = "goods";
+            $item['data'] = strval($fcode['goods_id']);;
+            $item['title'] = '';
+
+            $block['items'][] = $item;
+            $blocks[] = $block;
+        }
+
+        return $blocks;
+    }
+
+    public function change_addrexOp()
+    {
+        $logic_buy = Logic('buy');
+        $data = $logic_buy->changeAddr($_POST['freight_hash'], $_POST['city_id'], $_POST['area_id'], $_SESSION['member_id']);
+        if (!empty($data) && $data['state'] == 'success')
+        {
+            $result['offpay_hash'] = $data['offpay_hash'];
+            $result['offpay_hash_batch'] = $data['offpay_hash_batch'];
+
+            $freight = 0.00;
+            foreach ($data['content'] as $value) {
+                $freight += $value['value'];
+            }
+            $result['freight'] = $freight;
+
+            return self::outsuccess($result);
+        }
+        else
+        {
+            return self::outerr(errcode::ErrOrder, '地址修改失败');
+        }
+    }
+
+    private function pay_goods($cart_ids)
+    {
+        if (boolval($_POST['ifcart']) == true)
+        {
+            $mod_cart = Model('cart');
+            $items = $mod_cart->listCart('db', ['cart_id' => ['in', $cart_ids]], false);
+            $id_num = [];
+            foreach ($items as $val) {
+                $cart_id = $val['cart_id'];
+                $goods_num = $val['goods_num'];
+                $id_num[] = "{$cart_id}|{$goods_num}";
+            }
+            return $id_num;
+        }
+        else {
+            $id_num = $cart_ids;
+            return $id_num;
+        }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function check_passwordOp()
+    {
+        if (empty($_POST['password'])) {
+            return self::outerr(errcode::ErrOrder, '参数错误');
+        }
+
+        $model_member = Model('member');
+        $member_info = $model_member->getMemberInfoByID($_SESSION['member_id']);
+        if ($member_info['member_paypwd'] == md5($_POST['password'])) {
+            return self::outsuccess(['result' => '1']);
+        }
+        else {
+            return self::outerr(errcode::ErrOrder, '密码错误');
+        }
+    }
+}

+ 116 - 0
mapi/control/member_card.php

@@ -0,0 +1,116 @@
+<?php
+declare(strict_types=0);
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH   . '/helper/session_helper.php');
+require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
+
+class member_cardControl extends mbMemberControl
+{
+    const MAX_CARD_COUNT = 50;
+    private $mCardModel;
+
+    public function __construct() {
+        parent::__construct();
+        $this->mCardModel = Model('member_topcard');
+    }
+
+    public function card_listOp()
+    {
+        $card_type = mtopcard\topcard_type($_GET['card_type']);
+        if($card_type < 1 || $card_type > 3) {
+            $card_list = $this->mCardModel->getAllCards(session_helper::memberid());
+        }
+        else {
+            $card_list = $this->mCardModel->getCardsByType(session_helper::memberid(),$card_type);
+        }
+
+        $ret = mtopcard\topcard_format($card_list);
+        self::outsuccess(['card_list' => $ret]);
+    }
+
+    public function card_addOp()
+    {
+        $card_type = mtopcard\topcard_type($_GET['card_type']);
+        $card_no = $_GET['card_no'];
+
+        if($card_type < 1 || $card_type > 3 || empty($card_no)) {
+            return self::outerr(errcode::ErrParamter, '输入参数错误.');
+        }
+
+        $cards = new mtopcard\user_topcards(session_helper::memberid());
+        $result = $cards->addCard($card_no,$card_type);
+
+        if ($result) {
+            self::outsuccess(null);
+        } else {
+            return self::outerr(errcode::ErrTopCard, '充值卡保存失败');
+        }
+    }
+
+    public function card_editOp()
+    {
+        $card_id = intval($_GET['topcard_id']);
+        $card_no = $_GET['card_no'];
+        $card_type = mtopcard\topcard_type($_GET['card_type']);
+
+        $data = [];
+        if(!empty($card_no)) {
+            $data['card_no'] = $card_no;
+        }
+        if($card_type > 0 || $card_type < 4) {
+            $data['card_type'] = $card_type;
+        }
+
+        if($card_id < 0 || empty($data)) {
+            return self::outerr(errcode::ErrParamter, '输入参数错误.');
+        }
+        $card_info = $this->mCardModel->getCard($card_id);
+        if(empty($card_info)) {
+            return self::outerr(errcode::ErrTopCard, '没有找到卡信息.');
+        }
+
+        $card = new mtopcard\topcard($card_info);
+        if($card->can_edit())
+        {
+            $ret = $this->mCardModel->edit($card_id,$data);
+            if($ret) {
+                return self::outsuccess(null);
+            }
+            else {
+                return self::outerr(errcode::ErrTopCard, '编辑保存失败.');
+            }
+        }
+        else {
+            return self::outerr(errcode::ErrTopCard, '充值卡已经充过值,不能编辑.');
+        }
+    }
+
+    public function card_delOp()
+    {
+        $card_id = intval($_GET['topcard_id']);
+        if($card_id < 0) {
+            return self::outerr(errcode::ErrParamter, '输入参数错误.');
+        }
+        $card_info = $this->mCardModel->getCard($card_id);
+        if(empty($card_info)) {
+            return self::outerr(errcode::ErrTopCard, '没有找到卡信息.');
+        }
+
+        $card = new mtopcard\topcard($card_info);
+        if($card->can_edit())
+        {
+            $ret = $this->mCardModel->delete($card_id);
+            if($ret) {
+                return self::outsuccess(null);
+            }
+            else {
+                return self::outerr(errcode::ErrTopCard, '删除卡失败.');
+            }
+        }
+        else {
+            return self::outerr(errcode::ErrTopCard, '充值卡已经充过值,不能删除.');
+        }
+    }
+}

+ 23 - 0
mapi/control/member_cart.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/3/23
+ * Time: 下午3:27
+ */
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_MOBILE_PATH . '/control/cart.php');
+
+class member_cartControl extends cartControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function cart_addOp()
+    {
+        parent::addOp();
+    }
+}

+ 306 - 0
mapi/control/member_evaluate.php

@@ -0,0 +1,306 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2016/12/13
+ * Time: 下午8:31
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/FileUploader.php');
+require_once(BASE_ROOT_PATH . '/helper/order_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/account_helper.php');
+
+
+class member_evaluateControl extends mbMemberControl
+{
+    const pic_path = '/data/upload/shop/member';
+
+    public function __construct() {
+        parent::__construct();
+    }
+    public function indexOp()
+    {
+
+    }
+
+    private function order_id(&$err,&$order_info,&$store_info,&$order_goods)
+    {
+        $order_id = intval($_GET['order_id']);
+        $order_sn = $_GET['order_sn'];
+
+        if ($order_id <= 0 && empty($order_sn)) {
+            $err = array('code' => errcode::ErrOrderNotExist,'msg' => "订单信息不存在.");
+            return false;
+        }
+        else
+        {
+            if($order_id > 0) {
+                $cond['order_id'] = $order_id;
+            } else {
+                $cond['order_sn'] = $order_sn;
+            }
+        }
+
+        $model_order = Model('order');
+        $model_store = Model('store');
+        $order_info = $model_order->getOrderInfo($cond);
+
+        if(empty($order_info)) {
+            $err = array('code' => errcode::ErrOrder,'msg' => "无此订单.");
+            return false;
+        }
+
+        $order_id = intval($order_info['order_id']);
+        //判断订单身份
+        if($order_info['buyer_id'] != $_SESSION['member_id']) {
+            $err = array('code' => errcode::ErrOrder,'msg' => "只能评论自己的订单.");
+            return false;
+        }
+
+        //订单为'已收货'状态,并且未评论
+        $order_info['evaluate_able'] = $model_order->getOrderOperateState('evaluation',$order_info);
+        if (empty($order_info) || !$order_info['evaluate_able']) {
+            $err = array('code' => errcode::ErrOrder,'msg' => "该订单目前不能评论.");
+            return false;
+        }
+
+        //查询店铺信息
+        $store_info = $model_store->getStoreInfoByID($order_info['store_id']);
+        if(empty($store_info)) {
+            $err = array('code' => errcode::ErrOrder,'msg' => "店铺不存在.");
+            return false;
+        }
+
+        //获取订单商品
+        $order_goods = $model_order->getOrderGoodsList(array('order_id'=>$order_id));
+        if(empty($order_goods)) {
+            $err = array('code' => errcode::ErrOrder,'msg' => "找不到该订单商品.");
+            return false;
+        }
+        return $order_id;
+    }
+
+    public function infoOp()
+    {
+        $order_id = $this->order_id($err,$order_info,$store_info,$order_goods);
+        if($order_id == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+
+        for ($i = 0, $j = count($order_goods); $i < $j; $i++) {
+            $order_goods[$i]['goods_image_url'] = cthumb($order_goods[$i]['goods_image'], 240, $store_info['store_id']);
+        }
+
+        $result = [];
+        foreach ($order_goods as $key => $val) {
+            $item['goods_id'] = intval($val['goods_id']);
+            $item['goods_image'] = $val['goods_image_url'];
+            $item['store_id'] = intval($val['store_id']);
+            $item['goods_spec'] = $val['goods_spec'];
+            $item['goods_name'] = $val['goods_name'];
+            $result[] = $item;
+        }
+
+        return self::outsuccess(array('order_goods' => $result,'order_id' => $order_id));
+    }
+
+    private function destpath()
+    {
+        $path = BASE_ROOT_PATH . self::pic_path . '/' . $_SESSION['member_id'];
+        if(is_dir($path)) {
+            return $path;
+        }
+        else
+        {
+            if(mkdir($path)) {
+                return $path;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private function upfile($img,&$err)
+    {
+        $member_id = $_SESSION['member_id'];
+
+        $upload = new FileUploader();
+        if($upload->init_files($img,$member_id,$err) == false) {
+            return false;
+        }
+
+        $upload_dir = ATTACH_MALBUM.DS.$member_id.DS;
+        $upload->set('default_dir',$upload_dir.$upload->getSysSetPath());
+        $thumb_width	= '240,1024';
+        $thumb_height	= '2048,1024';
+
+        $upload->set('max_size',C('image_max_filesize'));
+        $upload->set('thumb_width', $thumb_width);
+        $upload->set('thumb_height',$thumb_height);
+        $upload->set('fprefix',$member_id);
+        $upload->set('thumb_ext', '_240,_1024');
+        $result = $upload->upfile('file');
+        if($result == true) {
+            return $upload->file_name;
+        } else {
+            $err = array('code' => errcode::ErrUpfile, 'msg' => $upload->error);
+            return false;
+        }
+    }
+
+    private function comment(&$err)
+    {
+        $input_goods = trim($_POST['evaluation']);
+        if(empty($input_goods)) {
+            $err = array('code' => errcode::ErrParamter,'msg' => "请填写评论信息.");
+            return false;
+        }
+
+        $input_goods = base64_decode($input_goods);
+        $input_goods = json_decode($input_goods,true);
+        if(empty($input_goods)) {
+            $err = array('code' => errcode::ErrParamter,'msg' => "请填写评论信息.");
+            return false;
+        }
+
+        $save_path = $this->destpath();
+        if($save_path == false) {
+            $err = array('code' => errcode::ErrParamter,'msg' => "请填写评论信息.");
+            return false;
+        }
+
+        $result = [];
+        foreach ($input_goods as $val)
+        {
+            $goods_id = intval($val['goods_id']);
+            $score = intval($val['score']);
+
+            $imges = [];
+            foreach ($val['images'] as $img)
+            {
+                $file_name = $this->upfile($img);
+                if($file_name != false) {
+                    $imges[] = $file_name;
+                }
+            }
+
+            $item['goods_id'] = $goods_id;
+            $item['score'] = $score;
+            $item['comment'] = $val['comment'];
+            $item['images'] = implode(',',$imges);
+
+            $result[$goods_id] = $item;
+        }
+
+        return $result;
+    }
+
+    public function addOp()
+    {
+        $order_id = $this->order_id($err,$order_info,$store_info,$order_goods);
+        if($order_id == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        $comments = $this->comment($err);
+        if($comments == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+
+        $anony = $_POST['anony'] ? 1 : 0;
+        $model_order = Model('order');
+        $model_evaluate_goods = Model('evaluate_goods');
+
+        $evaluate_goods_array = array();
+        $goodsid_array = array();
+
+        $mod_goods = Model('goods');
+        foreach ($order_goods as $value)
+        {
+            $goods_id = intval($value['goods_id']);
+            $goods_commonid = commonid_helper::instance()->common_id($goods_id);
+            //如果未评分,默认为5分
+            $evaluate_score = $comments[$goods_id]['score'];
+            if($evaluate_score <= 0 || $evaluate_score > 5) {
+                $evaluate_score = 5;
+            }
+            //默认评语
+            $evaluate_comment = $comments[$goods_id]['comment'];
+            if(empty($evaluate_comment)) {
+                $evaluate_comment = '不错哦';
+            }
+            $geval_image = $comments[$value['goods_id']]['images'];
+
+            $evaluate_goods_info = array();
+            $evaluate_goods_info['geval_orderid'] = $order_id;
+            $evaluate_goods_info['geval_orderno'] = $order_info['order_sn'];
+            $evaluate_goods_info['geval_ordergoodsid'] = $value['rec_id'];
+            $evaluate_goods_info['geval_commonid'] = $goods_commonid;
+            $evaluate_goods_info['geval_goodsid'] = $value['goods_id'];
+            $evaluate_goods_info['geval_goodsname'] = $value['goods_name'];
+            $evaluate_goods_info['geval_goodsprice'] = $value['goods_price'];
+            $evaluate_goods_info['geval_goodsimage'] = $value['goods_image'];
+            $evaluate_goods_info['geval_scores'] = $evaluate_score;
+            $evaluate_goods_info['geval_content'] = $evaluate_comment;
+            $evaluate_goods_info['geval_isanonymous'] = $anony;
+            $evaluate_goods_info['geval_addtime'] = time();
+            $evaluate_goods_info['geval_storeid'] = $store_info['store_id'];
+            $evaluate_goods_info['geval_storename'] = $store_info['store_name'];
+            $evaluate_goods_info['geval_frommemberid'] = $_SESSION['member_id'];
+            $evaluate_goods_info['geval_frommembername'] = $_SESSION['member_name'];
+
+            if(!empty($geval_image)) {
+                $evaluate_goods_info['geval_image'] = $geval_image;
+            } else {
+                $evaluate_goods_info['geval_image'] = '';
+            }
+
+            $evaluate_goods_array[] = $evaluate_goods_info;
+            $goodsid_array[] = $value['goods_id'];
+
+            $mod_goods->editGoodsCommon(['comments' => array('exp', "comments+1")],['goods_commonid' => $goods_commonid]);
+        }
+
+        $model_evaluate_goods->addEvaluateGoodsArray($evaluate_goods_array, $goodsid_array);
+
+        //更新订单信息并记录订单日志
+        $state = $model_order->editOrder(array('evaluation_state'=>1), array('order_id' => $order_id));
+        $model_order->editOrderCommon(array('evaluation_time'=>time()), array('order_id' => $order_id));
+        if ($state) {
+            $data = array();
+            $data['order_id'] = $order_id;
+            $data['log_role'] = 'buyer';
+            $data['log_msg'] = L('order_log_eval');
+            $model_order->addOrderLog($data);
+            QueueClient::push('onAsyncOrderEvaluate',['pay_sn' => $order_info['pay_sn']]);
+        }
+
+        //添加会员积分
+        if (C('points_isuse') == 1){
+            $points_model = Model('points');
+            $points_model->savePointsLog('comments',array('pl_memberid'=>$_SESSION['member_id'],'pl_membername'=>$_SESSION['member_name']));
+        }
+        //添加会员经验值
+        Model('exppoints')->saveExppointsLog('comments',array('exp_memberid'=>$_SESSION['member_id'],'exp_membername'=>$_SESSION['member_name']));
+
+        $order = $this->get_order(array("buyer_id" => $_SESSION['member_id'],'order_id' => $order_id));
+        if($order == false) {
+            $order = null;
+        }
+
+        return self::outsuccess(array("act_type" => 'if_evaluation',"order_id" => $order_id, "order" => $order));
+    }
+
+    private function get_order($condition)
+    {
+        $model_order = Model('order');
+        $order_list = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '', array('order_common','order_address', 'order_goods'));
+        $order_helper = new order_helper($order_list);
+        $orders = $order_helper->format();
+        $model_order->cls();
+        if(!empty($orders)) {
+            return $orders[0];
+        } else {
+            return false;
+        }
+    }
+}

+ 162 - 0
mapi/control/member_favorites.php

@@ -0,0 +1,162 @@
+<?php
+/**
+ * 我的收藏
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once (BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/favorite.php');
+
+class member_favoritesControl extends mbMemberControl
+{
+    static $stTypes = ['goods','brand'];
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $mod_favorites = Model('favorites');
+        $favorites  = $mod_favorites->getGoodsFavoritesList(['member_id' => $_SESSION['member_id']], '*', $this->page_size);
+        $page_count = $mod_favorites->gettotalpage();
+
+        $gids = [];
+        foreach ($favorites as $item)
+        {
+            if($item['fav_type'] == 'goods') {
+                $gids[] = intval($item['fav_id']);
+            }
+            elseif($item['fav_type'] == 'brand') {
+                continue;
+            }
+            else {
+                continue;
+            }
+        }
+
+        if(empty($gids))
+        {
+            return self::outsuccess(['special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_count)]);
+        }
+
+        $helper = new goods_helper($this->price_calcer());
+        $ret = $helper->online_summary($gids,$related_goods);
+        $block = special_formater::format_goods($gids,'我的商品',$ret['sort_summary']);
+        $blocks[] = $block;
+
+        return self::outsuccess(['special_list' => $blocks,
+            'summary'  => $ret['summary'],
+            'groupbuy' => $ret['groupbuy'],
+            'limitime' => $ret['limitime'],
+            'bundling' => $ret['bundling'],
+            'mobile_page' => mobile_page($page_count)]);
+    }
+
+    private function format($goods_ids,$sort_summary)
+    {
+        $result = [];
+
+        foreach ($goods_ids as $goods_id)
+        {
+            $block = [];
+            $block['item_title'] = '';
+            $block['item_type'] = 'home1';
+
+            $summary = $sort_summary[$goods_id];
+            $item['image'] = $summary['goods_image_url'];
+            $item['show_type'] = "favorite";
+            $item['show_data'] = strval($goods_id);
+            $item['type'] = "goods";
+            $item['data'] = strval($goods_id);
+            $item['title'] = $summary['goods_mobile_name'];
+
+            $block['items'][] = $item;
+            $result[] = $block;
+            $result[] = special_formater::def_divider();
+        }
+
+        return $result;
+    }
+
+    public function addOp()
+    {
+        $fav_type = $_POST['fav_type'];
+        $fav_id   = intval($_POST['fav_id']);
+
+        if ($fav_id <= 0 || empty($fav_type) || !in_array($fav_type,self::$stTypes)) {
+            return self::outerr(errcode::ErrParamter,"参数错误");
+        }
+
+        $mod_fav = Model('favorites');
+        $favorites_info = $mod_fav->getOneFavorites(['fav_id' => $fav_id, 'fav_type' => $fav_type, 'member_id' => $_SESSION['member_id']]);
+        if (!empty($favorites_info)) {
+            return self::outsuccess(null);
+        }
+        else
+        {
+            $insert_arr = [];
+            $insert_arr['member_id'] = $_SESSION['member_id'];
+            $insert_arr['fav_id']    = $fav_id;
+            $insert_arr['fav_type']  = $fav_type;
+            $insert_arr['fav_time']  = time();
+            $result = $mod_fav->addFavorites($insert_arr);
+
+            if ($result)
+            {
+                if($fav_type == 'goods') {
+                    $mod_goods = Model('goods');
+                    $mod_goods->editGoodsById(['goods_collect' => ['exp', 'goods_collect + 1']], [$fav_id]);
+                    $favorate = new user_session\favorite();
+                    $favorate->add('goods',$fav_id);
+                } else {
+                    $favorate = new user_session\favorite();
+                    $favorate->add('brand',$fav_id);
+                }
+                session_helper::clear_favorate();
+
+                return self::outsuccess(null);
+            } else {
+                return self::outerr(errcode::ErrParamter,"参数错误");
+            }
+        }
+    }
+
+    public function delOp()
+    {
+        $fav_id = intval($_POST['fav_id']);
+        $fav_type = $_POST['fav_type'];
+
+        if ($fav_id <= 0 || empty($fav_type) || !in_array($fav_type,self::$stTypes)) {
+            return self::outerr(errcode::ErrParamter,"参数错误");
+        }
+
+        $favorate = new user_session\favorite();
+        $favorate->del($fav_type,$fav_id);
+
+        $model_favorites = Model('favorites');
+        $ret = $model_favorites->delFavorites(['fav_id' => $fav_id,'fav_type' => $fav_type, 'member_id' => $_SESSION['member_id']]);
+        if($ret == false) {
+            return self::outerr(errcode::ErrParamter,"该收藏不存在或者已经被删除.");
+        }
+        else {
+            session_helper::clear_favorate();
+            return self::outsuccess(['fav_id' => $fav_id]);
+        }
+    }
+}

+ 155 - 0
mapi/control/member_fcode.php

@@ -0,0 +1,155 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/4/6
+ * Time: 下午1:42
+ */
+
+require_once (BASE_ROOT_PATH . '/helper/fcode/mfcode.php');
+require_once (BASE_ROOT_PATH . '/helper/fcode/operator.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/fcode.php');
+require_once (BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
+
+
+class member_fcodeControl extends mbMemberControl
+{
+    private $mFcodeBannerID;
+
+    public function __construct()
+    {
+        parent::__construct();
+        global $config;
+        $this->mFcodeBannerID = $config['autosend_fcodes']['myfcode_sid'];
+    }
+
+    public function listOp()
+    {
+        $mod_fcode = Model('goods_fcode');
+        $items = $mod_fcode->getFcodeList(array('mobile' => session_helper::mobile()),'*','fc_state asc,usable_time desc,fc_id asc',$this->page_size());
+        $page_count = $mod_fcode->gettotalpage();
+
+        if($this->page_no() == 1)
+        {
+            if(isset($_SESSION['fcodes'])) {
+                unset($_SESSION['fcodes']);
+            }
+        }
+
+        $fcodes = [];
+        $gids = [];
+
+        foreach ($items as $item)
+        {
+            $fcoder = new fcode\mfcode($item);
+            $fcode = $fcoder->format();
+            if($fcode != false) {
+                $gids[] = intval($fcode['goods_id']);
+                $fcodes[] = $fcode;
+            }
+        }
+
+        if(empty($fcodes))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'fcodes' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_count)));
+        }
+        else
+        {
+            if($this->page_no() == 1 && $this->mFcodeBannerID > 0)
+            {
+                $blocks = special_manager::instance()->special($this->mFcodeBannerID,$unused_gids);
+                $items = $this->format($fcodes);
+                $blocks = array_merge($blocks,$items);
+            }
+            else {
+                $blocks = $this->format($fcodes);
+            }
+
+            $helper = new goods_helper($this->price_calcer(),false);
+            $ret = $helper->cart_summary($gids,$related_goods);
+
+            return self::outsuccess(array('special_list' => $blocks,
+                'fcodes' => $fcodes,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page($page_count)));
+        }
+    }
+
+    private function format($fcodes)
+    {
+        $blocks = [];
+        if(!empty($fcodes)) {
+            $blocks[] = special_formater::def_divider();
+        }
+
+        foreach ($fcodes as $fcode)
+        {
+            $block = [];
+            $block['item_title'] = '';
+            $block['item_type'] = 'home1';
+            $block['scale'] = 3.224299;
+
+            $item['image'] = '';
+            $item['show_type'] = "fcode";
+            $item['show_data'] = strval($fcode['fcode_id']);
+            $item['type'] = "goods";
+            $item['data'] = strval($fcode['goods_id']);;
+            $item['title'] = '';
+
+            $block['items'][] = $item;
+            $blocks[] = $block;
+            $blocks[] = special_formater::def_divider();
+        }
+
+        return $blocks;
+    }
+
+    public function addOp()
+    {
+        $fc_code  = $_GET['fcode'];
+        $user_key = $_GET['key'];
+
+        if(empty($fc_code) || empty($user_key)) {
+            return self::outerr(errcode::ErrParamter,"参数错误,请输入正确的参数");
+        }
+
+        try
+        {
+            $fcode = new fcode\mfcode($fc_code);
+            if($fcode->locked()) {
+                return self::outerr(errcode::ErrParamter,"该F码处在锁定状态,不能添加.");
+            }
+            if($fcode->used()) {
+                return self::outerr(errcode::ErrParamter,"该F码已经使用过了,不能添加.");
+            }
+            if($fcode->expired()) {
+                return self::outerr(errcode::ErrParamter,"该F码已经过期,不能添加.");
+            }
+
+            if($fcode->user_key() != $user_key) {
+                return self::outerr(errcode::ErrParamter,"密钥不正确,可能输入错误或者已经被其他人占用.");
+            }
+
+            $oper = new fcode\operator($fcode->commonid(),$fcode->batch_code(),session_helper::mobile(),session_helper::session_id());
+            $oper->change($fcode->params());
+
+            $fcode = new user_session\fcode();
+            $fcode->onStatus();
+
+            return self::outsuccess(null);
+        }
+        catch (Exception $ex) {
+            return self::outerr(errcode::ErrParamter,"参数错误,没有此F码.");
+        }
+    }
+}

+ 50 - 0
mapi/control/member_feedback.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ * 我的反馈
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_feedbackControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function pageOp()
+    {
+        self::outsuccess(NULL,'shop/feedback','wap');
+    }
+    public function addOp()
+    {
+        $mb_feedback = Model('mb_feedback');
+
+        $param = array();
+        $param['content'] = urldecode($_POST['feedback']);
+        $param['type'] = $_SESSION['client_type'];
+        $param['ftime'] = time();
+
+        if($_SESSION['is_login'] == 1) {
+            $param['member_id'] = $_SESSION['member_id'];
+            $param['member_name'] = $_SESSION['member_name'];
+        } else {
+            $param['member_name'] = (isset($_GET['mobile']) && !empty($_GET['mobile'])) ? $_GET['mobile'] : '';
+        }
+
+        $result = $mb_feedback->addMbFeedback($param);
+
+        if ($result) {
+            self::outsuccess(NULL);
+        } else {
+            self::outerr('保存失败');
+        }
+    }
+}

+ 293 - 0
mapi/control/member_info.php

@@ -0,0 +1,293 @@
+<?php
+/**
+ * 获取用户信息
+ ***/
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_HELPER_PATH . '/text_filter.php');
+require_once(BASE_HELPER_PATH . '/FileUploader.php');
+require_once(BASE_HELPER_PATH . '/relation_helper.php');
+require_once(BASE_HELPER_PATH . '/util_helper.php');
+require_once(BASE_HELPER_PATH . '/url_helper.php');
+require_once(BASE_HELPER_PATH . '/mcard/mcard.php');
+require_once(BASE_RESOURCE_PATH . '/phpqrcode/index.php');
+
+
+class member_infoControl extends mbMemberControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    //个人中心页面的首页
+    public function indexOp()
+    {
+        $ret = $this->person_info();
+        self::outsuccess($ret);
+    }
+
+    public function getinfoOp()
+    {
+        $ret = $this->person_info();
+        self::outsuccess($ret);
+    }
+
+    public function getOp()
+    {
+        $ret = $this->person_info();
+        self::outsuccess($ret);
+    }
+
+    private function sub_titles()
+    {
+        $ret['qrcode'] = '扫上面的二维码图案,加我好友';
+
+        $addr_num = session_helper::address_num();
+        if($addr_num > 0) {
+            $ret['addr_num'] = "{$addr_num}个";
+        } else {
+            $ret['addr_num'] = "尚未设置";
+        }
+
+        $favorate_num = session_helper::favorate_num();
+        if($favorate_num > 0) {
+            $ret['favorate_num'] = "{$favorate_num}个";
+        } else {
+            $ret['favorate_num'] = "尚未收藏";
+        }
+
+        $fcode_num = session_helper::fcode_num();
+        if($fcode_num > 0) {
+            $ret['fcode_num'] = "{$fcode_num}个可用";
+        } else {
+            $ret['fcode_num'] = "没有F码";
+        }
+
+        $mod_bargain = Model('room_bargain');
+        $bargain_num = $mod_bargain->getBargainNumByUser(session_helper::memberid());
+        if($bargain_num > 0) {
+            $ret['bargain_num'] = "{$bargain_num}个砍价正在进行中";
+        } else {
+            $ret['bargain_num'] = "";
+        }
+
+        return $ret;
+    }
+
+    private function upfile($img,&$err)
+    {
+        $member_id = $_SESSION['member_id'];
+
+        $upload = new FileUploader();
+        if($upload->init_files($img,$member_id,$err) == false) {
+            return false;
+        }
+
+        $upload_dir = ATTACH_AVATAR.DS.$member_id.DS;
+        $upload->set('default_dir',$upload_dir.$upload->getSysSetPath());
+        $thumb_width	= '480,1024';
+        $thumb_height	= '480,1024';
+
+        $upload->set('max_size',C('image_max_filesize'));
+        $upload->set('thumb_width', $thumb_width);
+        $upload->set('thumb_height',$thumb_height);
+        $upload->set('fprefix',$member_id);
+        $upload->set('thumb_ext', '_240,_1024');
+        $result = $upload->upfile('file');
+        if($result == true) {
+            return $upload->file_name;
+        } else {
+            $err = ['code' => errcode::ErrUpfile, 'msg' => $upload->error];
+            return false;
+        }
+    }
+
+    private function file_path()
+    {
+        $file_path = $_POST["file_path"];
+        if(file_exists($file_path) == false) {
+            $file_path = BASE_ROOT_PATH . '/data/upload/upfile' . $file_path;
+        }
+        return $file_path;
+    }
+
+    public function upavatarOp()
+    {
+        $file_path = $this->file_path();
+        $member_id = $_SESSION['member_id'];
+        $file_name = $this->upfile($file_path,$err);
+        if($file_name == false) {
+            return self::outerr(errcode::ErrUploadFileFailed);
+        }
+        $file_path = DS.$member_id.DS.$file_name;
+        $ret = Model("member")->editMember(['member_id' => $member_id], ['member_avatar' => $file_path]);
+        if ($ret) {
+            $_SESSION['member_avatar'] = $file_path;
+            $url = UPLOAD_SITE_URL . "/shop/avatar{$file_path}";
+            return self::outsuccess(['member_avatar' => $url]);
+        } else {
+            return self::outerr(errcode::ErrDB);
+        }
+    }
+
+    public function upcontactsOp()
+    {
+        $contacts = session_helper::parse_contacts($_POST["contact_list"]);
+        if ($contacts == false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        relation_helper::onUpContacts($_SESSION['member_id'],$contacts);
+        return self::outsuccess(NULL);
+    }
+
+    public function updateinfoOp()
+    {
+        $this->editOp();
+    }
+
+    public function editOp()
+    {
+        $member_nickname = urldecode($_GET['nickname']);
+        $member_truename = urldecode($_GET['truename']);
+        $member_signname = urldecode($_GET['signname']);
+        $member_sex      = trim(urldecode($_GET['sex']));
+        $member_birthday = trim(urldecode(($_GET['birthday'])));
+
+        $update = [];
+        if (is_numeric($member_sex))
+        {
+            $iSex = intval($member_sex);
+            if($iSex == 0 || $iSex == 1) {
+                $update['member_sex'] = $member_sex;
+            }
+        }
+        if(isset($member_nickname) && !empty($member_nickname)) {
+            $member_nickname = text_filter::filter_input($member_nickname);
+            $update['member_nickname'] = $member_nickname;
+        }
+        if(isset($member_truename) && !empty($member_truename)) {
+            $member_truename = text_filter::filter_input($member_truename);
+            $update['member_truename'] = $member_truename;
+        }
+        if(isset($member_signname) && !empty($member_signname)) {
+            $member_signname = text_filter::filter_input($member_signname);
+            $update['member_signname'] = $member_signname;
+        }
+        if(isset($member_birthday))
+        {
+            $itm = intval($member_birthday);
+            if($itm > 0 && $member_birthday = strftime("%Y-%m-%d",$member_birthday)) {
+                $update['member_birthday'] = $member_birthday;
+            }
+        }
+        if(empty($update)) {
+            return self::outerr(errcode::ErrInputParam);
+        }
+
+        $mod = Model('member');
+        $ret = $mod->editMember(['member_id' => $_SESSION['member_id']],$update);
+        if($ret && $mod->affected_rows() > 0)
+        {
+            foreach($update as $key => $val) {
+                $_SESSION[$key] = $val;
+            }
+            self::outsuccess(['ret' => 1]);
+        }
+        else {
+            self::outsuccess(['ret' => 1]);
+        }
+    }
+
+    public function modifypassOp()
+    {
+        $oldpasswd = trim($_GET['oldpasswd']);
+        $newpasswd = trim($_GET['newpasswd']);
+
+        // 校验原有用户内容
+        $model = Model('member');
+        $oldpasswd = empty($oldpasswd) ? '' : md5($oldpasswd);
+        $newpasswd = empty($newpasswd) ? '' : md5($newpasswd);
+        $ret = $model->editMember(['member_id' => $_SESSION['member_id'],'member_passwd' => $oldpasswd],['member_passwd' => $newpasswd]);
+        if ($ret === false) {
+            return self::outerr(errcode::ErrPasswd);
+        } else {
+            return self::outsuccess(NULL);
+        }
+    }
+
+    public function qrcodeOp()
+    {
+        return self::outsuccess(['url' => session_helper::qrcode()]);
+    }
+
+    /**
+     * @return array
+     */
+    private function person_info(): array
+    {
+        $fields = ['member_sex', 'member_nickname', 'member_truename', 'member_signname', 'member_birthday', 'member_mobile', 'member_avatar'];
+        $ret = [];
+        foreach ($fields as $key)
+        {
+            if (array_key_exists($key, $_SESSION))
+            {
+                if ($key == 'member_birthday')
+                {
+                    $time = $_SESSION[$key];
+                    $birthday = strtotime($time);
+                    $ret[$key] = ($birthday == false) ? '0' : $birthday;
+                }
+                elseif ($key == 'member_avatar')
+                {
+                    $path = $_SESSION[$key];
+                    if (empty($path))
+                    {
+                        $ret['member_avatar'] = "";
+                    }
+                    elseif (util::ishttp($path))
+                    {
+                        $ret['member_avatar'] = $path;
+                    }
+                    else
+                    {
+                        $url = UPLOAD_SITE_URL . "/shop/avatar{$path}";
+                        $ret['member_avatar'] = $url;
+                    }
+                }
+                else
+                {
+                    $ret[$key] = $_SESSION[$key];
+                }
+            }
+        }
+        $ret['qrcode'] = session_helper::qrcode();
+        $ret['sub_titles'] = $this->sub_titles();
+        $ret['is_vip'] = session_helper::isVip();
+        $card_list =  mtopcard\priority_cards(session_helper::memberid());
+        $ret['cards'] = mtopcard\topcard_format($card_list);
+        $ret['mini_code'] = $this->mini_code();
+
+        $usercards = new mcard\user_mcards(session_helper::memberid());
+        $ret['vip_left_amount'] = $usercards->left_amount();
+
+        if ($ret['member_sex'] == 2) {
+            $ret['member_sex'] = 0;
+        }
+        return $ret;
+    }
+    private function mini_code()
+    {
+        $uid = session_helper::memberid();
+        $passwd = util::passwd;
+        $name = md5("{$uid}.{$passwd}") . ".png";
+        $save_path = BASE_UPLOAD_PATH . DS . ATTACH_MINI_QRCODE . DS . $name;
+        $url = UPLOAD_SITE_URL . DS . ATTACH_MINI_QRCODE . DS . $name;
+
+        if(!file_exists($save_path)) {
+            QueueClient::push('makeMemberMiniQrCode',['member_id' => $uid]);
+        }
+        return $url;
+    }
+}

+ 146 - 0
mapi/control/member_invitee.php

@@ -0,0 +1,146 @@
+<?php
+declare(strict_types=0);
+
+
+require_once(BASE_HELPER_PATH . '/model_helper.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
+
+
+class member_inviteeControl extends mbMemberControl
+{
+    public function listOp()
+    {
+        $mod_member = Model('member');
+        $items = $mod_member->getMemberList(['inviter_id' => session_helper::memberid()],'*', 0, 'member_time desc');
+
+        $result = [];
+        foreach ($items as $item)
+        {
+            $user_info = new member_info($item);
+            $result[] = $user_info->filter();
+        }
+
+        return self::outsuccess($result);
+    }
+
+    public static function comp_policy($left,$right)
+    {
+        $t_l = intval($left['num']);
+        $t_r = intval($right['num']);
+
+        if($t_l > $t_r) {
+            return 1;
+        }
+        elseif($t_l == $t_r)
+        {
+            return 0;
+        }
+        else {
+            return -1;
+        }
+    }
+
+    public function goods_shareOp()
+    {
+        $goods_id = intval($_GET['goods_id']);
+        if($goods_id <= 0) {
+            return self::outerr(errcode::ErrParamter,'goods_id 不能小于0.');
+        }
+        else
+        {
+            $calctor = new CalcPrice(session_helper::memberid());
+            $policy = $calctor->share_policy($goods_id);
+            if(empty($policy)) {
+                return self::outsuccess([]);
+            }
+
+            usort($policy,[__CLASS__,'comp_policy']);
+            [$policy,$maxnum,$amount] = $this->fill_policy($policy);
+            $result['policy'] = $policy;
+
+            $left_invitees = $calctor->left_invitees();
+            $invitees = [];
+
+            if($maxnum > $left_invitees) {
+                $result['tip_title'] = "邀请{$maxnum}好友,可以省{$amount}元";
+                $result['tip_num'] = $maxnum-$left_invitees;
+                $count = $left_invitees;
+            }
+            else {
+                $result['tip_title'] = "您已成功邀请{$maxnum}好友,下单即省{$amount}元";
+                $result['tip_num'] = 0;
+                $count = $maxnum;
+            }
+
+            if($left_invitees > 0)
+            {
+                $mod_member = Model('member');
+                $items = $mod_member->getMemberList(['inviter_id' => session_helper::memberid()],'*', 0, 'member_id desc',$left_invitees);
+                $items = array_reverse($items);
+
+                $index = 0;
+                foreach ($items as $item)
+                {
+                    try {
+                        if($index >= $count) break;
+                        $member = new member_info($item);
+                        $invitees[] = $member->filter();
+                        $index++;
+                    }
+                    catch (Exception $ex) {
+                        Log::record($ex->getMessage(),Log::ERR);
+                    }
+                }
+            }
+            $result['invitess'] = $invitees;
+            $result['mini_code'] = $this->mini_code();
+            $result['share_code'] = $this->share_code();
+
+            return self::outsuccess($result);
+        }
+    }
+
+    private function fill_policy($policy)
+    {
+        $index = 1;
+        foreach ($policy as $item)
+        {
+            for($end = $item['num']; $end > $index;$index++) {
+                $result[] = ['num' => $index,'discount' => 0];
+            }
+            $result[] = $item;
+            $index += 1;
+        }
+        return [$result,$item['num'],$item['discount']];
+    }
+
+    private function mini_code()
+    {
+        $uid = session_helper::memberid();
+        $passwd = util::passwd;
+        $name = md5("{$uid}.{$passwd}") . ".png";
+        $save_path = BASE_UPLOAD_PATH . DS . ATTACH_MINI_QRCODE . DS . $name;
+        $url = UPLOAD_SITE_URL . DS . ATTACH_MINI_QRCODE . DS . $name;
+
+        if(!file_exists($save_path)) {
+            QueueClient::push('makeMemberMiniQrCode',['member_id' => $uid]);
+            return '';
+        }
+        return $url;
+    }
+    private function share_code()
+    {
+        $uid = session_helper::memberid();
+        $passwd = util::passwd;
+        $name = md5("{$uid}.{$passwd}") . ".png";
+        $name = "share-{$name}";
+
+        $save_path = BASE_UPLOAD_PATH . DS . ATTACH_MINI_QRCODE . DS . $name;
+        $url = UPLOAD_SITE_URL . DS . ATTACH_MINI_QRCODE . DS . $name;
+
+        if(!file_exists($save_path)) {
+            QueueClient::push('makeMemberMiniQrCode',['member_id' => $uid]);
+        }
+        return $url;
+    }
+}

+ 125 - 0
mapi/control/member_invoice.php

@@ -0,0 +1,125 @@
+<?php
+/**
+ * 我的发票
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_invoiceControl extends mbMemberControl
+{
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 发票信息列表
+     */
+    public function invoice_listOp()
+    {
+        $model_invoice = Model('invoice');
+        $condition = array();
+        $condition['member_id'] = $_SESSION['member_id'];
+        $invoice_list = $model_invoice->getInvList($condition, 10, 'inv_id,inv_title,inv_content');
+        
+        return self::outsuccess(array('invoice_list' => $invoice_list));
+    }
+
+    /**
+     * 发票信息删除
+     */
+    public function invoice_delOp()
+    {
+        $inv_id = intval($_POST['inv_id']);
+        if ($inv_id <= 0) {
+            return self::outerr(errcode::ErrInvoice, '参数错误');
+        }
+
+        $model_invoice = Model('invoice');
+        $result = $model_invoice->delInv(array('inv_id' => $inv_id, 'member_id' => $_SESSION['member_id']));
+        if ($result) {
+            return self::outsuccess(array('result' => '1'));
+        } else {
+            return self::outerr(errcode::ErrInvoice, '删除失败');
+        }
+    }
+
+    /**
+     * 发票信息添加
+     */
+    public function invoice_addOp()
+    {
+        $model_invoice = Model('invoice');
+        $data = array();
+        $data['inv_state'] = 1;
+        $data['inv_title'] = $_POST['inv_title_select'] == 'person' ? '个人' : urldecode($_POST['inv_title']);
+        $data['inv_content'] = urldecode($_POST['inv_content']);
+        $data['member_id'] = $_SESSION['member_id'];
+        $result = $model_invoice->addInv($data);
+        if ($result) {
+            return self::outsuccess(array('inv_id' => $result));
+        } else {
+            return self::outerr(errcode::ErrInvoice, '添加失败');
+        }
+    }
+
+    /**
+     * 发票信息添加
+     */
+    public function invoice_editOp()
+    {
+        $model_invoice = Model('invoice');
+        $condition = array();
+        $condition['inv_id'] = $_POST['inv_id'];
+        $data = array();
+        $data['inv_title'] = urldecode($_POST['inv_title']);
+        $result = $model_invoice->editInv($condition, $data);
+        if ($result) {
+            return self::outsuccess(array('result' => 1));
+        } else {
+            return self::outerr(errcode::ErrInvoice, '添加失败');
+        }
+    }
+
+    /**
+     * 发票内容列表
+     */
+    public function invoice_content_listOp()
+    {
+        $token = trim($_GET['key']);
+        if (false == $this->checkToken($token)) {
+            return self::outerr($this->err_code);
+        }
+
+        $invoice_content_list = array(
+            '明细',
+            '酒',
+            '食品',
+            '饮料',
+            '玩具',
+            '日用品',
+            '装修材料',
+            '化妆品',
+            '办公用品',
+            '学生用品',
+            '家居用品',
+            '饰品',
+            '服装',
+            '箱包',
+            '精品',
+            '家电',
+            '劳防用品',
+            '耗材',
+            '电脑配件'
+        );
+        return self::outsuccess(array('invoice_content_list' => $invoice_content_list));
+    }
+}

+ 27 - 0
mapi/control/member_logout.php

@@ -0,0 +1,27 @@
+<?php
+/**
+ * 注销
+ *
+ *
+ *
+ *
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_logoutControl extends mbMemberControl
+{
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        session::instance()->destroy();
+        return self::outsuccess(NULL);
+    }
+}

+ 309 - 0
mapi/control/member_message.php

@@ -0,0 +1,309 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: james
+ * Date: 2017/4/21
+ * Time: 上午10:23
+ */
+
+class message_formater
+{
+    public function format($param)
+    {
+        $result = [];
+        $result['message_id'] = intval($param['message_id']);
+
+        $result['message_parent_id'] = intval($param['message_parent_id']);
+        $result['from_member_id'] = intval($param['from_member_id']);
+        $result['to_member_id'] = strval($param['to_member_id']);
+
+        $result['message_title'] = strval($param['message_title']);
+        $result['message_body'] = strval($param['message_body']);
+
+        $result['message_time'] = strval($param['message_time']);
+        $result['message_update_time'] = strval($param['message_update_time']);
+
+        $result['message_open'] = intval($param['message_open']);
+        $result['message_state'] = intval($param['message_state']);
+        $result['message_type'] = intval($param['message_type']);
+        $result['read_member_id'] = strval($param['read_member_id']);
+        $result['del_member_id'] = strval($param['del_member_id']);
+        $result['message_ismore'] = intval($param['message_ismore']);
+        $result['read_member_id'] = strval($param['read_member_id']);
+        $result['from_member_name'] = strval($param['from_member_name']);
+        $result['to_member_name'] = strval($param['to_member_name']);
+
+        return $result;
+    }
+}
+
+class member_messageControl extends mbMemberControl
+{
+    public function indexOp()
+    {
+
+    }
+
+    public function listOp()
+    {
+        $mod_message	= Model('message');
+        $items	= $mod_message->listMessage(array('message_type'=>'1','to_member_id_common'=>$_SESSION['member_id'],'no_message_state'=>'2'));
+
+        if (empty($items)) {
+            return self::outsuccess(null, 'nomessage');
+        }
+        else
+        {
+            $messages = [];
+            $messager = new message_formater();
+            foreach ($items as $item)
+            {
+                $messages[] = $messager->format($item);
+            }
+
+            $newnum = $this->countnewnum();
+            return self::outsuccess(array('newnum'=>$newnum, 'message_array'=>$messages));
+        }
+    }
+
+
+    public function systemmsgOp()
+    {
+        $model_message	= Model('message');
+        $message_array	= $model_message->listMessage(array('from_member_id'=>'0','message_type'=>'1','to_member_id'=>$_SESSION['member_id'],'no_del_member_id'=>$_SESSION['member_id']));
+        if (!empty($message_array) && is_array($message_array))
+        {
+            foreach ($message_array as $k=>$v)
+            {
+                $v['message_open'] = '0';
+                if (!empty($v['read_member_id'])){
+                    $tmp_readid_arr = explode(',',$v['read_member_id']);
+                    if (in_array($_SESSION['member_id'],$tmp_readid_arr)){
+                        $v['message_open'] = '1';
+                    }
+                }
+                $v['from_member_name'] = Language::get('home_message_system_message');
+                $message_array[$k]	= $v;
+            }
+            $message_array = array_slice($message_array, 0, 20);
+            $messages = [];
+            foreach ($message_array as $item)
+            {
+                $messager = new message_formater($item);
+                $message = $messager->format();
+                $messages[] = $message;
+            }
+
+            $newnum = intval($model_message->countNewMessage($_SESSION['member_id']));
+            return self::outsuccess($messages);
+        } else {
+            return self::outsuccess(null, 'nomessage');
+        }
+    }
+
+    public function showmsgbatchOp()
+    {
+        $model_message	= Model('message');
+        $message_id =  intval($_GET['message_id']);
+        $drop_type = trim($_GET['drop_type']);
+        $referer_url = getReferer();
+        if(!in_array($drop_type,array('msg_system','msg_seller')) || $message_id<=0){
+         //   showMessage(Language::get('wrong_argument'),$referer_url,'html','error');
+        }
+        //查询站内信
+        $param = array();
+        $param['message_id'] = "$message_id";
+        $param['to_member_id'] = "{$_SESSION['member_id']}";
+        $param['no_del_member_id'] = "{$_SESSION['member_id']}";
+        $message_info = $model_message->getRowMessage($param);
+        if (empty($message_info)){
+           // showMessage(Language::get('home_message_no_record'),$referer_url,'html','error');
+        }
+        if ($drop_type == 'msg_system'){
+            $message_info['from_member_name'] =  Language::get('home_message_system_message');
+        }
+//        if ($drop_type == 'msg_seller'){
+//            //查询店铺信息
+//            $model_store = Model('store');
+//            $store_info = $model_store->getStoreInfo(array('member_id'=>"{$message_info['from_member_id']}"));
+//            $message_info['from_member_name'] =  $store_info['store_name'];
+//            $message_info['store_id'] =  $store_info['store_id'];
+//        }
+        $message_list[0] = $message_info;
+        //    Tpl::output('message_list',$message_list);//站内信列表
+        //更新为已读信息
+        $tmp_readid_str = '';
+        if (!empty($message_info['read_member_id'])){
+            $tmp_readid_arr = explode(',',$message_info['read_member_id']);
+            if (!in_array($_SESSION['member_id'],$tmp_readid_arr)){
+                $tmp_readid_arr[] = $_SESSION['member_id'];
+            }
+            foreach ($tmp_readid_arr as $readid_k=>$readid_v){
+                if ($readid_v == ''){
+                    unset($tmp_readid_arr[$readid_k]);
+                }
+            }
+            $tmp_readid_arr = array_unique ($tmp_readid_arr);//去除相同
+            sort($tmp_readid_arr);//排序
+            $tmp_readid_str = ",".implode(',',$tmp_readid_arr).",";
+        }else {
+            $tmp_readid_str = ",{$_SESSION['member_id']},";
+        }
+        $model_message->updateCommonMessage(array('read_member_id'=>$tmp_readid_str),array('message_id'=>"{$message_id}"));
+        //更新未读站内信数量cookie值
+        //   $cookie_name = 'msgnewnum'.$_SESSION['member_id'];
+        //   $countnum = $model_message->countNewMessage($_SESSION['member_id']);
+        //    setNcCookie($cookie_name,$countnum,2*3600);//保存2小时
+        //   Tpl::output('message_num',$countnum);
+
+        // 新消息数量
+        $newnum = $this->countnewnum();
+        return self::outsuccess(array('message_list'=>$message_list, 'newnum' => $newnum));
+
+        // Tpl::output('drop_type',$drop_type);
+        //  $this->profile_menu('showmsg');
+        //  Tpl::showpage('member_message.view');
+    }
+
+    /**
+     * 删除普通信
+     */
+    public function dropcommonmsgOp() {
+        $message_id = trim($_GET['message_id']);
+        $drop_type = trim($_GET['drop_type']);
+        if(!in_array($drop_type,array('msg_private','msg_list','sns_msg')) || empty($message_id)) {
+            showMessage(Language::get('wrong_argument'),'','html','error');
+        }
+        $messageid_arr = explode(',',$message_id);
+        $messageid_str = '';
+        if (!empty($messageid_arr)){
+            $messageid_str = "'".implode("','",$messageid_arr)."'";
+        }
+        $model_message	= Model('message');
+        $param	= array('message_id_in'=>$messageid_str);
+        if($drop_type == 'msg_private'){
+            $param['from_member_id'] = "{$_SESSION['member_id']}";
+        }elseif($drop_type == 'msg_list'){
+            $param['to_member_id_common']	= "{$_SESSION['member_id']}";
+        }elseif($drop_type == 'sns_msg'){
+            $param['from_to_member_id']	= $_SESSION['member_id'];
+        }
+        $drop_state	= $model_message->dropCommonMessage($param,$drop_type);
+        if ($drop_state){
+            //更新未读站内信数量cookie值
+            $cookie_name = 'msgnewnum'.$_SESSION['member_id'];
+            $countnum = $model_message->countNewMessage($_SESSION['member_id']);
+            setNcCookie($cookie_name,$countnum,2*3600);//保存2小时
+            showDialog(Language::get('home_message_delete_success'),'reload','succ');
+        }else {
+            showDialog(Language::get('home_message_delete_fail'),'','error');
+        }
+    }
+    /**
+     * 删除批量站内信
+     */
+    public function dropbatchmsgOp() {
+        $message_id = trim($_GET['message_id']);
+        $drop_type = trim($_GET['drop_type']);
+        if(!in_array($drop_type,array('msg_system','msg_seller')) || empty($message_id)){
+            // showDialog(Language::get('home_message_delete_request_wrong'));
+            self::outerr('home_message_delete_request_wrong');
+        }
+        $messageid_arr = explode(',',$message_id);
+        $messageid_str = '';
+        if (!empty($messageid_arr)){
+            $messageid_str = "'".implode("','",$messageid_arr)."'";
+        }
+        $model_message	= Model('message');
+        $param	= array('message_id_in'=>$messageid_str);
+        if($drop_type == 'msg_system'){
+            $param['message_type'] = '1';
+            $param['from_member_id'] = '0';
+        }
+        if($drop_type == 'msg_seller'){
+            $param['message_type'] = '2';
+        }
+        $drop_state	= $model_message->dropBatchMessage($param,$_SESSION['member_id']);
+        if ($drop_state){
+            //更新未读站内信数量cookie值
+            //  $cookie_name = 'msgnewnum'.$_SESSION['member_id'];
+            $countnum = $model_message->countNewMessage($_SESSION['member_id']);
+            return self::outsuccess(array('drop_state'=>true, 'newnum' => $countnum));
+            //  setNcCookie($cookie_name,$countnum,2*3600);//保存2小时
+            // showDialog(Language::get('home_message_delete_success'),'reload','succ');
+        }else {
+            return self::outerr(array('drop_state' => false));
+        }
+    }
+
+    public function settingOp() {
+        $model_membermsgsetting = Model('member_msg_setting');
+        if (chksubmit())
+        {
+            $insert = array(
+                // 付款成功提醒
+                array( 'mmt_code' => 'order_payment_success', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['order_payment_success']) ),
+                // 商品出库提醒
+                array( 'mmt_code' => 'order_deliver_success', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['order_deliver_success']) ),
+                // 余额变动提醒
+                array( 'mmt_code' => 'predeposit_change', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['predeposit_change']) ),
+                // 充值卡余额变动提醒
+                array( 'mmt_code' => 'recharge_card_balance_change', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['recharge_card_balance_change']) ),
+                // 代金券使用提醒
+                array( 'mmt_code' => 'voucher_use', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['voucher_use']) ),
+                // 退款退货提醒
+                array( 'mmt_code' => 'refund_return_notice', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['refund_return_notice']) ),
+                // 到货通知提醒
+                array( 'mmt_code' => 'arrival_notice', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['arrival_notice']) ),
+                // 商品咨询回复提醒
+                array( 'mmt_code' => 'consult_goods_reply', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['consult_goods_reply']) ),
+                // 平台客服回复提醒
+                array( 'mmt_code' => 'consult_mall_reply', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['consult_mall_reply']) ),
+                // 代金券即将到期
+                array( 'mmt_code' => 'voucher_will_expire', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['voucher_will_expire'])),
+                // 兑换码即将到期提醒
+                array( 'mmt_code' => 'vr_code_will_expire', 'member_id' => $_SESSION['member_id'], 'is_receive' => intval($_POST['vr_code_will_expire'])),
+            );
+            $result = $model_membermsgsetting->addMemberMsgSettingAll($insert);
+            if ($result) {
+                self::outsuccess(array('set_mess' => true));
+            } else {
+                self::outerr(array('set_mess'=>false));
+            }
+        }
+        // 新消息数量
+        $newnum = $this->countnewnum();
+
+        $setting_list = $model_membermsgsetting->getMemberMsgSettingList(array('member_id' => $_SESSION['member_id']));
+        $setting_array = array();
+        if (!empty($setting_list)) {
+            foreach ($setting_list as $val) {
+                $setting_array[$val['mmt_code']] = intval($val['is_receive']);
+            }
+        }
+        return self::outsuccess(array('setting_array'=>$setting_array, 'newnum'=>$newnum));
+    }
+
+    private function countnewnum()
+    {
+        $num = [];
+        $num['system'] = $this->countNsystem();
+        return $num;
+    }
+
+    private function countNsystem()
+    {
+        $mod = Model('message');
+        $con = [];
+        $con['message_type'] = '1';
+        $con['to_member_id'] = $_SESSION['member_id'];
+        $con['no_del_member_id'] = $_SESSION['member_id'];
+        $con['no_read_member_id'] = $_SESSION['member_id'];
+        $countnum = $mod->countMessage($con);
+        return $countnum;
+    }
+
+
+
+
+}

+ 114 - 0
mapi/control/member_notice.php

@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/4/2
+ * Time: 下午6:31
+ */
+require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/anotice.php');
+
+class member_noticeControl extends mbMemberControl
+{
+    public function indexOp()
+    {
+        $mod_anotice = Model('arrival_notice');
+        $notices = $mod_anotice->getArrivalNoticeList(array('member_id' => $_SESSION['member_id']));
+        if(empty($notices))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        }
+        else
+        {
+            $gids = [];
+            foreach ($notices as $notice) {
+                $gids[] = intval($notice['goods_id']);
+            }
+            $model_goods = Model('goods');
+            $goods_list = $model_goods->getGoodsListByColorDistinct(array('goods_id' => array('in',$gids)),goods_helper::fieldstr);
+            $page_count = $mod_anotice->gettotalpage();
+
+            $helper = new goods_helper($this->price_calcer());
+            $ret = $helper->summary($goods_list,$related_goods);
+
+            $block = special_formater::format_goods($gids,"",$ret['sort_summary']);
+            $blocks[] = $block;
+
+            return self::outsuccess(array('special_list' => $blocks,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page($page_count)));
+        }
+    }
+
+    public function addOp()
+    {
+        $goods_id = $_POST['goods_id'];
+        if ($goods_id <= 0) {
+            return self::outerr(errcode::ErrParamter,"请输入正确的参数.");
+        }
+
+        $goods_info = Model('goods')->getGoodsInfoByID($goods_id, 'goods_id,goods_name,goods_storage,goods_state');
+        if (empty($goods_info)) {
+            return self::outerr(errcode::ErrParamter,"该商品不存在.");
+        }
+        if($goods_info['goods_storage'] > 0 && $goods_info['goods_state'] == 1) {
+            return self::outerr(errcode::ErrParamter,"该商品还有库存,不能添加通知提醒.");
+        }
+
+
+        $type = intval($goods_info['is_appoint']) == 1 ? 2 : 1;
+
+        $mod_anotice = Model('arrival_notice');
+        $where = array();
+        $where['goods_id'] = $goods_info['goods_id'];
+        $where['member_id'] = $_SESSION['member_id'];
+        $where['an_type'] = $type;
+        $notice_info = $mod_anotice->getArrivalNoticeInfo($where);
+
+        if(empty($notice_info))
+        {
+            $insert = array();
+            $insert['goods_id'] = $goods_info['goods_id'];
+            $insert['goods_name'] = $goods_info['goods_name'];
+            $insert['member_id'] = $_SESSION['member_id'];
+            $insert['an_mobile'] = $_SESSION['member_mobile'];
+            $insert['an_type'] = $type;
+            $ret = $mod_anotice->addArrivalNotice($insert);
+            if($ret == false) {
+                Log::record("goods_common arrival_notice error.",Log::ERR);
+            }
+            $anotice  = new user_session\anotice();
+            $anotice->add($goods_info['goods_id']);
+        }
+
+        return self::outsuccess(array('goods_id' => $goods_id));
+    }
+    public function delOp()
+    {
+        $goods_id = $_POST['goods_id'];
+        if ($goods_id <= 0) {
+            return self::outerr(errcode::ErrParamter,"请输入正确的参数.");
+        }
+
+        $mod_anotice = Model('arrival_notice');
+        $ret = $mod_anotice->delArrivalNotice(array('goods_id' => $goods_id,'member_id' => $_SESSION['member_id']));
+        $anotice  = new user_session\anotice();
+        $anotice->del($goods_id);
+
+        if($ret == false) {
+            Log::record("{$_SESSION['member_id']} del arraval notice $goods_id = {$goods_id} faile",Log::ERR);
+        }
+
+        return self::outsuccess(array('goods_id' => $goods_id));
+    }
+}

+ 435 - 0
mapi/control/member_order.php

@@ -0,0 +1,435 @@
+<?php
+/**
+ * 我的订单
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/kdn_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/order_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/pay_helper.php');
+
+class member_orderControl extends mbMemberControl
+{
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function listOp()
+    {
+        $model_order = Model('order');
+        $condition = [];
+        $condition['buyer_id'] = $_SESSION['member_id'];
+
+        $order_state = intval(trim($_GET['state']));
+        if ($order_state >= 10) {
+            $condition['order_state'] = $order_state;
+        }
+
+        if ($_GET['state_type'] != '') {
+            $condition['order_state'] = str_replace(
+                ['state_new','state_pay','state_send','state_success','state_noeval'],
+                [ORDER_STATE_NEW,ORDER_STATE_PAY,ORDER_STATE_SEND,ORDER_STATE_SUCCESS], $_GET['state_type']);
+        } else {
+            $condition['order_state'] = ["in", [ORDER_STATE_NEW,ORDER_STATE_PAY,ORDER_STATE_SEND,ORDER_STATE_SUCCESS,ORDER_STATE_CANCEL]];
+        }
+
+        $order_list_array = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '', ['order_common','order_address', 'order_goods']);
+        $page_count = $model_order->gettotalpage();
+
+        $order_helper = new order_helper($order_list_array);
+        $result = $order_helper->format();
+
+        return self::outsuccess(['orders' => $result,'mobile_page' =>mobile_page($page_count)]);
+    }
+
+    public function infoOp()
+    {
+        $pay_sn = $_POST['pay_sn'];
+        if(empty($pay_sn)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $order = $this->get_order(["buyer_id" => $_SESSION['member_id'],'pay_sn' => $pay_sn]);
+        if($order == false) {
+            return self::outerr(errcode::ErrOrder);
+        } else {
+            return self::outsuccess(['order' => $order]);
+        }
+    }
+
+    public function pay_infoOp()
+    {
+        $pay_sn = $_POST['pay_sn'];
+        if(empty($pay_sn)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $order = $this->get_order(["buyer_id" => $_SESSION['member_id'],'pay_sn' => $pay_sn]);
+        $pay_ments = pay_helper::pay_types();
+        if($order == false) {
+            return self::outerr(errcode::ErrOrder);
+        } else {
+            return self::outsuccess(['order' => $order,"paytype" => $pay_ments]);
+        }
+    }
+
+    public function change_stateOp()
+    {
+        $act_type = $_GET['act_type'];
+        $order_id = intval($_POST['order_id']);
+
+        $state_type = $this->state_type($act_type);
+        if($state_type == false || $order_id <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $action = new order_action();
+        $fOk = $action->change_state($state_type,$order_id);
+
+        if($fOk == true)
+        {
+            $order = $this->get_order(["buyer_id" => $_SESSION['member_id'],'order_id' => $order_id]);
+            if($order == false) {
+                $order = null;
+            }
+
+            return self::outsuccess(["act_type" => $act_type,"order_id" => $order_id, "order" => $order]);
+        }
+        else {
+            return self::outerr(errcode::ErrOrder);
+        }
+    }
+
+    private function state_type($act_type)
+    {
+        if($act_type == "if_cancel")  return "order_cancel";
+        if($act_type == "if_delete")  return "order_delete";
+        if($act_type == "if_receive") return "order_receive";
+        return false;
+    }
+
+    private function get_order($condition)
+    {
+        $model_order = Model('order');
+        $order_list = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '',
+            ['order_common','order_address', 'order_goods']);
+        $order_helper = new order_helper($order_list);
+        $orders = $order_helper->format();
+        $model_order->cls();
+        if(!empty($orders)) {
+            return $orders[0];
+        } else {
+            return false;
+        }
+    }
+
+    public function payOp()
+    {
+        $pay_sn = $_GET['pay_sn'];
+        $payment = $_GET['payment'];
+        if(empty($pay_sn) || empty($payment)) {
+            return self::outerr(errcode::ErrParamter,"支付号或者支付类型错误");
+        }
+
+        $payer = new pay_helper($pay_sn);
+        $out_put = $payer->pay($payment,$err);
+
+        if($out_put == false) {
+            return self::outerr($err['code'],$err['msg']);
+        } else {
+            $out_put['payment'] = $payment;
+            $out_put['pay_sn']  = $pay_sn;
+            return self::outsuccess($out_put);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////下面是老接口///////////////////////////////////////////////////////////////////////////
+    public function order_listOp()
+    {
+        $this->page_size = 1000;
+        $model_order = Model('order');
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $order_state = intval(trim($_GET['state']));
+        if ($order_state >= 10) {
+            $condition['order_state'] = $order_state;
+        }
+
+        $order_list_array = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '', array('order_address', 'order_goods'));
+        $order_group_list = array();
+        $order_pay_sn_array = array();
+
+        $model_refund = Model('refund_return');
+
+        foreach ($order_list_array as $value) 
+        {
+            //显示取消订单
+            $value['if_cancel'] = $model_order->getOrderOperateState('buyer_cancel', $value);
+            //显示收货
+            $value['if_receive'] = $model_order->getOrderOperateState('receive', $value);
+            //显示锁定中
+            $value['if_lock'] = $model_order->getOrderOperateState('lock', $value);
+            //显示物流跟踪
+            $value['if_deliver'] = $model_order->getOrderOperateState('deliver', $value);
+            //订单是否能退货
+            $value['if_refund_return'] = $model_refund->getRefundState($value);
+
+            //商品图
+            foreach ($value['extend_order_goods'] as $k => $goods_info) {
+                $value['extend_order_goods'][$k]['goods_image_url'] = cthumb($goods_info['goods_image'], 240, $value['store_id']);
+                $value['extend_order_goods'][$k]['refund_id']       = (string)$model_refund->getRefundIdForGood($goods_info,$value['extend_order_goods'][$k]['refund_state']);
+            }
+
+            $value['refund_id'] = (string)$model_refund->getRefundId($value,$value['refund_state']);
+            $order_group_list[$value['pay_sn']]['order_list'][] = $value;
+
+            //如果有在线支付且未付款的订单则显示合并付款链接
+            if ($value['order_state'] == ORDER_STATE_NEW) {
+                $order_group_list[$value['pay_sn']]['pay_amount'] += $value['order_amount'] - $value['rcb_amount'] - $value['pd_amount'];
+            }
+            $order_group_list[$value['pay_sn']]['add_time'] = $value['add_time'];
+
+            //记录一下pay_sn,后面需要查询支付单表
+            $order_pay_sn_array[] = $value['pay_sn'];
+        }
+
+        $new_order_group_list = array();
+        foreach ($order_group_list as $key => $value) {
+            $value['pay_sn'] = strval($key);
+            $new_order_group_list[] = $value;
+        }
+
+        $page_count = $model_order->gettotalpage();
+        $model_order->cls();
+
+        $array_data = array('order_group_list' => $new_order_group_list);
+        if (isset($_GET['getpayment']) && $_GET['getpayment'] == "true") 
+        {
+            $model_mb_payment = Model('mb_payment');
+            $payment_list = $model_mb_payment->getMbPaymentOpenList();
+            $payment_array = array();
+            if (!empty($payment_list)) 
+            {
+                foreach ($payment_list as $value) {
+                    $payment_array[] = ['payment_code' => $value['payment_code'], 'payment_name' => $value['payment_name']];
+                }
+            }
+            $array_data['payment_list'] = $payment_array;
+        }
+
+        $array_data['mobile_page'] = mobile_page($page_count);
+        self::outsuccess($array_data);
+    }
+
+    public function order_infoOp()
+    {
+        $model_order = Model('order');
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $condition['pay_sn'] = $_POST['pay_sn'];
+        $order_list_array = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '', array('order_address', 'order_goods'));
+
+        $model_refund = Model('refund_return');
+        $array_data = array();
+        foreach ($order_list_array as $value)
+        {
+            //显示取消订单
+            $value['if_cancel'] = $model_order->getOrderOperateState('buyer_cancel', $value);
+            //显示收货
+            $value['if_receive'] = $model_order->getOrderOperateState('receive', $value);
+            //显示锁定中
+            $value['if_lock'] = $model_order->getOrderOperateState('lock', $value);
+            //显示物流跟踪
+            $value['if_deliver'] = $model_order->getOrderOperateState('deliver', $value);
+
+            foreach ($value['extend_order_goods'] as $k => $goods_info) {
+                $value['extend_order_goods'][$k]['goods_image_url'] = cthumb($goods_info['goods_image'], 240, $value['store_id']);
+                $value['extend_order_goods'][$k]['refund_id']       = (string)$model_refund->getRefundIdForGood($goods_info,$value['extend_order_goods'][$k]['refund_state']);
+            }
+            $value['refund_id'] = (string)$model_refund->getRefundId($value,$value['refund_state']);
+            $array_data[] = $value;
+        }
+
+        self::outsuccess(array("order_list" => $array_data));
+    }
+
+    /**
+     * 取消订单
+     */
+    public function order_cancelOp()
+    {
+        $condition = array();
+        if (!empty($_POST['order_id'])) {
+            $order_id = intval($_POST['order_id']);
+            $condition['order_id'] = $order_id;
+        } elseif (!empty($_POST['order_sn'])) {
+            $condition['order_sn'] = trim($_POST['order_sn']);
+        } else {
+            return self::outerr(errcode::ErrParamter, "请传入order_sn.");
+        }
+
+        $model_order = Model('order');
+        $logic_order = Logic('order');
+
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        Log::record("buyer_id = {$condition['buyer_id']}", Log::DEBUG);
+
+        $order_info = $model_order->getOrderInfo($condition);
+        if ($order_info['order_state'] != ORDER_STATE_NEW) {
+            Log::record("order_state = {$order_info['order_state']}.", Log::ERR);
+            return self::outerr(errcode::ErrOrder, "已支付和已发货订单不能取消.");
+        }
+
+        if ($order_info['order_state'] == ORDER_STATE_CANCEL) {
+            return self::outsuccess(array('result' => '1'));
+        }
+
+        $result = $logic_order->changeOrderStateCancel($order_info, 'buyer', $_SESSION['member_name'], '其它原因');
+        if (!$result['state']) {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        } else {
+            return self::outsuccess(array('result' => '1'));
+        }
+    }
+
+    /**
+     * 订单确认收货
+     */
+    public function order_receiveOp()
+    {
+        $model_order = Model('order');
+        $order_id = intval($_POST['order_id']);
+
+        $condition = array();
+        $condition['order_id'] = $order_id;
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $order_info = $model_order->getOrderInfo($condition);
+        $if_allow = $model_order->getOrderOperateState('receive', $order_info);
+        if (!$if_allow) {
+            return self::outerr(errcode::ErrOrder, '无权操作');
+        }
+
+        $logic_order = Logic('order');
+        $result = $logic_order->changeOrderStateReceive($order_info, 'buyer', $_SESSION['member_name']);
+        if (!$result['state']) {
+            return self::outerr(errcode::ErrOrder, $result['msg']);
+        } else {
+            return self::outsuccess(array('result' => '1'));
+        }
+    }
+
+    /**
+     * 物流跟踪
+     */
+    public function search_deliverOp()
+    {
+        $order_id = intval($_POST['order_id']);
+        if ($order_id <= 0) {
+            return self::outsuccess(NULL,'express/error','wap');
+        }
+
+        $model_order = Model('order');
+        $condition['order_id'] = $order_id;
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $order_info = $model_order->getOrderInfo($condition, array('order_common', 'order_goods'));
+
+        if (empty($order_info) || !in_array($order_info['order_state'], array(ORDER_STATE_SEND, ORDER_STATE_SUCCESS))) {
+            return self::outsuccess(NULL,'express/error','wap');
+        }
+
+        $express = rkcache('express', true);
+        $e_code = $express[$order_info['extend_order_common']['shipping_express_id']]['e_kdn_code'];
+        $e_name = $express[$order_info['extend_order_common']['shipping_express_id']]['e_name'];
+
+        $key = "express_{$e_code}_" . $order_info['shipping_code'];
+        $deliver_info = rkcache($key);
+        if (empty($deliver_info))
+        {
+            $deliver_info = kdn_helper::query($e_code, $order_info['shipping_code']);
+            if ($deliver_info === false || empty($deliver_info)) {
+                return self::outsuccess(NULL,'express/error','wap');
+            }
+            $deliver_info = json_decode(urldecode($deliver_info), true);
+            wkcache($key, $deliver_info, 3600);
+        }
+
+        $routes = $deliver_info['Traces'];
+        krsort($routes);
+        switch ($deliver_info['State'])
+        {
+            case '2':
+                $msg = '在途中';
+                break;
+            case '3':
+                $msg = '已签收';
+                break;
+            case '4':
+                $msg = '问题件';
+                break;
+            default: {
+                return self::outsuccess(NULL,'express/error','wap');
+            }
+        }
+        $outdatas = array('query_status' => true,
+            'msg_statu' => $msg,'LogisticCode' => $deliver_info['LogisticCode'],'shipper_namer' => $e_name,
+            'routes' => $routes);
+        return self::outsuccess($outdatas,'express/info','wap');
+    }
+
+    /**
+     * 获取不同状态下订单数量
+     */
+    public function orderCountStateOp()
+    {
+        $result = [];
+        $all = 0;
+
+        $items = Model()->table('order')->field('order_state, count(*) as count')->where(array('buyer_id' => $_SESSION['member_id'],'delete_state' => 0))->group('order_state')->select();
+        foreach ($items as $item)
+        {
+            $state = $item['order_state'];
+            $count = intval($item['count']);
+            if($state == '10') {
+                $val = ['count' => $count,'order_state' => '10'];
+                $all += $count;
+            }
+            elseif($state == '20') {
+                $val = ['count' => $count,'order_state' => '20'];
+                $all += $count;
+            }
+            elseif($state == '30') {
+                $val = ['count' => $count,'order_state' => '30'];
+                $all += $count;
+            }
+            elseif($state == '40') {
+                $all += $count;
+                continue;
+            }
+            else {
+                continue;
+            }
+
+            $result[] = $val;
+        }
+        $result[] = ['order_state' => '0','count' => $all];
+
+        //待评价
+        $ev_items = Model()->table('order')->field('order_state, count(*) as count')
+            ->where(['buyer_id' => $_SESSION['member_id'],'delete_state' => 0,'order_state' => ORDER_STATE_SUCCESS, 'evaluation_state' => 0])
+            ->group('order_state')->select();
+        if(!empty($ev_items)) {
+            $result[] = ['order_state' => '40','count' => intval($ev_items[0]['count'])];
+        }
+
+        $ret_count = Model('refund_return')->getRefundReturn(array('buyer_id' => $_SESSION['member_id']));
+        $result[] = ['order_state' => 'refund_return','count' => strval($ret_count)];
+
+        self::outsuccess(['order_count' => $result]);
+    }
+}

+ 116 - 0
mapi/control/member_payment.php

@@ -0,0 +1,116 @@
+<?php
+/**
+ * 支付
+ *
+ *
+ *
+ *
+ * by 33hao.com 好商城V3 运营版
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_paymentControl extends mbMemberControl
+{
+
+    private $payment_code = 'alipay';
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->payment_code = isset($_GET['payment_code']) && trim($_GET['payment_code']) != '' ? trim($_GET['payment_code']) : 'alipay';
+    }
+
+    /**
+     * 实物订单支付
+     */
+    public function payOp()
+    {
+        $pay_sn = $_GET['pay_sn'];
+        $model_mb_payment = Model('mb_payment');
+        $logic_payment = Logic('payment');
+        $condition = array();
+        $condition['payment_code'] = $this->payment_code;
+        $mb_payment_info = $model_mb_payment->getMbPaymentOpenInfo($condition);
+        if (!$mb_payment_info) {
+            output_error('系统不支持选定的支付方式');
+        }
+        //重新计算所需支付金额
+        $result = $logic_payment->getRealOrderInfo($pay_sn, $_SESSION['member_id']);
+        if (!$result['state']) {
+            output_error($result['msg']);
+        }
+        //第三方API支付
+        $this->_api_pay($result['data'], $mb_payment_info);
+    }
+
+    /**
+     * 虚拟订单支付
+     */
+    public function vr_payOp()
+    {
+        $order_sn = $_GET['pay_sn'];
+        $model_mb_payment = Model('mb_payment');
+        $logic_payment = Logic('payment');
+        $condition = array();
+        $condition['payment_code'] = $this->payment_code;
+        $mb_payment_info = $model_mb_payment->getMbPaymentOpenInfo($condition);
+        if (!$mb_payment_info) {
+            output_error('系统不支持选定的支付方式');
+        }
+        //重新计算所需支付金额
+        $result = $logic_payment->getVrOrderInfo($order_sn, $_SESSION['member_id']);
+
+        if (!$result['state']) {
+            output_error($result['msg']);
+        }
+        //第三方API支付
+        $this->_api_pay($result['data'], $mb_payment_info);
+    }
+
+    /**
+     * 第三方在线支付接口
+     *
+     */
+    private function _api_pay($order_pay_info, $payment_info)
+    {
+        $inc_file = BASE_PATH . DS . 'api' . DS . 'payment' . DS . $this->payment_code . DS . $this->payment_code . '.php';
+        if (!is_file($inc_file)) {
+            output_error('支付接口不存在');
+        }
+        if ($payment_info['payment_code'] == 'wxpay') {
+            $wxpayurl = BASE_SITE_URL . '/mobile/api/payment/wxpay/wxpay.php?pay_sn=' . $order_pay_info['pay_sn'] . '&pay_amount=' . $order_pay_info['api_pay_amount'];
+            redirect($wxpayurl);
+            //@header("Location: ".ApiUrl.'/api/paymentpaypay.php?pay_sn='.$order_pay_info['pay_sn'].'&pay_amount='.$order_pay_info['api_pay_amount']);
+        } else {
+            require($inc_file);
+            $param = array();
+            $param = $payment_info['payment_config'];
+            $param['order_sn'] = $order_pay_info['pay_sn'];
+            $param['order_amount'] = $order_pay_info['api_pay_amount'];
+            $param['order_type'] = ($order_pay_info['order_type'] == 'real_order' ? 'r' : 'v');
+            $payment_api = new $this->payment_code();
+            $return = $payment_api->submit($param);
+            echo $return;
+        }
+        exit();
+    }
+
+    /**
+     * 获取可用参数列表
+     */
+    public function payment_listOp()
+    {
+        $model_mb_payment = Model('mb_payment');
+        $payment_list = $model_mb_payment->getMbPaymentOpenList();
+        $payment_array = array();
+        if (!empty($payment_list)) {
+            foreach ($payment_list as $value) {
+                $payment_array[] = $value['payment_code'];
+            }
+        }
+        output_data(array('payment_list' => $payment_array));
+    }
+}

+ 473 - 0
mapi/control/member_refund.php

@@ -0,0 +1,473 @@
+<?php
+/**
+ * 会员退款退货
+ *
+ *
+ *
+ * 全部退款,单个商品退货
+ *
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/order_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/fcode/operator.php');
+require_once (BASE_ROOT_PATH . '/helper/fcode/send_manager.php');
+require_once (BASE_ROOT_PATH . '/helper/user_session/fcode.php');
+
+class member_refundControl extends mbMemberControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function listOp()
+    {
+        $helper = new refund_helper($_SESSION['member_id']);
+        $refund_list = $helper->list_all($this->page_size(),$total_page);
+        return self::outsuccess(array('refunds' => $refund_list,'mobile_page' => mobile_page($total_page)));
+    }
+
+    public function viewOp()
+    {
+        $refund_id = $_GET['refund_id'];
+        if (!isset($refund_id)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $helper = new refund_helper($_SESSION['member_id']);
+        $refund = $helper->view($refund_id,$err);
+        if($refund == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else
+        {
+            $order = $this->get_order(array('order_id' => $refund['order_id'],'buyer_id' => $_SESSION['member_id']));
+
+            if($order == false) {
+                return self::outerr(errcode::ErrParamter,"查不到该订单");
+            } else {
+                global $config;
+                return self::outsuccess(array('refund' => $refund,'order' => $order,'return_address' => $config['return_address']));
+            }
+        }
+    }
+
+    public function order_refundOp()
+    {
+        $order_sn = $_GET['order_sn'];
+        if(!isset($order_sn) || empty($order_sn)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $helper = new refund_helper($_SESSION['member_id']);
+        $refund_id = $helper->refund($order_sn,$err);
+        if($refund_id == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else
+        {
+            $fcode = new user_session\fcode(true);
+            $order = $this->get_order(array('order_sn' =>$order_sn,'buyer_id' => $_SESSION['member_id']));
+            if($order == false) {
+                return self::outerr(errcode::ErrParamter,"查不到该订单");
+            } else {
+                Logic('delivery')->cancel_order($order_sn);
+                return self::outsuccess(array('order' => $order));
+            }
+        }
+    }
+
+    public function return_infoOp()
+    {
+        $order_sn = $_GET['order_sn'];
+        $rec_id = intval($_GET['rec_id']);
+        if(empty($order_sn) || $rec_id <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $helper = new refund_helper($_SESSION['member_id']);
+        $ret = $helper->return_info($order_sn,$rec_id,$err);
+        if($ret == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else
+        {
+            $reason_list = $ret['reason_list'];
+            $goods_pay_price = doubleval($ret['goods']['goods_pay_price']);
+            $order = $this->get_order(array('order_sn' =>$order_sn,'buyer_id' => $_SESSION['member_id']));
+            if ($order != false)
+            {
+                $order_goods = &$order['order_goods'];
+                foreach ($order_goods as &$item)
+                {
+                    if($item['rec_id'] == $rec_id) {
+                        $item['goods_pay_price'] = $goods_pay_price;
+                        break;
+                    }
+                }
+                return self::outsuccess(array("reason_list" => $reason_list,'rec_id' => $rec_id,'order' => $order));
+            }
+            else
+            {
+                return self::outerr(errcode::ErrParamter,"查不到该订单");
+            }
+        }
+    }
+
+    public function goods_returnOp()
+    {
+        $order_sn = $_GET['order_sn'];
+        $rec_id = intval($_GET['rec_id']);
+        $buyer_msg = isset($_GET['buyer_message']) ? remove_tags(urldecode($_GET['buyer_message'])) : '';
+        $goods_num = intval($_GET['goods_num']);
+        $refund_amount = doubleval($_GET['refund_amount']);
+        $reason_id = intval($_GET['reason_id']);//退货退款原因
+
+        if(empty($order_sn) || $rec_id <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $helper = new refund_helper($_SESSION['member_id']);
+        $ret = $helper->return_goods($order_sn,$rec_id,$goods_num,$refund_amount,$reason_id,$buyer_msg,$err);
+
+        if($ret == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else
+        {
+            $fcode = new user_session\fcode(true);
+            $order = $this->get_order(array('order_sn' =>$order_sn,'buyer_id' => $_SESSION['member_id']));
+            if($order == false) {
+                return self::outerr(errcode::ErrParamter,"查不到该订单");
+            } else {
+                return self::outsuccess(array('order' => $order));
+            }
+        }
+    }
+
+    public function shipOp()
+    {
+        $refund_id = intval($_GET['refund_id']);
+        $ship_code = remove_tags(urldecode($_GET['shipping_code']));
+        $express_id = intval($_GET['express_id']);
+        if($refund_id <= 0 || empty($ship_code)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $helper = new refund_helper($_SESSION['member_id']);
+        $ret = $helper->ship($refund_id,$express_id,$ship_code,$err);
+        if($ret == true) {
+            return self::outsuccess(NULL);
+        } else {
+            return self::outerr($err['code'],$err['msg']);
+        }
+    }
+
+    private function get_order($condition)
+    {
+        $model_order = Model('order');
+        $order_list = $model_order->getNormalOrderList($condition, $this->page_size, '*', 'order_id desc', '', array('order_common','order_address', 'order_goods'));
+        $order_helper = new order_helper($order_list);
+        $orders = $order_helper->format();
+        $model_order->cls();
+        if(!empty($orders)) {
+            return $orders[0];
+        } else {
+            return false;
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * 向商家添加全部退款请求,即付完款后取消订单
+     */
+    public function add_refund_allOp()
+    {
+        $order_info = Model('order')->getOrderInfo(array('order_sn' => $_GET['order_sn']));
+        if (empty($order_info)) {
+            return self::outerr(errcode::ErrOrderNotExist);
+        }
+
+        $model_refund = Model('refund_return');
+        $order_id = intval($order_info['order_id']);
+        $order = $model_refund->getRightOrderList(array('buyer_id' => $_SESSION['member_id'], 'order_id' => $order_id));
+
+        $order_amount = $order['order_amount'];//订单金额
+        $condition = array();
+        {
+            $condition['buyer_id'] = $order['buyer
+            _id'];
+            $condition['order_id'] = $order['order_id'];
+            $condition['goods_id'] = '0';
+            $condition['seller_state'] = array('lt', '3'); //状态:1为待审核,2为同意,3为不同意
+        }
+
+        $refund_list = $model_refund->getRefundReturnList($condition);
+        $refund = array();
+        if (!empty($refund_list) && is_array($refund_list)) {
+            $refund = $refund_list[0];
+        }
+        $model_trade = Model('trade');
+        $order_paid = $model_trade->getOrderState('order_paid');//订单状态20:已付款
+        $payment_code = $order['payment_code'];//支付方式
+        if ($refund['refund_id'] > 0 || $order['order_state'] != $order_paid || $payment_code == 'offline') {//检查订单状态,防止页面刷新不及时造成数据错误
+            return self::outerr(errcode::ErrOrderState, "只有付完款尚未发货的时才能退款。");
+        }
+
+        $refund_array = array();
+        $refund_array['refund_type'] = '1'; //类型:1为退款,2为退货
+        $refund_array['seller_state'] = '1';//状态:1为待审核,2为同意,3为不同意
+        $refund_array['order_lock'] = '2';  //锁定类型:1为不用锁定,2为需要锁定
+        $refund_array['goods_id'] = '0';
+        $refund_array['order_goods_id'] = '0';
+        $refund_array['reason_id'] = '0';
+        $refund_array['reason_info'] = '取消订单,全部退款';
+        $refund_array['goods_name'] = '订单商品全部退款';
+        $refund_array['refund_amount'] = ncPriceFormat($order_amount);
+        $refund_array['buyer_message'] = remove_tags(urldecode($_POST['buyer_message']));
+        $refund_array['add_time'] = time();
+
+        $pic_array = array();
+        $pic_array['buyer'] = array();
+        $refund_array['pic_info'] = serialize($pic_array);
+        $refund_id = $model_refund->addRefundReturn($refund_array, $order);
+
+        if ($refund_id) {
+            $model_refund->editOrderLock($order_id);
+            return self::outsuccess(array("ret" => 1, "refund_id" => $refund_id, "order_sn" => $_GET['order_sn']));
+        } else {
+            return self::outerr(errcode::ErrOrderRefundError, "退款失败.");
+        }
+    }
+
+    //该函数用来返回退款具体信息。已经付款,未发货时退款,退货。
+    public function refund_one_infoOp()
+    {
+        $order_info = Model('order')->getOrderInfo(array('order_sn' => $_GET['order_sn']));
+        if (empty($order_info)) {
+            return self::outerr(errcode::ErrOrderNotExist);
+        }
+        $order_id = intval($order_info['order_id']);
+        $order_goods_id = intval($_GET['order_goods_id']);//订单商品表编号
+        if ($order_id < 1 || $order_goods_id < 1) {       //参数验证
+            return self::outerr(errcode::ErrParamter, "商品参数错误.");
+        }
+
+        $model_refund = Model('refund_return');
+        $condition = array();
+        $reason_data = $model_refund->getReasonList($condition, '', '', 'reason_id,reason_info');//退款退货原因
+        foreach ($reason_data as $data) {
+            $reason_list[] = $data;
+        }
+        array_push($reason_list, array('reason_id' => 0, 'reason_info' => '其他'));
+
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $condition['order_id'] = $order_id;
+        $order = $model_refund->getRightOrderList($condition, $order_goods_id);
+        $order_amount = $order['order_amount'];//订单金额
+        $order_refund_amount = $order['refund_amount'];//订单退款金额
+        $goods_list = $order['goods_list'];
+        $goods = $goods_list[0];
+        $goods_pay_price = $goods['goods_pay_price'];//商品实际成交价
+        if ($order_amount < ($goods_pay_price + $order_refund_amount)) {
+            $goods_pay_price = $order_amount - $order_refund_amount;
+            $goods['goods_pay_price'] = $goods_pay_price;
+        }
+
+        $goods_id = $goods['rec_id'];
+        $condition = array();
+        $condition['buyer_id'] = $order['buyer_id'];
+        $condition['order_id'] = $order['order_id'];
+        $condition['order_goods_id'] = $goods_id;
+        $condition['seller_state'] = array('lt', '3');
+        $refund_list = $model_refund->getRefundReturnList($condition);
+        $refund = array();
+        if (!empty($refund_list) && is_array($refund_list)) {
+            $refund = $refund_list[0];
+        }
+        $refund_state = $model_refund->getRefundState($order);//根据订单状态判断是否可以退款退货
+
+        if ($refund['refund_id'] > 0) {
+            return self::outerr(errcode::ErrOrderRefundError, "不能重复退货.");
+        }
+        if ($refund_state != 1) {
+            return self::outerr(errcode::ErrOrderState, '请确认订单状态,在已经付款后才能退款,已经发货后才能退货.');
+        }
+
+        $goods['goods_image'] = cthumb($goods['goods_image'], 360, $order_info['store_id']);
+        $goods['order_goods_id'] = $order_goods_id;
+
+        return self::outsuccess(array('ret' => 1, 'reason_list' => (array)$reason_list, 'goods' => $goods));
+    }
+
+    //已经付款,未发货时退款。只能单品退款
+    public function add_refund_oneOp()
+    {
+        // if(!isset($_GET['refund_type']) || empty($_GET['refund_type'])
+        //     || !in_array($_GET['refund_type'],self::$refund_type))
+        // {
+        //    return self::outerr(errcode::ErrParamter,"请使用正确的退款类型,1:退款,2:退货.");
+        //}
+        //$refund_type = $_GET['refund_type'];
+
+        $order_info = Model('order')->getOrderInfo(array('order_sn' => $_GET['order_sn']));
+        if (empty($order_info)) {
+            return self::outerr(errcode::ErrOrderNotExist);
+        }
+        $order_id = $order_info['order_id'];
+        $order_goods_id = intval($_GET['order_goods_id']);//订单商品表编号
+        if ($order_id < 1 || $order_goods_id < 1) {       //参数验证
+            return self::outerr(errcode::ErrParamter, "商品参数错误.");
+        }
+        $buyer_msg = isset($_GET['buyer_message']) ? remove_tags(urldecode($_GET['buyer_message'])) : '';
+
+        $model_refund = Model('refund_return');
+
+        $reason_list = $model_refund->getReasonList();//退款退货原因
+        $reason_id = intval($_POST['reason_id']);//退货退款原因
+        $reson_info = '其他';
+        if (!empty($reason_list[$reason_id])) {
+            $reason_array = $reason_list[$reason_id];
+            $reson_info = $reason_array['reason_info'];
+        }
+        $goods_num = intval($_POST['goods_num']);//退货数量
+        $refund_amount = doubleval($_POST['refund_amount']);//退款金额
+
+        ////////////////////////////////////////////////////////////////
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $condition['order_id'] = $order_id;
+        $order = $model_refund->getRightOrderList($condition, $order_goods_id);
+        $order_id = $order['order_id'];
+        $order_amount = $order['order_amount'];//订单金额
+        $order_refund_amount = $order['refund_amount'];//订单退款金额
+        $goods_list = $order['goods_list'];
+        $goods = $goods_list[0];
+        $goods_pay_price = $goods['goods_pay_price'];//商品实际成交价
+        if ($order_amount < ($goods_pay_price + $order_refund_amount)) {
+            $goods_pay_price = $order_amount - $order_refund_amount;
+            $goods['goods_pay_price'] = $goods_pay_price;
+        }
+
+        $goods_id = $goods['rec_id'];
+        $condition = array();
+        $condition['buyer_id'] = $order['buyer_id'];
+        $condition['order_id'] = $order['order_id'];
+        $condition['order_goods_id'] = $goods_id;
+        $condition['seller_state'] = array('lt', '3');
+        $refund_list = $model_refund->getRefundReturnList($condition);
+        $refund = array();
+        if (!empty($refund_list) && is_array($refund_list)) {
+            $refund = $refund_list[0];
+        }
+        $refund_state = $model_refund->getRefundState($order);//根据订单状态判断是否可以退款退货
+        if ($refund['refund_id'] > 0 || $refund_state != 1) {//检查订单状态,防止页面刷新不及时造成数据错误
+            return self::outerr(errcode::ErrOrderState);
+        }
+
+        $refund_array = array();
+
+        if (($refund_amount < 0) || ($refund_amount > $goods_pay_price)) {
+            $refund_amount = $goods_pay_price;
+        }
+        if (($goods_num < 0) || ($goods_num > $goods['goods_num'])) {
+            $goods_num = 1;
+        }
+
+        $refund_array['reason_info'] = $reson_info;
+        $refund_array['reason_id'] = $reason_id;
+        $refund_array['pic_info'] = serialize(array('buyer' => array()));
+
+        $model_trade = Model('trade');
+        $order_shipped = $model_trade->getOrderState('order_shipped');//订单状态30:已发货
+        if ($order['order_state'] == $order_shipped) {
+            $refund_array['order_lock'] = '2';//锁定类型:1为不用锁定,2为需要锁定
+        }
+        $refund_array['refund_type'] = 2;//类型:1为退款,2为退货
+        $refund_array['return_type'] = '2';//退货类型:1为不用退货,2为需要退货
+        if ($refund_array['refund_type'] != '2') {
+            $refund_array['refund_type'] = '1';
+            $refund_array['return_type'] = '1';
+        }
+        $refund_array['seller_state'] = '1';//状态:1为待审核,2为同意,3为不同意
+        $refund_array['refund_amount'] = ncPriceFormat($refund_amount);
+        $refund_array['goods_num'] = $goods_num;
+        $refund_array['buyer_message'] = $buyer_msg;
+        $refund_array['add_time'] = time();
+        $refund_id = $model_refund->addRefundReturn($refund_array, $order, $goods);
+
+        if ($refund_id) {
+            if ($order['order_state'] == $order_shipped) {
+                $model_refund->editOrderLock($order_id);
+            }
+            return self::outsuccess(array('ret' => 1, "refund_id" => $refund_id, "order_sn" => $_GET['order_sn'], "order_goods_id" => $_GET['order_goods_id']));
+        } else {
+            return self::outerr(errcode::ErrOrderRefundError, "退货失败.");
+        }
+    }
+
+    /**
+     * 退款或退货退款记录详情
+     */
+    public function refund_viewOp()
+    {
+        if (!isset($_GET['refund_id']) || empty($_GET['refund_id'])) {
+            return self::outerr(errcode::ErrParamter, "记录参数有误");
+        }
+        $model_refund = Model('refund_return');
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $condition['refund_id'] = intval($_GET['refund_id']);
+        $condition['seller_state'] = array('lt', '3'); //状态:1为待审核,2为同意,3为不同意
+        $refund_fields = 'refund_id,order_id,order_sn,order_goods_id,add_time,refund_type,return_type,seller_time,ship_time,admin_time';
+        $refund_list = $model_refund->getRefundReturnList($condition, '', $refund_fields);
+
+        if (empty($refund_list)) {
+            return self::outerr(errcode::ErrOrderState);
+        }
+
+        $refund = $refund_list[0];
+        $refund['refund_state'] = $model_refund->getRefundStatueApp($refund);
+
+        unset($refund['seller_time']);
+        unset($refund['ship_time']);
+        unset($refund['admin_time']);
+        $model_order = Model('order');
+        $condition = array();
+        $condition['order_id'] = $refund['order_id'];
+        $condition['rec_id'] = $refund['order_goods_id'];
+        $good_fields = 'goods_id,goods_name,goods_price,goods_num,goods_image,goods_pay_price,goods_type,commis_rate,gc_id,goods_spec';
+        $refund['good_list'] = $model_order->getOrderGoodsList($condition, $good_fields);
+        return self::outsuccess(array('refund' => $refund));
+    }
+
+    /**
+     * 用户发货
+     */
+    public function refund_shipOp()
+    {
+        $model_refund = Model('refund_return');
+        $condition = array();
+        $condition['buyer_id'] = $_SESSION['member_id'];
+        $condition['refund_id'] = intval($_GET['refund_id']);
+        $return_list = $model_refund->getReturnList($condition);
+        $return = $return_list[0];
+        if ($return['seller_state'] != '2' || $return['goods_state'] != '1') {//检查状态,防止页面刷新不及时造成数据错误
+            return self::outerr(errcode::ErrFrequentlyRequest, "该申请已发货");
+        }
+        $refund_array = array();
+        $refund_array['ship_time'] = time();
+        $refund_array['delay_time'] = time();
+      //  $refund_array['express_id'] = $_POST['express_id'];
+        $refund_array['invoice_no'] = remove_tags(urldecode($_POST['invoice_no']));
+        $refund_array['goods_state'] = '2';
+        $state = $model_refund->editRefundReturn($condition, $refund_array);
+        if ($state) {
+            return self::outsuccess(array('ret' => 1));
+        } else {
+            return self::outerr(errcode::ErrOrderRefundError, "发货失败.");
+        }
+    }
+}

+ 280 - 0
mapi/control/member_relation.php

@@ -0,0 +1,280 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/7/21
+ * Time: 下午12:07
+ */
+require_once (BASE_ROOT_PATH . '/helper/relation_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/model_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/room_helper.php');
+
+class member_relationControl extends mbMemberControl
+{
+    //subscriber TEXT COMMENT '订阅我为好友的人。',
+    //follower TEXT COMMENT   '我订阅别人成为好友通过的人。'
+    public function __construct()
+    {
+        parent::__construct();
+        relation_helper::onLogin($_SESSION['member_id']);
+    }
+
+    //我关注的人
+    public function subscriberOp()
+    {
+        $iRelation = new relation\mem_relation($_SESSION['member_id']);
+        $follower = $iRelation->follower();
+
+        $mem_desc = [];
+        $pages = 0;
+        $follower_infos = [];
+
+        if(!empty($follower))
+        {
+            $follower = self::separate_page($follower,$pages);
+            $members = Model('member')->getMemberList(['member_id' => ['in',$follower]]);
+
+            foreach ($members as $val) {
+                $info = new member_info($val);
+                array_push($mem_desc,$info->filter());
+            }
+
+            $f_infos = Model('member_relation')->getRelationList(['member_id' => ['in',$follower]]);
+            foreach ($f_infos as $val)
+            {
+                $relation = new relation\mem_relation($val);
+                $item = ['fans_count' =>$relation->subscriber_count(),
+                         'member_id' => $relation->member_id(),
+                         'subscribed' => true];
+                array_push($follower_infos,$item);
+            }
+        }
+
+        return self::outsuccess(['subscribers' => $follower_infos,
+            'count' => $iRelation->follower_count(),
+            'mem_desc' => $mem_desc,
+            'mobile_page' => mobile_page($pages)]);
+    }
+
+    //我的粉丝
+    public function followerOp()
+    {
+        $iRelation = new relation\mem_relation($_SESSION['member_id']);
+        $follows = $iRelation->subscriber();
+
+        $mem_desc = [];
+        $pages = 0;
+        $follower_infos = [];
+        if(!empty($follows))
+        {
+            $follows = self::separate_page($follows,$pages);
+            $members = Model('member')->getMemberList(['member_id' => ['in',$follows]]);
+            foreach ($members as $val) {
+                $info = new member_info($val);
+                array_push($mem_desc,$info->filter());
+            }
+            $f_infos = Model('member_relation')->getRelationList(['member_id' => ['in',$follows]]);
+            foreach ($f_infos as $val)
+            {
+                $relation = new relation\mem_relation($val);
+                $item = [ 'fans_count' => $relation->subscriber_count(),
+                          'member_id'  => $relation->member_id(),
+                          'subscribed' => $iRelation->is_follower($relation->member_id())];
+                array_push($follower_infos,$item);
+            }
+        }
+
+        return self::outsuccess(['followers' => $follower_infos,
+                                 'count' => $iRelation->subscriber_count(),
+                                 'mem_desc' => $mem_desc,
+                                 'mobile_page' => mobile_page($pages)]);
+    }
+
+    public function subscribeOp()
+    {
+        if(!isset($_GET['userid']) || empty($_GET['userid'])) {
+            return self::outerr(errcode::ErrParamter,"需要传递userid参数.");
+        }
+
+        $userid = intval($_GET['userid']);
+        if($userid <= 0) {
+            return self::outerr(errcode::ErrParamter,"userid必须大于0.");
+        }
+        try
+        {
+            if(relation_helper::is_follow(session_helper::memberid(),$userid))
+            {
+                try
+                {
+                    if(relation_helper::onUnSubscribe(session_helper::memberid(),$userid) == true) {
+                        return self::outsuccess(NULL);
+                    } else{
+                        return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+                    }
+                } catch (Exception $ex) {
+                    return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+                }
+            }
+            elseif(relation_helper::onSubscribe(session_helper::memberid(),$userid) == true) {
+                return self::outsuccess(NULL);
+            }
+            else {
+                return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+            }
+        }
+        catch (Exception $ex) {
+            return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+        }
+    }
+    
+    public function unsubscribeOp()
+    {
+        if(!isset($_GET['userid']) || empty($_GET['userid'])) {
+            return self::outerr(errcode::ErrParamter,"需要传递userid参数.");
+        }
+
+        $userid = intval($_GET['userid']);
+        if($userid <= 0) {
+            return self::outerr(errcode::ErrParamter,"userid必须大于0.");
+        }
+        try
+        {
+            if(relation_helper::is_follow($_SESSION['member_id'],$userid))
+            {
+                if(relation_helper::onUnSubscribe($_SESSION['member_id'],$userid) == true) {
+                    return self::outsuccess(NULL);
+                } else{
+                    return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+                }
+            }
+            elseif(relation_helper::onSubscribe($_SESSION['member_id'],$userid) == true) {
+                return self::outsuccess(NULL);
+            } else {
+                return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+            }
+        }
+        catch (Exception $ex) {
+            return self::outerr(errcode::ErrRelation,"关注的用户不存在");
+        }
+    }
+
+    public function kinsOp()
+    {
+        $mem_desc = [];
+        $kins = [];
+
+        $invitor = $this->inviter();
+        if($this->page_no() == 1 && !empty($invitor)) {
+            $info = new member_info($invitor);
+            $item = $info->filter();
+            $item['is_invitor'] = true;
+
+            $kin['fans_count'] = 3;
+            $kin['member_id'] = $info->member_id();
+            $kin['subscribed'] = true;
+            $kins[] = $kin;
+
+            $mem_desc [] = $item;
+        }
+
+        $mod_member = Model('member');
+        $invitees = $mod_member->getMemberList(['inviter_id' => $_SESSION['member_id']],'*',$this->page_size());
+        foreach ($invitees as $val) {
+            $info = new member_info($val);
+            $item = $info->filter();
+            $item['is_invitor'] = true;
+            $mem_desc [] = $item;
+
+            $kin['fans_count'] = 3;
+            $kin['member_id'] = $info->member_id();
+            $kin['subscribed'] = true;
+            $kins[] = $kin;
+        }
+
+        $pages = $mod_member->gettotalpage();
+        $count = intval($mod_member->gettotalnum()) + (empty($invitor) ? 0 : 1);
+
+        return self::outsuccess(['count' => $count,
+            'kins' => $kins,
+            'mem_desc' => $mem_desc,
+            'mobile_page' => mobile_page($pages)]);
+    }
+
+    private function inviter()
+    {
+        $mod_member = Model('member');
+        if(isset($_SESSION['inviter_id']) == false) {
+            $inviter_id = $mod_member->getMemberInfo(['member_id' => $_SESSION['member_id']],'inviter_id');
+            $_SESSION['inviter_id'] = $inviter_id;
+        }
+
+        $inviter_id = $_SESSION['inviter_id'];
+        if($inviter_id > 0) {
+            $info = $mod_member->getMemberInfoByID($inviter_id);
+            return $info;
+        } else {
+            return false;
+        }
+    }
+
+    //处理好友申请
+    public function handle_applysOp()
+    {
+        $msgid = intval($_GET['msg_id']);
+        $pass  = boolval($_GET['pass']);
+
+        $item = room_helper::message($msgid);
+        if($item == false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $msg = json_decode($item['orgmsg'],true);
+        $apply_user = intval($msg['from']['userid']);
+        if($apply_user <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        if($msg['state'] === 'pending')
+        {
+            $mod_room = Model('room');
+            if($msg['type'] == 'apply_friend')
+            {
+                if($pass)
+                {
+                    $relateion = new relation\mem_relation(session_helper::memberid());
+                    $isfriend =  $relateion->is_friends($apply_user);
+                    if($isfriend) {
+                        $msg['state'] = 'accept';
+                        $mod_room->updateMsg($msgid,['orgmsg' => json_encode($msg,JSON_UNESCAPED_UNICODE)]);
+                        return self::outerr(errcode::ErrMemberNotExist,"你们已经是好友了");
+                    }
+
+                    relation_helper::onAccept(session_helper::memberid(),$apply_user);
+                    room\pusher::instance()->new_friend(session_helper::memberid(),$apply_user);
+                    room\pusher::instance()->new_friend($apply_user,session_helper::memberid());
+                    $msg['state'] = 'accept';
+                } else {
+                    $msg['state'] = 'refuse';
+                }
+            }
+            elseif($msg['type'] == 'apply_room')
+            {
+                $roomid = $msg['room_id'];
+                if($pass) {
+                    room\factory_client::instance()->invite($roomid, session_helper::memberid(),[$apply_user]);
+                    $msg['state'] = 'accept';
+                } else {
+                    $msg['state'] = 'refuse';
+                }
+            }
+
+            if($msg['state'] != 'pending') {
+                $mod_room->updateMsg($msgid,['orgmsg' => json_encode($msg,JSON_UNESCAPED_UNICODE)]);
+            }
+        }
+
+        return self::outsuccess(null,"处理成功");
+    }
+}

File diff suppressed because it is too large
+ 1456 - 0
mapi/control/member_talk.php


+ 735 - 0
mapi/control/member_ugc.php

@@ -0,0 +1,735 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/7/5
+ * Time: 下午4:02
+ */
+
+use bonus\account;
+
+require_once(BASE_ROOT_PATH . '/mobile/control/special.php');
+require_once(BASE_ROOT_PATH . '/helper/ugc_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/text_filter.php');
+require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+
+class member_ugcControl extends specialControl
+{
+    const greater = 0;
+    const lesser  = 1;
+    private $mUgcBanner;
+
+    public function __construct()
+    {
+        parent::__construct();
+        global $config;
+        $this->mUgcBanner = $config['ugc_banner'];
+    }
+
+    public function pub_listOp()
+    {
+        return $this->fetch('pub_list');
+    }
+
+    public function pri_listOp()
+    {
+        $this->need_login();
+        return $this->fetch('pri_list');
+    }
+    public function mine_listOp()
+    {
+        $this->need_login();
+        return $this->fetch('mine_list');
+    }
+
+    public function ugc_tabsOp()
+    {
+        //todo -- 需要和数据库对应确认
+        $tabs = Model('mb_special')->getUgcTypesList();
+        $ret = [];
+        foreach ($tabs as $k => $tab) {
+            $ret[$k]['tab_id']  = intval($tab['ugcat_id']);
+            $ret[$k]['name']    = $tab['type_name'];
+        }
+
+        return self::outsuccess([ 'tabs' => $ret ]);
+    }
+
+    public function ugc_listOp()
+    {
+        return $this->fetch('pub_list');
+    }
+
+    private function fetch($type)
+    {
+        $special_id = intval($_GET['special_id']);
+        $count = $this->page_size();
+
+        if($special_id == -1) {
+            $special_id = -1;
+            $direct = self::lesser;
+        }
+        elseif ($special_id == 0) {
+            return self::outsuccess(['special_list' => null,'mobile_page' => mobile_page(0)]);
+        }
+        else {
+            $direct = $this->direct();
+        }
+
+        if($type == "pub_list") {
+            $ugcat    = intval($_GET['tab_id']);
+            $specials = search\relation_client::instance()->fetch_pub_special(['special_id' => $special_id,'count'=> $count,'type' => $direct,'ugcat' => $ugcat]);
+        }
+        elseif($type == 'pri_list') {
+            $specials = search\relation_client::instance()->fetch_pri_special(['user_id' => session_helper::memberid(),
+                'special_id' => $special_id,'count'=> $count,'type' => $direct]);
+        }
+        elseif($type == "mine_list") {
+            $specials = $this->mine_specials($special_id,$count);
+        }
+        else {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $blocks = [];
+        if($special_id == -1)
+        {
+            $extid = $this->tip_block($type);
+            if($extid != false) {
+                $helper = new special_formater($extid);
+                $blocks = $helper->format($goods_ids);
+            }
+        }
+
+        if(empty($specials))
+        {
+            $page_no = $this->page_no();
+            if($page_no == 1) $page_no = 0;
+            return self::outsuccess(['special_list' => $blocks,'mobile_page' => mobile_page($page_no)]);
+        }
+        else
+        {
+            $special_list = $this->special_list($specials,$ugcs);
+            $page_no = $this->page_no();
+            if($this->page_size() <= count($specials)) {
+                $page_no += 1;
+            }
+            foreach ($special_list as $val) {
+                $blocks[] = $val;
+            }
+            return self::outsuccess(['special_list' => $blocks,
+                'ugcs' => $ugcs,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_no)]);
+        }
+    }
+
+    private function mine_specials($special_id,$count)
+    {
+        $mod_special = Model();
+        $userid = session_helper::memberid();
+
+        if($special_id == -1) {
+            $items = $mod_special->table('mb_special')->field('special_id')
+                ->where(['member_id' => $userid,'from_user' => 1])
+                ->order('special_id desc')->limit($count)->select();
+        } else {
+            $items = $mod_special->table('mb_special')->field('special_id')
+                ->where(array('special_id' => ['lt',$special_id],'member_id' => $userid,'from_user' => 1))
+                ->order('special_id desc')->limit($count)->select();
+        }
+
+        $result = [];
+        foreach ($items as $item) {
+            $spid = intval($item['special_id']);
+            $result[] = $spid;
+        }
+
+        return $result;
+    }
+    private function tip_block($type)
+    {
+        if($type == "pub_list") {
+            $spid = $this->mUgcBanner['pub'];
+        }
+        elseif($type == 'pri_list') {
+            $spid = $this->mUgcBanner['friend'];
+        }
+        elseif($type == "mine_list") {
+            $spid = $this->mUgcBanner['mine'];
+        }
+        else {
+            return false;
+        }
+
+        if(empty($spid) || $spid == 0) {
+            return false;
+        }
+        else {
+            return $spid;
+        }
+    }
+    private function direct()
+    {
+        $cur_page = $this->page_no();
+        if($cur_page == 1) {
+            return self::greater;
+        } else {
+            return self::lesser;
+        }
+    }
+
+    private function special_list($spids, &$ugcs)
+    {
+        $result = [];
+        $mod_special = Model('mb_special');
+        $items = $mod_special->getMbSpecialList(['special_id' => ['in',$spids],'member_id' => ['gt',0],'from_user' => 1]);
+
+        $users = [];
+        $specials = [];
+        foreach ($items as $item)
+        {
+            $special = new ugc\special($item);
+            $specials[] = $special;
+            $sender = $special->memberid();
+            $users[] = $sender;
+        }
+        sort($users);
+        $users = array_unique($users);
+
+        $minfos = [];
+        if(!empty($users))
+        {
+            $mod_member = Model('member');
+            $members = $mod_member->getMemberList(['member_id' => ['in',$users]]);
+            foreach ($members as $member) {
+                $info = new member_info($member);
+                $mid = $info->member_id();
+                $minfos[$mid] = $info;
+            }
+        }
+
+        $ugcs = [];
+        foreach ($specials as $special)
+        {
+            $block = special_formater::format_ugc($special);
+            $result[] = $block;
+            $divider = special_formater::def_divider();
+            $result[] = $divider;
+
+            $mid = $special->memberid();
+            $minfo = $minfos[$mid];
+
+            if(is_null($minfo) == false) {
+                $ugc = $this->format_ugc($minfo,$special);
+                $ugcs[] = $ugc;
+            }
+        }
+        return $result;
+    }
+
+    private function format_ugc(member_info $minfo, ugc\special $special)
+    {
+        $ret['special_id'] = $special->special_id();
+        $ret['member_avatar'] = $minfo->avatar();
+        $ret['member_nickname'] = $minfo->nickname();
+        $ret['has_vote'] = $special->has_vote();
+        $ret['appreciate_num'] = $special->appreciates();
+        $ret['comment_num'] = $special->comments();
+        $ret['clicks'] = $special->clicks();
+        $ret['pubtime'] = $special->editime();
+        $ret['desc'] = $special->description();
+        $supporter = new ugc\special_support($special->special_id(),0);
+        $ret['supported'] = $supporter->supported();
+        $ret['support_num'] = $special->likes();
+        $cid = $special->category_id();
+        $ret['category'] = ugc_helper::category_title($cid);
+
+        $ret['can_del'] = false;
+        if(session_helper::logined())
+        {
+            if($special->memberid() == $_SESSION['member_id']) {
+                $ret['can_del'] = true;
+            }
+        }
+
+        return $ret;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function addOp()
+    {
+        $this->need_login();
+
+        $contet = $_POST['content'];
+        if(empty($contet)) {
+            return self::outerr(errcode::ErrParamter,"上传的内容不能为空");
+        }
+        return $this->add($contet);
+    }
+
+    public function addexOp()
+    {
+        $this->need_login();
+
+        $contet = $_POST['content'];
+        if(empty($contet)) {
+            return self::outerr(errcode::ErrParamter,"上传的内容不能为空");
+        }
+        else {
+            $contet = urldecode($contet);
+        }
+        return $this->add($contet);
+    }
+
+    private function add($contet)
+    {
+        $sp_data = json_decode($contet,true);
+        if(empty($sp_data)) {
+            return self::outerr(errcode::ErrParamter,"上传的内容不能为空");
+        }
+
+        $spobj = ugc_helper::crate_special($sp_data,$err);
+        if($spobj == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        if($spobj->count() > 0)
+        {
+            $special_id = $spobj->save($_SESSION['member_id'],$sp_data);
+        } else {
+            $special_id = false;
+        }
+
+        if($special_id == false) {
+            return self::outerr(errcode::ErrUGC,"抱歉,内容云同步失败 :(");
+        }
+        else {
+            return self::outsuccess(['special_id' => $special_id]);
+        }
+    }
+
+    public function previewOp()
+    {
+        $this->need_login();
+        return parent::indexOp();
+    }
+
+    public function publishOp()
+    {
+        $this->need_login();
+
+        $special_id = intval($_GET['special_id']);
+        $setting = $_GET['setting'];
+
+        if($special_id < 0 || empty($setting)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        return $this->publish($special_id,$setting);
+    }
+
+    public function publishexOp()
+    {
+        $this->need_login();
+
+        $special_id = intval($_GET['special_id']);
+        $setting = $_GET['setting'];
+
+        if($special_id < 0 || empty($setting)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        else {
+            $setting = urldecode($setting);
+        }
+        return $this->publish($special_id,$setting);
+    }
+
+    private function publish($special_id,$setting)
+    {
+        $setting = json_decode($setting,true);
+        if(ugc_helper::pub_special($special_id,$setting,$err) == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else {
+            return self::outsuccess(['special_id' => $special_id]);
+        }
+    }
+
+    public function delOp()
+    {
+        $this->need_login();
+
+        $special_id = intval($_GET['special_id']);
+        if(ugc_helper::del_special($special_id,$err) == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else {
+            return self::outsuccess(['special_id' => $special_id]);
+        }
+    }
+
+    public function supportOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $comment_id = intval($_GET['comment_id']);
+        $supported = ugc_helper::support_special($special_id,$comment_id);
+        return self::outsuccess(['special_id' => $special_id,'comment_id' => $comment_id,'supported' => $supported]);
+    }
+
+    public function commentsOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $comment_id = intval($_GET['comment_id']);
+        if($comment_id <= 0)
+        {
+            $mod_comment = Model('ugc_comment');
+            $count = $mod_comment->top_counts($special_id);
+            $items = $mod_comment->getTopCommentList($special_id,'comment_id',$this->page_size(),$count);
+            $pages = $mod_comment->gettotalpage();
+            $mobile_page = mobile_page($pages);
+
+            $commentids = $this->commentids($items);
+            if(!empty($commentids))
+            {
+                $mod = Model('ugc_comment');
+                $comment_subcounts = [];
+                $items = $mod->comments_counts($special_id,$commentids);
+                foreach ($items as $item) {
+                    $comment_id = intval($item['comment_id']);
+                    $count = intval($item['nc_count']);
+                    $comment_subcounts[$comment_id] = $count;
+                }
+                $comments = $mod->getCommentList(array('top_id' => ['in',$commentids]),'*',0);
+                $comments_obj =new ugc\comments($comments,$special_id,$comment_subcounts);
+                $comments = $comments_obj->comments();
+                $uids = $comments_obj->users();
+                $members = $this->users($uids);
+            } else {
+                $comments = [];
+                $members = [];
+            }
+        }
+        else
+        {
+            $mod_comment = Model('ugc_comment');
+            $count = $mod_comment->comment_counts($special_id,$comment_id);
+            $items = $mod_comment->getSubCommentList($special_id,$comment_id,'comment_id',$this->page_size(),$count);
+            $pages = $mod_comment->gettotalpage();
+            $mobile_page = mobile_page($pages);
+            $commentids = $this->commentids($items);
+
+            if($commentids) {
+                $mod = Model('ugc_comment');
+                $comments = $mod->getCommentList(array('comment_id' => ['in',$commentids]),'*',0);
+                $comments_obj =new ugc\comments($comments,$special_id,[]);
+                $comments = $comments_obj->comments();
+                $uids = $comments_obj->users();
+                $members = $this->users($uids);
+            } else {
+                $comments = [];
+                $members = [];
+            }
+        }
+
+        return self::outsuccess(['comments' => $comments,'members' => $members,'mobile_page' => $mobile_page]);
+    }
+
+    private function users($user_ids)
+    {
+        if(empty($user_ids)) return [];
+
+        $mod_member = Model('member');
+        $members = $mod_member->getMemberList(array('member_id' => ['in',$user_ids]));
+        if(empty($members)) return [];
+
+        $result = [];
+        foreach ($members as $item)
+        {
+            $member = new member_info($item);
+            $val['member_id'] = $member->member_id();
+            $val['avatar'] = $member->avatar();
+            $val['nickname'] = $member->nickname();
+
+            $result[] = $val;
+        }
+        return $result;
+    }
+
+    private function commentids($items)
+    {
+        $result = [];
+        foreach ($items as $val) {
+            $commentid = intval($val['comment_id']);
+            $result[] = $commentid;
+        }
+        return $result;
+    }
+
+    public function commentOp()
+    {
+        $this->need_login();
+
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $comment = urldecode($_GET['content']);
+        if(empty($comment)) {
+            return self::outerr(errcode::ErrParamter,"评论内容不能为空.");
+        }
+        $comment = text_filter::filter_html($comment);
+        if(empty($comment)) {
+            return self::outerr(errcode::ErrParamter,"评论内容不能含非法字符.");
+        }
+
+        $comment_id = intval($_GET['comment_id']);
+        $mod_comment = Model('ugc_comment');
+        if($comment_id > 0) {
+            $ret = $mod_comment->respond_comment($special_id,$comment_id,session_helper::memberid(),$comment);
+        } else {
+            $ret = $mod_comment->comment($special_id,session_helper::memberid(),$comment);
+        }
+
+        if($ret == false) {
+            return self::outerr(errcode::ErrDB,"抱歉,评论出错了.");
+        }
+        else
+        {
+            $mod = Model('ugc_comment');
+            $comments = $mod->getCommentList(['comment_id' => $ret],'*',0);
+            $comments_obj = new ugc\comments($comments,$special_id,[]);
+            $comments = $comments_obj->comments();
+            $uids = $comments_obj->users();
+            $members = $this->users($uids);
+
+            QueueClient::push('onAsyncUgcComment',['special_id' => $special_id, 'comment_id' => $comment_id,'user_id' => session_helper::memberid()]);
+            return self::outsuccess(['comments' => $comments,'members' => $members,'mobile_page' => mobile_page(0)]);
+        }
+    }
+
+    public function mine_bonusOp()
+    {
+        $this->need_login();
+        $pred = new account($_SESSION['member_id'],true);
+        $bonus_rate = $pred->pay_bonus_rates();
+
+        if($bonus_rate != null)
+        {
+            $rates = $bonus_rate->format();
+            $rates_money = [];
+            foreach ($rates as $rate => $money) {
+                $item['rate']  = $rate;
+                $item['total'] = $money;
+                $rates_money[] = $item;
+            }
+        }
+        else {
+            $rates_money = [];
+        }
+
+        return self::outsuccess(['bonus_rate' => $rates_money]);
+    }
+
+    public function appreciateOp()
+    {
+        $this->need_login();
+
+        $special_id = intval($_GET['special_id']);
+        $rate  = intval($_GET['rate']);
+        $money = intval($_GET['money']);
+
+        $bless = urldecode($_GET['bless']);
+        $bless = text_filter::filter_html($bless);
+
+        if($special_id < 0 || $rate <= 0 || $rate > 100 || $money <= 0) {
+            return self::outerr(errcode::ErrParamter,"参数错误");
+        }
+
+        $ret = ugc_helper::appreciate($special_id,$rate,$money,$bless);
+        if($ret == false) {
+            return self::outsuccess(errcode::ErrBonus,"抱歉,赞赏失败,请晚点再试。");
+        }
+        else
+        {
+            $mod_appreciate = Model('appreciate');
+            $insertid = $mod_appreciate->insert(['special_id' => $special_id,'member_id' => session_helper::memberid(),'rate' => $rate,'money' => $money,'addtime' => time()]);
+            if($insertid != false) {
+                $mod_special = Model('mb_special');
+                $mod_special->table('mb_special')->where(['special_id' => $special_id])->update(array('appreciates' => ['exp', 'appreciates + 1'],
+                                                                                                      'appreciate_amonut' => ['exp', "appreciate_amonut + {$money}"]));
+            }
+            QueueClient::push('onAsyncUgcAppreciate',['special_id' => $special_id,
+                                                      'user_id' => session_helper::memberid(),
+                                                      'rate' => $rate,'amount' => $money]);
+            return self::outsuccess(null);
+        }
+    }
+    public function appreciate_listOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+
+        $mod_appreciate = Model('appreciate');
+        $count = $mod_appreciate->counts($special_id);
+        $items = $mod_appreciate->getListBySpecialid($special_id,'*',$this->page_size(),$count);
+        $pages = $mod_appreciate->gettotalpage();
+
+        $uids = [];
+        foreach ($items as $val) {
+            $user_id = intval($val['member_id']);
+            $uids[] = $user_id;
+        }
+        $members = $this->users($uids);
+
+        $result = [];
+        foreach ($items as $item) {
+            $val = [];
+            $val['member_id'] = intval($item['member_id']);
+            $val['rate'] = intval($item['rate']);
+            $val['money'] = doubleval($item['money']);
+            $val['addtime'] = intval($item['addtime']);
+
+            $result[] = $val;
+        }
+
+        return self::outsuccess(['appreciate' => $result,'members' => $members,'mobile_page' => mobile_page($pages)]);
+    }
+
+    public function answer_pageOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $memberid = session_helper::memberid();
+        if($memberid > 0) {
+            $mod_answer = Model('ugc_answer');
+            $answer = $mod_answer->getAnswer($special_id,$memberid);
+        }
+
+        if(empty($answer))
+        {
+            return self::outsuccess(['answer' => [],'special_id' => $special_id,'scale' => 0],'ugc/answer.list');
+        }
+        else
+        {
+            $result = $this->format_answer($answer,'','');
+            $correct_num = $answer['correct_num'];
+            if($correct_num > 0)
+            {
+                $lt_count = $mod_answer->lt_count($special_id,$correct_num);
+                $counts   = $mod_answer->counts($special_id);
+                if($lt_count > 0 && $counts > 0) {
+                    $scale = intval($lt_count * 100 / $counts + 0.5);
+                } else {
+                    $scale = false;
+                }
+
+            } else {
+                $scale = false;
+            }
+
+            return self::outsuccess(['answer' => $result,'special_id' => $special_id,'scale' => $scale],'ugc/answer.list');
+        }
+    }
+
+    private function format_answer($answer,$nickname,$avatar)
+    {
+        $result['correct_num'] = intval($answer['correct_num']);
+        $result['total_num']   = intval($answer['total_num']);
+        if($result['total_num'] == 0) {
+            $result['score'] = 0;
+        }
+        else {
+            $result['score']  = intval($result['correct_num'] * 100 / $result['total_num'] + 0.5);
+        }
+        $result['bonus_rate'] = intval($answer['bonus_rate']);
+        $result['amount']     = doubleval($answer['amount']);
+        $result['answer_time']= intval($answer['answer_time']);
+        $result['nickname']   = $nickname;
+        $result['avatar']     = $avatar;
+
+        return $result;
+    }
+
+    public function answersOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $mod_answer = Model('ugc_answer');
+        $count = $mod_answer->counts($special_id);
+        $items = $mod_answer->answer_list($special_id,'*',$this->page_size(),$count);
+        $pages = $mod_answer->gettotalpage();
+
+        if(empty($items)) {
+            return self::outsuccess(['answers' => [],'mobile_page' => mobile_page(0)]);
+        }
+
+        $uids = [];
+        foreach ($items as $val) {
+            $user_id = intval($val['member_id']);
+            $uids[] = $user_id;
+        }
+        $minfos = $this->users($uids);
+        $members = [];
+        foreach ($minfos as $val) {
+            $mid = intval($val['member_id']);
+            $members[$mid] = $val;
+        }
+
+        $answers = [];
+        foreach ($items as $item) {
+            $mid = intval($item['member_id']);
+            $member = $members[$mid];
+            $value = $this->format_answer($item,$member['nickname'],$member['avatar']);
+            $answers[] = $value;
+        }
+        return self::outsuccess(['answers' => $answers,'mobile_page' => mobile_page($pages)]);
+    }
+
+    public function subscribe_authorOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+        $memberid = $_SESSION['member_id'];
+        $success = ugc_helper::subscribe($memberid,$special_id);
+        return self::outsuccess(['success' => $success]);
+    }
+    public function report_pageOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+
+        return self::outsuccess(['special_id' => $special_id],'ugc/report');
+    }
+    public function reportOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        $content = urldecode($_GET['content']);
+        if($special_id > 0 && !empty($content)) {
+            $content = text_filter::filter_input($content);
+            $mod_report = Model();
+            $mod_report->table('special_report')->insert(['special_id' => $special_id,'reporter_id' => session_helper::memberid(),'content' => $content]);
+        }
+        return self::outsuccess([]);
+    }
+}

+ 355 - 0
mapi/control/member_vorder.php

@@ -0,0 +1,355 @@
+<?php
+/**
+ * 我的订单
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/session.php');
+require_once(BASE_ROOT_PATH . '/helper/login_helper.php');
+
+class member_vorderControl extends mbMemberControl
+{
+	public function __construct(){
+		parent::__construct();
+	}
+
+    public function listOp()
+    {
+        $model_vr_order = Model('vr_order');
+        if ($_GET['state_type'] != '')
+        {
+            $condition['order_state'] = str_replace(
+                ['state_new','state_pay','state_send','state_success','state_noeval'],
+                [ORDER_STATE_NEW,ORDER_STATE_PAY,ORDER_STATE_SEND,ORDER_STATE_SUCCESS], $_GET['state_type']);
+        } else {
+            $condition['order_state'] = ["in", [ORDER_STATE_NEW,ORDER_STATE_PAY,ORDER_STATE_SEND,ORDER_STATE_SUCCESS]];
+        }
+
+        $condition['buyer_id'] = session_helper::memberid();
+        $order_list = $model_vr_order->getOrderList($condition, $this->page_size, '*', 'order_id desc');
+        $page_count = $model_vr_order->gettotalpage();
+
+        $helper = new vorder_helper($order_list);
+        $result = $helper->format();
+
+        return self::outsuccess(['vorders' => $result, 'mobile_page' => mobile_page($page_count)], mobile_page($page_count));
+    }
+
+    public function infoOp()
+    {
+        $condition = [];
+
+        if (isset($_GET['order_id'])) {
+            $condition['order_id'] = intval($_GET['order_id']);
+        }
+
+        if (isset($_GET['pay_sn'])) {
+            $condition['order_sn'] = $_GET['pay_sn'];
+        }
+
+        if (empty($condition)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $order = $this->get_order($condition);
+        if($order == false) {
+            return self::outerr(errcode::ErrOrder);
+        } else {
+            return self::outsuccess(['order' => $order]);
+        }
+    }
+
+
+    public function change_stateOp()
+    {
+        $act_type = $_GET['act_type'];
+        $order_id = intval($_GET['order_id']);
+
+        $state_type = $this->state_type($act_type);
+        if($state_type == false || $order_id <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $vorder_action = new vorder_action();
+        $fOk = $vorder_action->change_state($state_type,$order_id);
+
+        if($fOk == true)
+        {
+            $order = $this->get_order(["buyer_id" => session_helper::memberid(),'order_id' => $order_id]);
+            if($order == false) {
+                $order = null;
+            }
+            return self::outsuccess(["act_type" => $act_type,"order_id" => $order_id, "order" => $order]);
+        }
+        else {
+            return self::outerr(errcode::ErrOrder);
+        }
+    }
+
+    public function payOp()
+    {
+        $pay_sn = $_GET['pay_sn'];
+        $payment = $_GET['payment'];
+        if(empty($pay_sn) || empty($payment)) {
+            return self::outerr(errcode::ErrParamter,"支付号或者支付类型错误");
+        }
+
+        $payer = new pay_helper($pay_sn);
+        $out_put = $payer->pay($payment,$err);
+
+        if($out_put == false) {
+            return self::outerr($err['code'],$err['msg']);
+        } else {
+            $out_put['payment'] = $payment;
+            $out_put['pay_sn']  = $pay_sn;
+            return self::outsuccess($out_put);
+        }
+    }
+
+    public function pay_infoOp()
+    {
+        $order_sn = $_GET['pay_sn'];
+        if(empty($order_sn)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $order = $this->get_order(["buyer_id" => session_helper::memberid(),'order_sn' => $order_sn]);
+        $pay_ments = pay_helper::pay_types();
+        if($order == false) {
+            return self::outerr(errcode::ErrOrder);
+        } else {
+            return self::outsuccess(['order' => $order,"paytype" => $pay_ments]);
+        }
+    }
+
+    private function get_order($condition)
+    {
+        $model_vr_order = Model('vr_order');
+        $order_list = $model_vr_order->getOrderList($condition);
+        $helper = new vorder_helper($order_list);
+        $orders = $helper->format();
+        //$model_vr_order->cls();
+        if(!empty($orders)) {
+            return $orders[0];
+        } else {
+            return false;
+        }
+    }
+    private function state_type($act_type)
+    {
+        if($act_type == "if_cancel") return "order_cancel";
+        if($act_type == "if_delete") return "order_delete";
+        if($act_type == "if_receive") return "order_receive";
+        return false;
+    }
+
+    public function indate_code_listOp() {
+        $order_id = intval($_POST['order_id']);
+        if ($order_id <= 0) {
+            output_error('订单不存在');
+        }
+        $model_vr_order = Model('vr_order');
+        $condition = [];
+        $condition['order_id'] = $order_id;
+        $condition['buyer_id'] = session_helper::memberid();
+        $order_info = $model_vr_order->getOrderInfo($condition);
+        if (empty($order_info) || $order_info['delete_state'] == ORDER_DEL_STATE_DROP) {
+            output_error('订单不存在');
+        }
+        $order_list = [];
+        $order_list[$order_id] = $order_info;
+        $order_list = $model_vr_order->getCodeRefundList($order_list);//没有使用的兑换码列表
+        $code_list = [];
+        if(!empty($order_list[$order_id]['code_list'])) {
+            foreach ($order_list[$order_id]['code_list'] as $value) {
+                $code = [];
+                $code['vr_code'] = $value['vr_code'];
+                $code['vr_indate'] = $value['vr_indate'];
+                $code_list[] = $code;
+            }
+        }
+        output_data(['code_list' => $code_list]);
+    }
+
+    public function upload_certOp()
+    {
+        $member_id = session_helper::memberid();
+	    $order_sn = $_GET['order_sn'];
+	    $phone = $_GET['phone'];
+	    $code = $_GET['code'];
+	    $cert_account = $_GET['ali_account'];
+	    $contract_img = $_GET['contract_img'];
+        $invoice_img = $_GET['invoice_img'];
+        $liences_img = $_GET['license_img'];
+
+        $contract_img   = explode(",", $contract_img);
+        $invoice_img    = explode(",", $invoice_img);
+        $liences_img    = explode(",", $liences_img);
+
+        // 输入内容判断
+        $validator = new Validator();
+        $validator->setValidate(Validator::verify_mobile($phone));
+        $err = $validator->validate();
+        if ($err != '') {
+            return self::outerr(errcode::ErrInputParam,$err);
+        }
+        //校验验证码
+        $ret = sms_helper::check_code(sms_helper::register,$code,$phone);
+        if(is_array($ret)) {
+            return self::outerr($ret['code'], $ret['msg']);
+        }
+
+        //校验本人订单
+        $mod = Model();
+        $orderinfo = $mod->table('vr_order')->where(['buyer_id'=>$member_id,'order_sn'=>$order_sn])->find();
+        if(empty($orderinfo)){
+            Log::record("orderSn:{$order_sn} buyer_id:{$member_id} member_id:{$member_id}",Log::DEBUG);
+            return self::outerr(errcode::ErrMemberRight,"非本人不能操作");
+        }
+
+        if($phone != $orderinfo['buyer_phone']){
+            return self::outerr(errcode::ErrOrderMobile,"验证手机与订单手机不同");
+        }
+
+        //已经上传过了 cert_state 0:未上传 1:等待审核 2:同意 3:拒绝  4:已打款
+        if(!($orderinfo['cert_state'] <= 0 || $orderinfo['cert_state'] == 3)){
+            return self::outerr(errcode::ErrHasOrderCert,"不可重复上传过凭证");
+        }
+
+        //移动图片
+        $save_root_path  =  BASE_UPLOAD_PATH;
+        $contract_path = '/contract/';
+        $save_path = $save_root_path.$contract_path;
+
+        //下载图片至临时目录
+        if(! is_dir($save_path)) {
+            if (! mkdir($save_path)) {
+                return false;
+            }
+            @chmod($save_path, 0777);
+        }
+
+        $image_need_mv = [
+            'img_contract'=>  $contract_img,
+            'img_invoice' =>  $invoice_img,
+            'img_license' =>  $liences_img,
+        ];
+
+        foreach ($image_need_mv as $key=>$v)
+        {
+            $tmp_arr = [];
+            foreach ($v as $k =>$value){
+                $arr = explode('.',$value);
+                $ext = end($arr);
+                $newfileName = md5(time().$value).'.'.$ext;
+
+                @unlink($save_path.$newfileName);
+                $move = copy($value,$save_path.$newfileName);
+                if($move != true){
+                    return self::outerr(errcode::ErrOrder,"凭证上传失败,请稍后再试");
+                }
+                @unlink($value);
+
+                $tmp_arr[] = $newfileName;
+            }
+            $image_need_mv[$key] = implode(",", $tmp_arr);
+            unset($tmp_arr);
+        }
+
+
+        //上传凭证
+        $order_id = intval($orderinfo['order_id']);
+        $update = [
+            'cert_state'   => 1,
+            'pay_account' => $cert_account,
+            'img_contract'=> $image_need_mv['img_contract'],
+            'img_invoice'=>  $image_need_mv['img_invoice'],
+            'img_license'  =>$image_need_mv['img_license']
+        ];
+
+        $res = $mod->table('vr_order')->where(['order_id'=>$order_id,'cert_state'=>['in','0,3']])->update($update);
+
+
+        if($res) {
+            $this->add_track_log($order_id,$member_id);
+            return self::outsuccess(array('success' => true));
+        } else {
+            return self::outsuccess(array('success' => false));
+        }
+    }
+
+    private function add_track_log($order_id,$buyer_id){
+        $data['order_id']	= $order_id;
+        $data['log_type']	= "上传凭证";
+        $data['log_time']	= time();
+        $data['log_msg']	= "";
+        $data['log_role']	= "用户";
+        $data['log_user']	= $buyer_id;
+        $data['log_username']	= "";
+        $data['ip']			    = getIp();
+        return Model('vr_order_track_log')->insert($data);
+    }
+
+    /**
+     * 获取不同状态下订单数量
+     */
+    public function orderCountStateOp()
+    {
+        $result = [];
+        $all = 0;
+
+        $items = Model()->table('vr_order')
+                        ->field('order_state, count(*) as count')
+                        ->where(['buyer_id' => $_SESSION['member_id'],'delete_state' => 0])
+                        ->group('order_state')
+                        ->select();
+
+        foreach ($items as $item)
+        {
+            $state = intval($item['order_state']);
+            $count = intval($item['count']);
+            if($state == ORDER_STATE_NEW) {
+                $val = ['count' => $count,'order_state' => ORDER_STATE_NEW];
+                $all += $count;
+            }
+            elseif($state == ORDER_STATE_PAY) {
+                $val = ['count' => $count,'order_state' => ORDER_STATE_PAY];
+                $all += $count;
+            }
+            elseif($state == ORDER_STATE_SEND) {
+                $val = ['count' => $count,'order_state' => ORDER_STATE_SEND];
+                $all += $count;
+            }
+            elseif($state == ORDER_STATE_SUCCESS) {
+                $all += $count;
+                $val = ['count' => $count,'order_state' => ORDER_STATE_SUCCESS];
+            }
+            else {
+                continue;
+            }
+
+            $result[] = $val;
+        }
+        $result[] = ['order_state' => '0','count' => $all];
+
+//        //待评价
+//        $ev_items = Model()->table('vr_order')
+//            ->field('order_state, count(*) as count')
+//            ->where(['buyer_id' => $_SESSION['member_id'],'delete_state' => 0,'order_state' => ORDER_STATE_SUCCESS, 'evaluation_state' => 0])
+//            ->group('order_state')
+//            ->select();
+//        if(!empty($ev_items)) {
+//            $result[] = ['order_state' => '40','count' => intval($ev_items[0]['count'])];
+//        }
+
+        self::outsuccess(['order_count' => $result]);
+    }
+}

+ 34 - 0
mapi/control/member_voucher.php

@@ -0,0 +1,34 @@
+<?php
+/**
+ * 我的代金券
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_voucherControl extends mbMemberControl
+{
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 代金券列表
+     */
+    public function voucher_listOp()
+    {
+        $model_voucher = Model('voucher');
+        $voucher_list = $model_voucher->getMemberVoucherList($_SESSION['member_id'], $_POST['voucher_state'], $this->page_size());
+        $page_count = $model_voucher->gettotalpage();
+
+        output_data(array('voucher_list' => $voucher_list), mobile_page($page_count));
+    }
+}

+ 106 - 0
mapi/control/member_vr_buy.php

@@ -0,0 +1,106 @@
+<?php
+/**
+ * 购买
+ *
+ *
+ *
+ *
+
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class member_vr_buyControl extends mbMemberControl
+{
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 虚拟商品购买第一步,设置购买数量
+     * POST
+     * 传入:cart_id:商品ID,quantity:购买数量
+     */
+    public function buy_step1Op()
+    {
+        $_POST['goods_id'] = $_POST['cart_id'];
+        $logic_buy_virtual = Logic('buy_virtual');
+        $result = $logic_buy_virtual->getBuyStep2Data($_POST['goods_id'], $_POST['quantity'], $this->member_info['member_id']);
+
+        if (!$result['state']) {
+            output_error($result['msg']);
+        } else {
+            $result = $result['data'];
+        }
+        unset($result['member_info']);
+        output_data($result);
+    }
+
+    /**
+     * 虚拟商品购买第二步,设置接收手机号
+     * POST
+     * 传入:goods_id:商品ID,quantity:购买数量
+     */
+    public function buy_step2Op()
+    {
+        $token = trim($_GET['key']);
+        if (false == $this->checkToken($token)) {
+            return joutput_error($this->err_code);
+        }
+
+        $logic_buy_virtual = Logic('buy_virtual');
+        $result = $logic_buy_virtual->getBuyStep2Data($_POST['goods_id'], $_POST['quantity'], $this->member_info['member_id']);
+        if (!$result['state']) {
+            output_error($result['msg']);
+        } else {
+            $result = $result['data'];
+            $member_info = array();
+            $member_info['member_mobile'] = $result['member_info']['member_mobile'];
+            $member_info['available_predeposit'] = $result['member_info']['available_predeposit'];
+            $member_info['available_rc_balance'] = $result['member_info']['available_rc_balance'];
+            unset($result['member_info']);
+            $result['member_info'] = $member_info;
+            output_data($result);
+        }
+    }
+
+    /**
+     * 虚拟订单第三步,产生订单
+     * POST
+     * 传入:goods_id:商品ID,quantity:购买数量,buyer_phone:接收手机,buyer_msg:下单留言,pd_pay:是否使用预存款支付0否1是,password:支付密码
+     */
+    public function buy_step3Op()
+    {
+        $token = trim($_GET['key']);
+        if (false == $this->checkToken($token)) {
+            return joutput_error($this->err_code);
+        }
+
+        $logic_buy_virtual = Logic('buy_virtual');
+        $input = array();
+        $input['goods_id'] = $_POST['goods_id'];
+        $input['quantity'] = $_POST['quantity'];
+        $input['buyer_phone'] = $_POST['buyer_phone'];
+        $input['buyer_msg'] = $_POST['buyer_msg'];
+        //支付密码
+        $input['password'] = $_POST['password'];
+
+        //是否使用充值卡支付0是/1否
+        $input['rcb_pay'] = intval($_POST['rcb_pay']);
+
+        //是否使用预存款支付0是/1否
+        $input['pd_pay'] = intval($_POST['pd_pay']);
+
+        $input['order_from'] = 2;
+        $result = $logic_buy_virtual->buyStep3($input, $this->member_info['member_id']);
+        if (!$result['state']) {
+            output_error($result['msg']);
+        } else {
+            output_data($result['data']);
+        }
+    }
+}

+ 556 - 0
mapi/control/merchant_info.php

@@ -0,0 +1,556 @@
+<?php
+require_once(BASE_ROOT_PATH . '/mobile/control/merchantweb.php');
+
+class merchant_infoControl extends mbMerchantControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $mchid = $this->mchid();
+        $model_merchant = Model('merchant');
+        $field = 'mchid,admin_id,name,alarm_amount,ip_white_list,use_key,contact_name,contact_phone,warning_phone,company_name,quality,time_out,credit_bonus';
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid], $field);
+        $model_member = Model('member');
+        $member_info = $model_member->getMemberInfo(['member_id' => $merchant_info['admin_id']], 'available_predeposit');
+        if (empty($member_info)) {
+            $member_info['available_predeposit'] = 0;
+        }
+        $merchant_info['member'] = $member_info;
+
+        if (empty($merchant_info['ip_white_list'])) {
+            $merchant_info['ips'] = [];
+        } else {
+            $merchant_info['ips'] = unserialize($merchant_info['ip_white_list']);
+        }
+        if (empty($merchant_info['warning_phone'])) {
+            $merchant_info['warning_phone'] = [];
+        } else {
+            $merchant_info['warning_phone'] = unserialize($merchant_info['warning_phone']);
+        }
+
+        $cond['status'] = $cond['is_operation'] = 2;
+        $cond['mchid'] = $mchid;
+        $stats = Model('')->table('refill_evidence')
+            ->field('sum(amount) as amounts')
+            ->where($cond)->select();
+        $merchant_info['evidence_amounts'] = empty($stats) ? 0 : $stats[0]['amounts'];
+        $cond['add_time'] = ['between', [strtotime(date("Y-m-d",time())), time()]];
+        $day_evidence = $model_merchant->getRefillEvidence($cond);
+        $merchant_info['evidence_count'] = count($day_evidence);
+        $merchant_info['time_out'] = intval($merchant_info['time_out'] / 60);
+        $merchant_info['quality'] = intval($merchant_info['quality']);
+
+//        $pub = new message\publisher();
+//        $pub->modify_refill_merchant();
+
+        return self::outsuccess($merchant_info);
+    }
+
+    public function SetQualityTimeOutOp()
+    {
+        $mchid = $this->mchid();
+        $save = [];
+        $quality = intval($_POST['quality']);
+        if($quality > 0) {
+            if(!in_array($quality , [1,2,3])) {
+                return self::outerr(errcode::ErrParamter, "通道质量类型错误");
+            }
+            $save['quality'] = $quality;
+        }
+        $time_out = intval($_POST['time_out']);
+        if($quality > 0) {
+            if($time_out <3) {
+                return self::outerr(errcode::ErrParamter, "超时时间应大于3分钟");
+            }
+            $time_out = intval($time_out * 60);
+            $save['time_out'] = $time_out;
+        }
+        if(empty($save)) {
+            return self::outsuccess([]);
+        }
+        $model_merchant = Model('merchant');
+        $resp = $model_merchant->editMerchant($save, ['mchid' => $mchid]);
+        if($resp) {
+            return self::outsuccess([]);
+        }else{
+            return self::outerr(errcode::ErrOperation, "系统错误.");
+        }
+    }
+
+    public function homeOp()
+    {
+        $mchid = $this->mchid();
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid], 'mchid,admin_id,name,company_name');
+        $model_member = Model('member');
+        $member_info = $model_member->getMemberInfo(['member_id' => $merchant_info['admin_id']], 'available_predeposit');
+        if (empty($member_info)) {
+            $merchant_info['available_predeposit'] = 0;
+        } else {
+            $merchant_info['available_predeposit'] = ncPriceFormat($member_info['available_predeposit']);
+        }
+
+        $statistics = $this->statistics();
+        ksort($statistics);
+        $result['merchant_info'] = $merchant_info;
+        $result['todayStatistics'] = $statistics[strtotime(date("Y-m-d",time()))];
+        $result['weeksStatistics'] = $statistics;
+        $max = 0;
+        foreach ($statistics as $key => $val){
+            if($max == 0){
+                $max = $val['successAmounts'];
+
+            }
+            if($max < $val['count']){
+                $max = $val['successAmounts'];
+            }
+        }
+        $result['max'] = ncPriceFormat(ceil($max * 1.1));
+        $week_month_stats = $this->refillStats();
+        $result['month'] = $week_month_stats['month'];
+        $result['week'] = $week_month_stats['week'];
+        return self::outsuccess($result);
+    }
+
+    private function statistics()
+    {
+        $date = date('Y-m-d',time());
+        $today = strtotime("{$date}");
+
+        $times_begin = function ($start) {
+            $times = [];
+            $begin = $start;
+            for($i = 0; $i < 7; $i++) {
+                $times[] = $begin;
+                $begin -= 86400;
+            }
+            return $times;
+        };
+
+        $reader = function ($mchid,$time) {
+            $cond['mchid'] = $mchid;
+            $cond['inner_status'] = 0;
+            $cond['refill_order.order_time'] = ['between', [$time, $time + 86400 -1]];
+
+            $items = Model('')->table('refill_order,vr_order')->join('inner')
+                ->on('refill_order.order_id=vr_order.order_id')
+                ->field('count(*) as order_count, vr_order.order_state, sum(mch_amount) as mch_amounts')
+                ->group('order_state')
+                ->where($cond)->select();
+
+            return $this->refillCountDispose($items);
+        };
+
+        $begins = $times_begin($today);
+
+        $states = rcache($this->mchid() , 'refillstat-');
+
+        if(empty($states)){
+            $states = [];
+        }else{
+            $states = unserialize($states['data']);
+        }
+        $result = [];
+        $cache = [];
+        foreach ($begins as $begin)
+        {
+            if(array_key_exists($begin,$states)) {
+                $item = $states[$begin];
+            }
+            else {
+                $item = $reader($this->mchid(),$begin);
+            }
+            $result[$begin] = $item;
+
+            //判断item 中充值中的状态是否为0,为0且不是今天的情况下放进cache
+            if($item['sendCount'] == 0 && $begin != $today){
+                $cache[$begin] = $item;
+            }
+        }
+        if(!empty($cache) && !$this->isSame($states,$cache)) {
+            wcache($this->mchid() ,['data' => serialize($cache)], 'refillstat-');
+        }
+
+        return $result;
+    }
+
+    private function isSame($arr1, $arr2)
+    {
+        ksort($arr1);
+        ksort($arr2);
+        return $arr1 == $arr2;
+    }
+
+    private function refillCountDispose($stats)
+    {
+        $result['count'] = $result['sendCount'] = $result['errorCount'] = $result['successCount'] = $result['amountCount'] = $result['errorAmounts'] = $result['successAmounts'] = 0;
+        foreach ($stats as $count) {
+            $result['count'] += $count['order_count'];
+            $result['amountCount'] += ncPriceFormat($count['mch_amounts']);
+            if($count['order_state'] == ORDER_STATE_SEND) {
+                $result['sendCount'] = $count['order_count'];
+            }
+            if($count['order_state'] == ORDER_STATE_CANCEL) {
+                $result['errorCount'] = $count['order_count'];
+                $result['errorAmounts'] = ncPriceFormat($count['mch_amounts']);
+            }
+            if($count['order_state'] == ORDER_STATE_SUCCESS) {
+                $result['successCount'] = $count['order_count'];
+                $result['successAmounts'] = ncPriceFormat($count['mch_amounts']);
+            }
+        }
+        $result['amountCount'] = ncPriceFormat($result['amountCount']);
+        $result['errorAmounts'] = ncPriceFormat($result['errorAmounts']);
+        $result['successAmounts'] = ncPriceFormat($result['successAmounts']);
+        return $result;
+    }
+
+    private function refillStats()
+    {
+        $reader = function ($mchid,$time,$end_time) {
+            $cond['mchid'] = $mchid;
+            $cond['inner_status'] = 0;
+            $cond['refill_order.order_time'] = ['between', [$time, $end_time]];
+
+            $items = Model('')->table('refill_order,vr_order')->join('inner')
+                ->on('refill_order.order_id=vr_order.order_id')
+                ->field('count(*) as order_count, vr_order.order_state, sum(mch_amount) as mch_amounts')
+                ->group('order_state')
+                ->where($cond)->select();
+
+            return $this->refillCountDispose($items);
+        };
+        $date = date("Y-m-d");
+        $first = 1;
+        $w = date('w',strtotime($date));
+        $week_start = strtotime(date('Y-m-d',strtotime("$date -".($w ? $w - $first : 6).' days')));
+        $w = 7 - $w + 1;
+        $week_end = strtotime(date('Y-m-d',strtotime("+{$w} days"))) - 1;
+        $week = $reader($this->mchid(), $week_start,$week_end);
+
+        $month_start = strtotime(date("Y-m-1"));
+        $month_end = strtotime(date("Y-m-1",strtotime("+1month")))-1;
+        $month = $reader($this->mchid(), $month_start, $month_end);
+
+        return ['week' => $week , 'month' => $month];
+    }
+
+    public function addipOp()
+    {
+        $mchid = $this->mchid();
+        $ip = $_POST['ip'];
+        if (empty($ip)) {
+            return self::outerr(errcode::ErrParamter, "参数错误");
+        }
+        $ip = trim($ip);
+        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
+        {
+            $model_merchant = Model('merchant');
+            $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+            if (empty($merchant_info['ip_white_list'])) {
+                $ips = [];
+            } else {
+                $ips = unserialize($merchant_info['ip_white_list']);
+            }
+
+            $ips[] = $ip;
+            $ips = array_unique($ips);
+
+            $model_merchant->editMerchant(['ip_white_list' => serialize($ips)], ['mchid' => $merchant_info['mchid']]);
+            return self::outsuccess([]);
+        } else {
+            return self::outerr(errcode::ErrParamter, "ip地址错误");
+        }
+    }
+
+    public function ipdelOp()
+    {
+        $mchid = $this->mchid();
+        $ip = $_POST['ip'];
+        if (empty($ip)) {
+            return self::outerr(errcode::ErrParamter, "参数错误");
+        }
+        $ip = trim($ip);
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        $ips = unserialize($merchant_info['ip_white_list']);
+        $new_ips = [];
+        foreach ($ips as $value) {
+            if ($value != $ip) {
+                $new_ips[] = $value;
+            }
+        }
+        if (empty($new_ips)) {
+            $new_ips = '';
+        } else {
+            $new_ips = serialize($new_ips);
+        }
+        $model_merchant->editMerchant(['ip_white_list' => $new_ips], ['mchid' => $merchant_info['mchid']]);
+        return self::outsuccess([]);
+    }
+
+    public function setcontactOp(){
+        $mchid = $this->mchid();
+        if(!empty($_POST['contact_name']))
+        {
+            $params['contact_name'] = trim($_POST['contact_name']);
+        }
+        if(!empty($_POST['contact_phone']))
+        {
+            $params['contact_phone'] = trim($_POST['contact_phone']);
+        }
+        if(!empty($_POST['alarm_amount']))
+        {
+            $params['alarm_amount'] = trim($_POST['alarm_amount']);
+        }
+        if(empty($params))
+        {
+            return self::outsuccess([]);
+        }
+        $model_merchant = Model('merchant');
+        $ret = $model_merchant->editMerchant($params, ['mchid' => $mchid]);
+        if ($ret) {
+            return self::outsuccess([]);
+        } else {
+            return self::outerr(errcode::ErrOperation, "系统错误.");
+        }
+    }
+
+    public function addwphoneOp()
+    {
+        $mchid = $this->mchid();
+        $phone = $_POST['phone'];
+        if (empty($phone)) {
+            return self::outerr(errcode::ErrParamter, "参数错误");
+        }
+        $phone = explode(',' ,trim($phone));
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        if (empty($merchant_info['warning_phone'])) {
+            $phones = [];
+        } else {
+            $phones = unserialize($merchant_info['warning_phone']);
+        }
+        foreach ($phone as $item) {
+            $phones[] = $item;
+        }
+        $phones = array_unique($phones);
+        $model_merchant->editMerchant(['warning_phone' => serialize($phones)], ['mchid' => $merchant_info['mchid']]);
+        return self::outsuccess([]);
+    }
+
+    public function wphonedelOp()
+    {
+        $mchid = $this->mchid();
+        $phone = $_POST['phone'];
+        if (empty($phone)) {
+            return self::outerr(errcode::ErrParamter, "参数错误");
+        }
+        $phone = trim($phone);
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        $phones = unserialize($merchant_info['warning_phone']);
+        $new_phones = [];
+        foreach ($phones as $value) {
+            if ($value != $phone) {
+                $new_phones[] = $value;
+            }
+        }
+        if (empty($new_phones)) {
+            $new_phones = '';
+        } else {
+            $new_phones = serialize($new_phones);
+        }
+        $model_merchant->editMerchant(['warning_phone' => $new_phones], ['mchid' => $merchant_info['mchid']]);
+        return self::outsuccess([]);
+    }
+
+    public function setkeyOp()
+    {
+        $mchid = $this->mchid();
+        $secure_key = $_POST['secure_key'];
+        if (empty($secure_key)) {
+            return self::outerr(errcode::ErrParamter, "参数错误");
+        }
+        $model_merchant = Model('merchant');
+        $ret = $model_merchant->editMerchant(['secure_key' => $secure_key, 'use_key' => 1], ['mchid' => $mchid]);
+        if ($ret) {
+            return self::outsuccess([]);
+        } else {
+            return self::outerr(errcode::ErrOperation, "系统错误.");
+        }
+    }
+
+    public function modifypwOp()
+    {
+        $mchid = $this->mchid();
+        $new_pw = $_POST['new_pw'];
+        $new_pw2 = $_POST['new_pw2'];
+        if (trim($new_pw) !== trim($new_pw2)) {
+            return self::outerr(errcode::ErrPasswd, "密码错误");
+        }
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        if (!$merchant_info) {
+            return self::outerr(errcode::ErrMemberNotExist, "用户不存在.");
+        }
+        $pwd = trim($new_pw);
+        if (md5($pwd) == $merchant_info['password']) {
+            return self::outsuccess([]);
+        }
+        $ret = $model_merchant->editMerchant(['password' => md5($pwd), 'org_pwd' => $pwd], ['mchid' => $merchant_info['mchid']]);
+        if ($ret) {
+            return self::outsuccess([]);
+        } else {
+            return self::outerr(errcode::ErrOperation, "系统错误.");
+        }
+    }
+
+    public function pdlogOp()
+    {
+        $mchid = $this->mchid();
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        if (!$merchant_info) {
+            return self::outerr(errcode::ErrMemberNotExist, "用户不存在.");
+        }
+        $model_pd = Model('merchant');
+        if (empty($merchant_info['admin_id'])) {
+            $result['data'] = [];
+            $result['total'] = 0;
+            return self::outsuccess($result);
+        }
+        $cond['lg_member_id'] = $merchant_info['admin_id'];
+        if (!empty($_GET['lg_type'])) {
+            $cond['lg_type'] = $_GET['lg_type'];
+        }
+        if ($_GET['start_time'] && $_GET['end_time']) {
+            $cond['lg_add_time'] = ['between', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        $list = $model_pd->getPdlog($cond, $this->page, '*', 'lg_id desc');
+        $list = $this->PdLogFormat($list);
+        $result['data'] = $list;
+        $result['total'] = $model_pd->gettotalpage();
+        return self::outsuccess($result);
+    }
+
+    private function PdLogFormat($pdlog)
+    {
+        $data = [];
+        foreach ($pdlog as $key => $value) {
+            if (isset($value['lg_add_time'])) {
+                $value['lg_add_time'] = date('Y-m-d H:i:s', $value['lg_add_time']);
+            }
+            switch ($value['lg_type']) {
+                case 'order_pay':
+                    $value['lg_type_text'] = '下单减款';
+                    break;
+                case 'order_cancel':
+                    $value['lg_type_text'] = '下单失败返回余款';
+                    break;
+                case 'recharge':
+                    $value['lg_type_text'] = '余款充值';
+                    break;
+                case 'sys_add_money':
+                    $value['lg_type_text'] = '管理员调节预存款【增加】';
+                    break;
+                case 'sys_del_money':
+                    $value['lg_type_text'] = '管理员调节预存款【减少】';
+                    break;
+                case 'sys_freeze_money':
+                    $value['lg_type_text'] = '管理员调节预存款【冻结】';
+                    break;
+                case 'sys_unfreeze_money':
+                    $value['lg_type_text'] = '管理员调节预存款【解冻】';
+                    break;
+                default:
+                    $value['lg_type_text'] = 'unknown';
+                    break;
+            }
+            $data[] = $value;
+        }
+        return $data;
+    }
+
+    public function pdlogexportOp()
+    {
+        $mchid = $this->mchid();
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        if (!$merchant_info) {
+            return self::outerr(errcode::ErrMemberNotExist, "用户不存在.");
+        }
+
+
+        $condition['lg_member_id'] = $merchant_info['admin_id'];
+        if (!empty($_GET['lg_type'])) {
+            $condition['lg_type'] = $_GET['lg_type'];
+        }
+        if ($_GET['start_time'] && $_GET['end_time']) {
+            $condition['lg_add_time'] = ['between', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        $list = Model('')->table('pd_log,refill_order')->join('left')
+            ->on('pd_log.lg_order_sn=refill_order.order_sn')
+            ->field('pd_log.lg_type,pd_log.lg_av_amount,pd_log.lg_add_time,refill_order.card_no,refill_order.mchid,refill_order.card_type,pd_log.lg_available,refill_order.refill_amount')
+            ->where($condition)->select();
+        $result = $this->export_pdlog_exec($list);
+        return self::outsuccess($result);
+    }
+
+    private function export_pdlog_exec($list)
+    {
+        $title = [
+            ['value' => '代理商账号'],
+            ['value' => '金额'],
+            ['value' => '账户余额'],
+            ['value' => '交易日期'],
+            ['value' => '类型'],
+            ['value' => '备注']
+        ];
+        $mchid = $this->mchid();
+        $card_type = ['1'=>'中石油' , '2' =>'中石化' , '4' => '移动' , '5' => '联通' , '6' => '电信'];
+        foreach ($list as $value) {
+            if (isset($value['lg_add_time'])) {
+                $value['lg_add_time'] = date('Y-m-d H:i:s', $value['lg_add_time']);
+            }
+            switch ($value['lg_type']) {
+                case 'order_pay':
+                    $value['lg_type_text'] = '消费';
+                    break;
+                case 'order_cancel':
+                    $value['lg_type_text'] = '退款';
+                    break;
+                case 'recharge':
+                    $value['lg_type_text'] = '充值';
+                    break;
+                case 'sys_add_money':
+                    $value['lg_type_text'] = '管理员充值【增加】';
+                    break;
+                case 'sys_del_money':
+                    $value['lg_type_text'] = '管理员减款';
+                    break;
+                default:
+                    $value['lg_type_text'] = '';
+                    break;
+            }
+            $data = [];
+            $str = "{$value['card_no']}-{$card_type[$value['card_type']]}{$value['refill_amount']}元";
+            if(empty($value['card_no']) || empty($value['card_type']) || empty($value['refill_amount'])) {
+                $str = '';
+            }
+            $data[] = ['value' => $mchid];
+            $data[] = ['value' => $value['lg_av_amount']];
+            $data[] = ['value' => ncPriceFormat($value['lg_available'] + $value['lg_av_amount'])];
+            $data[] = ['value' => $value['lg_add_time']];
+            $data[] = ['value' => $value['lg_type_text']];
+            $data[] = ['value' => $str];
+            $datas[] = $data;
+        }
+        Log::record(json_encode($datas),Log::DEBUG);
+        return ['title' => $title , 'data' => $datas];
+    }
+}

+ 54 - 0
mapi/control/merchant_login.php

@@ -0,0 +1,54 @@
+<?php
+
+require_once(BASE_ROOT_PATH . '/mobile/control/merchantweb.php');
+
+//商户后台登录
+class merchant_loginControl extends merchantwebControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function loginOp()
+    {
+        $name = $_POST['name'];
+        $pwd = md5($_POST['password']);
+        $model_merchant = Model('merchant');
+
+        $mch_info = $model_merchant->getMerchantInfo(['name' => $name], '*');
+        if (!empty($mch_info)) {
+            if ($mch_info['password'] != $pwd) {
+                return self::outerr(errcode::ErrPasswd, "密码错误");
+            }
+            if ($mch_info['merchant_state'] != 1) {
+                return self::outerr(errcode::ErrAccountStop, "机构已被关闭,无法登录。");
+            }
+
+            $client_ip = $_SERVER['REMOTE_ADDR'];
+            $model_merchant->editMerchant(['last_login_time' => time(), 'last_login_ip' => $client_ip], ['mchid' => $mch_info['mchid']]);
+
+            $model_member = Model('member');
+            $member_info = $model_member->getMemberInfo(['member_id' => $mch_info['admin_id']], 'available_predeposit');
+
+            $mch_info['member'] = $member_info;
+            if (empty($mch_info['ip_white_list'])) {
+                $mch_info['ips'] = [];
+            } else {
+                $mch_info['ips'] = unserialize($mch_info['ip_white_list']);
+            }
+            $_SESSION['mchid'] = $mch_info['mchid'];
+            $_SESSION['member_id'] = $mch_info['admin_id'];
+
+            return self::outsuccess([]);
+        } else {
+            return self::outerr(errcode::ErrMemberNotExist, "用户不存在.");
+        }
+    }
+
+    public function logoutOp()
+    {
+        setNcCookie('MPHPSESSID', 0, -3600);
+        return self::outsuccess([]);
+    }
+}

+ 289 - 0
mapi/control/merchant_order.php

@@ -0,0 +1,289 @@
+<?php
+require_once(BASE_ROOT_PATH . '/mobile/control/merchantweb.php');
+
+class merchant_orderControl extends mbMerchantControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function listOp()
+    {
+        $model_vr_order = Model('refill_order');
+
+        $cond['mchid'] = $this->mchid();
+        $cond['inner_status'] = 0;
+        if (!empty($_GET['card_type'])) {
+            if(in_array($_GET['card_type'] , ['1' , '2' , '4' , '5' , '6'])) {
+                $cond['refill_order.card_type'] = $_GET['card_type'];
+            }
+            if($_GET['card_type'] == 'oil') {
+                $cond['refill_order.card_type'] = ['in' , ['1' , '2']];
+            }
+            if($_GET['card_type'] == 'phone') {
+                $cond['refill_order.card_type'] = ['in' , ['4' , '5' , '6']];
+            }
+        }
+        if (!empty($_GET['card_no'])) {
+            $cond['refill_order.card_no'] = $_GET['card_no'];
+        }
+        if (!empty($_GET['refill_amount'])) {
+            $cond['refill_order.refill_amount'] = $_GET['refill_amount'];
+        }
+        if (!empty($_GET['mch_order'])) {
+            $cond['refill_order.mch_order'] = $_GET['mch_order'];
+        }
+        if (!empty($_GET['order_sn'])) {
+            $cond['refill_order.order_sn'] = $_GET['order_sn'];
+        }
+        if (in_array($_GET['order_state'], array('0', '30', '40'))) {
+            $cond['vr_order.order_state'] = $_GET['order_state'];
+            if($_GET['order_state'] == 30 && $_GET['time'] == 1){
+                $cond['refill_order.order_time'] = ['lt', (time() - 3600)];
+            }
+        }
+        if ($_GET['start_time'] > 0 && $_GET['end_time'] > 0) {
+            $cond['refill_order.order_time'] = ['between', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        $fields = 'refill_order.*,vr_order.order_state';
+        $order_list = $model_vr_order->getMerchantOrderList($cond, $this->page,0, $fields, 'refill_order.order_id desc');
+        $order_list = $this->merchant_order_format($order_list);
+        $result['data'] = $order_list;
+        $result['total'] = $model_vr_order->gettotalpage();
+        return self::outsuccess($result);
+    }
+
+    public function OrderStatsOp()
+    {
+        if(empty($_GET['time_type']) || empty($_GET['start_time']) || empty($_GET['end_time'])) {
+            return self::outerr(errcode::ErrInputParam, "参数错误.");
+        }
+        $cond['inner_status'] = 0;
+        $time_type = $_GET['time_type'];
+        if ($time_type == 'order_time') {
+            $cond['order_time'] = ['time', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        if ($time_type == 'notify_time') {
+            $cond['notify_time'] = ['time', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        if(empty($cond)) {
+            return self::outerr(errcode::ErrInputParam, "筛选日期类型错误.");
+        }
+        $cond['mchid'] = $this->mchid();
+        $stats = Model('')->table('refill_order,vr_order')->join('inner')
+            ->on('refill_order.order_id=vr_order.order_id')
+            ->field('count(*) as order_count ,sum(refill_amount) as refill_amounts, sum(mch_amount) as mch_amounts, order_state')
+            ->where($cond)->group('order_state')->select();
+
+        $result['count'] = $result['sendCount'] = $result['errorCount'] = $result['successCount'] = $result['refill_amounts'] = $result['mch_amounts'] = 0;
+        foreach ($stats as $stat) {
+            $result['count'] += $stat['order_count'];
+            if($stat['order_state'] == ORDER_STATE_SEND) {
+                $result['sendCount'] = $stat['order_count'];
+            }
+            if($stat['order_state'] == ORDER_STATE_CANCEL) {
+                $result['errorCount'] = $stat['order_count'];
+            }
+            if($stat['order_state'] == ORDER_STATE_SUCCESS) {
+                $result['successCount'] = $stat['order_count'];
+                $result['mch_amounts'] = $stat['mch_amounts'];
+                $result['refill_amounts'] = $stat['refill_amounts'];
+            }
+        }
+        return self::outsuccess($result);
+    }
+
+    private function merchant_order_format($orders)
+    {
+        $data = [];
+        foreach ($orders as $order) {
+            if($order['notify_time'] > 0)
+            {
+                $order['diff_time_text'] = $this->elapse_time($order['notify_time'] - $order['order_time']);
+                $order['diff_time'] = $order['notify_time'] - $order['order_time'];
+            }
+            else
+            {
+                $order['diff_time_text'] = $this->elapse_time(time() - $order['order_time']);
+                $order['diff_time'] = time() - $order['order_time'];
+            }
+            if (isset($order['order_time'])) {
+                $order['order_time'] = date('Y-m-d H:i:s', $order['order_time']);
+            }
+            if (isset($order['notify_time'])) {
+                $order['notify_time'] = date('Y-m-d H:i:s', $order['notify_time']);
+            }
+            if($order['is_retrying'] == 1) {
+                $order['order_state'] = ORDER_STATE_SEND;
+            }
+            if ($order['order_state'] == ORDER_STATE_NEW || $order['order_state'] == ORDER_STATE_PAY) {
+                $order['order_state'] = ORDER_STATE_SEND;
+            }
+            $order['order_state_text'] = $this->_orderState($order['order_state']);
+            $order['card_type_name'] = $this->scard_type($order['card_type']);
+            $data[] = $order;
+        }
+        return $data;
+    }
+
+    /**
+     * 取得订单状态文字输出形式
+     *
+     * @param int $order_state 订单数组
+     * @return string
+     */
+    private function _orderState($order_state)
+    {
+        switch ($order_state) {
+            case ORDER_STATE_CANCEL:
+                $text = '已取消';
+                break;
+            case ORDER_STATE_NEW:
+                $text = '新订单';
+                break;
+            case ORDER_STATE_SEND:
+                $text = '充值中';
+                break;
+            case ORDER_STATE_PAY:
+                $text = '支付成功';
+                break;
+            case ORDER_STATE_SUCCESS:
+                $text = '充值成功';
+                break;
+            case 'retrying':
+                $text = '重试中';
+                break;
+            default:
+                $text = '未知状态';
+        }
+        return $text;
+    }
+
+    private function scard_type(int $card_type)
+    {
+        if ($card_type == mtopcard\PetroChinaCard) { //中石油
+            return '中石油';
+        } elseif ($card_type == mtopcard\SinopecCard) { //中石化
+            return '中石化';
+        } elseif ($card_type == mtopcard\ChinaMobileCard) { //中国移动
+            return '中国移动';
+        } elseif ($card_type == mtopcard\ChinaUnicomCard) { //中国联通
+            return '中国联通';
+        } elseif ($card_type == mtopcard\ChinaTelecomCard) { //中国电信
+            return '中国电信';
+        } elseif ($card_type == mtopcard\ThirdRefillCard) { //中国电信
+            return '增值业务';
+        } else {
+            return 'unknown';
+        }
+    }
+
+    private function elapse_time($seconds)
+    {
+        $minutes = intval($seconds / 60);
+        $second = intval($seconds % 60);
+        if($minutes >= 60) {
+            $minute = $minutes % 60;
+            $hours = intval($minutes / 60);
+            $result = "{$minute}:{$second}";
+        }
+        else {
+            if($minutes > 0){
+                $result = "{$minutes}:{$second}";
+            }else{
+                $result = "{$second}";
+            }
+        }
+        if(isset($hours))
+        {
+            $result = "{$hours}:" . $result;
+        }
+        return $result;
+    }
+
+    public function OrderExportOp()
+    {
+        $model_vr_order = Model('refill_order');
+
+        $cond['mchid'] = $this->mchid();
+        $cond['inner_status'] = 0;
+        if (!empty($_GET['card_type'])) {
+            if(in_array($_GET['card_type'] , ['1' , '2' , '4' , '5' , '6'])) {
+                $cond['refill_order.card_type'] = $_GET['card_type'];
+            }
+            if($_GET['card_type'] == 'oil') {
+                $cond['refill_order.card_type'] = ['in' , ['1' , '2']];
+            }
+            if($_GET['card_type'] == 'phone') {
+                $cond['refill_order.card_type'] = ['in' , ['4' , '5' , '6']];
+            }
+        }
+        if (!empty($_GET['card_no'])) {
+            $cond['refill_order.card_no'] = $_GET['card_no'];
+        }
+        if (!empty($_GET['refill_amount'])) {
+            $cond['refill_order.refill_amount'] = $_GET['refill_amount'];
+        }
+        if (!empty($_GET['mch_order'])) {
+            $cond['refill_order.mch_order'] = $_GET['mch_order'];
+        }
+        if (!empty($_GET['order_sn'])) {
+            $cond['refill_order.order_sn'] = $_GET['order_sn'];
+        }
+        if (in_array($_GET['order_state'], array('0', '30', '40'))) {
+            $cond['vr_order.order_state'] = $_GET['order_state'];
+            if($_GET['order_state'] == 30 && $_GET['time'] == 1){
+                $cond['refill_order.order_time'] = ['lt', (time() - 3600)];
+            }
+        }
+        if ($_GET['start_time'] > 0 && $_GET['end_time'] > 0) {
+            $cond['refill_order.order_time'] = ['time', [$_GET['start_time'], $_GET['end_time']]];
+        }
+        $fields = 'refill_order.*,vr_order.order_state';
+        $order_list = $model_vr_order->getMerchantOrderList($cond, '10000',0, $fields, 'refill_order.order_id desc');
+        $order_list = $this->merchant_order_format($order_list);
+
+        $result = $this->export_order_exec($order_list);
+        return self::outsuccess($result);
+    }
+
+    private function export_order_exec($order_list)
+    {
+        $title = [
+            ['value' => '代理商账号'],
+            ['value' => '商品名称'],
+            ['value' => '交易账号'],
+            ['value' => '交易金额'],
+            ['value' => '交易面值'],
+            ['value' => '交易日期'],
+            ['value' => '交易状态'],
+            ['value' => '处理时间'],
+            ['value' => '第三方流水']
+        ];
+        $card_type = ['1'=>'中石油' , '2' =>'中石化' , '4' => '移动' , '5' => '联通' , '6' => '电信'];
+        foreach ($order_list as $order) {
+            $data = [];
+            $official_sn = $order['official_sn'];
+            $notify_time = $order['$notify_time'];
+            if(empty($order['official_sn'])) {
+                $official_sn = '';
+            }
+            if(empty($order['$notify_time'])) {
+                $notify_time = '';
+            }
+            $data[] = ['value' => $order['mchid']];
+            $data[] = ['value' => "{$card_type[$order['card_type']]}{$order['refill_amount']}元"];
+            $data[] = ['value' => $order['card_no']];
+            $data[] = ['value' => $order['mch_amount']];
+            $data[] = ['value' => $order['refill_amount']];
+            $data[] = ['value' => $order['order_time']];
+            $data[] = ['value' => $order['order_state_text']];
+            $data[] = ['value' => $notify_time];
+            $data[] = ['value' => $official_sn];
+            $datas[] = $data;
+        }
+        Log::record(json_encode($datas),Log::DEBUG);
+        return ['title' => $title , 'data' => $datas];
+    }
+}

+ 133 - 0
mapi/control/merchant_refill.php

@@ -0,0 +1,133 @@
+<?php
+
+require_once(BASE_ROOT_PATH . '/mobile/control/merchantweb.php');
+require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
+require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
+
+class merchant_refillControl extends mbMerchantControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function goodsOp()
+    {
+        $goods = refill\RefillFactory::instance()->goods();
+
+        $result['oil_amount'] = [];
+        $result['phone_amount'] = [];
+        foreach ($goods as $type => $specs)
+        {
+            if($type == mtopcard\SinopecCard || $type == mtopcard\PetroChinaCard) {
+                foreach ($specs as $spec) {
+                    $result['oil_amount'][] = $spec;
+                }
+            }
+            else {
+                foreach ($specs as $spec) {
+                    $result['phone_amount'][] = $spec;
+                }
+            }
+        }
+
+        $oil_amount = array_unique($result['oil_amount']);
+        sort($oil_amount);
+        $phone_amount = array_unique($result['phone_amount']);
+        sort($phone_amount);
+
+        return self::outsuccess(['oil_amount' => $oil_amount,'phone_amount' => $phone_amount]);
+    }
+
+    private function check_params($params)
+    {
+        if(empty($params['cardno'])) {
+            return [false,'参数没有包含cardno'];
+        }
+        if(empty($params['amount'])) {
+            return [false,'参数没有包含充值金额:amount'];
+        }
+
+        $card_no = $params['cardno'];
+        $card_type = mtopcard\card_type($card_no,$regin_no);
+
+        if($card_type == mtopcard\UnknownCard) {
+            return [false,'卡类型无法识别'];
+        }
+
+        return [true,""];
+    }
+
+    public function addOp()
+    {
+        $params = $_POST;
+
+        $mchid = $this->mchid();
+        $model_merchant = Model('merchant');
+        $merchant_info = $model_merchant->getMerchantInfo(['mchid' => $mchid]);
+        if (empty($merchant_info)) {
+            return self::outerr(errcode::ErrMemberNotExist, "用户不存在.");
+        }
+
+        $amount = intval($params['amount']);
+        $card_nos = trim($params['cardno']);
+        $card_nos = explode(',' , $card_nos);
+        if(empty($card_nos)){
+            return self::outerr(errcode::ErrParamter, "卡号格式错误或未上传");
+        }
+
+        //成功个数、失败个数
+        $success_no = $error_no = 0;
+        $data = [];
+        $all_no = count($card_nos);
+        foreach ($card_nos as $no)
+        {
+            $params['cardno'] = $no;
+            [$success,$error] = $this->check_params($params);
+
+            if($success === false) {
+                $error_no++;
+                $arr['state'] = 201;
+                $arr['err'] = $error;
+            }
+            else
+            {
+                Log::record("no = {$no}",Log::DEBUG);
+                $params = [ 'mchid' => $this->mchid(),
+                    'buyer_id' => intval($merchant_info['admin_id']),
+                    'amount' => $amount,
+                    'card_no' => $no,
+                    'order_time' => time(),
+                    'mch_order' => "",
+                    'notify_url' => ""];
+
+                $card_type = mtopcard\simple_card_type($no);
+                [$can_refill, $period] = refill\util::can_commit($no, $card_type);
+                if ($can_refill === false) {
+                    $ret = refill\util::async_add($params, $period);
+                } else {
+                    $ret = refill\util::push_add($params);
+                }
+
+                if($ret) {
+                    $arr['state'] = $ret;
+                    $arr['err'] = '';
+                    $success_no++;
+                }
+                else {
+                    $arr['state'] = 202;
+                    $arr['err'] = '提交失败';
+                    $error_no++;
+                }
+            }
+            $arr['card_no'] = $no;
+            $arr['amount'] = $amount;
+            $data[] = $arr;
+        }
+        $result['success_no'] = $success_no;
+        $result['error_no'] = $error_no;
+        $result['all_no'] = $all_no;
+        $result['data'] = $data;
+        return self::outsuccess($result);
+    }
+}

+ 159 - 0
mapi/control/merchantweb.php

@@ -0,0 +1,159 @@
+<?php
+
+require_once(BASE_HELPER_PATH . "/session_helper.php");
+
+class merchantwebControl
+{
+    //列表默认分页数
+    protected $page;
+    protected $cur_page;
+    //任务开始时间
+    private static $startime = 0;
+
+    public function __construct()
+    {
+        $_SESSION['client_type'] = $_GET['client_type'];
+        if (is_numeric($_GET['page']) && intval(trim($_GET['page'])) > 0) {
+            $this->page = intval(trim($_GET['page']));
+        } else {
+            $this->page = 10;
+        }
+
+        if (is_numeric($_GET['curpage']) && intval(trim($_GET['curpage'])) > 0) {
+            $this->cur_page = intval(trim($_GET['curpage']));
+        } else {
+            $this->cur_page = 1;
+        }
+        $this->initpage($this->page, $this->cur_page);
+    }
+
+
+    public static function outerr($code, $msg = '', $page = '', $type = 'ajax')
+    {
+        static $json_clients = ['android', 'ios', 'mini'];
+
+        if (!empty($type)) {
+            $show_type = $type;
+        } else {
+            $show_type = $_SESSION['client_type'];
+        }
+
+        if (in_array($show_type, $json_clients)) {
+            joutput_error($code, $msg);
+        } elseif ($show_type == 'wap') {
+            Tpl::clear();
+            Tpl::output("error", $msg);
+            if (!empty($page)) {
+                Tpl::showpage($page);
+            }
+        } elseif ($show_type == 'ajax') {
+            $callback = $_GET['callback'];
+            if (!isset($callback) || empty($callback)) {
+                joutput_error($code, $msg);
+            } else {
+                echo "{$callback}(";
+                joutput_error($code, $msg);
+                echo ");";
+            }
+        } else {
+            if (empty($msg)) {
+                $msg = errcode::msg($code);
+            }
+            $start = microtime(true);
+            echo joutput_error($code, $msg, 'web') . "<br/>";
+            perfor_period("joutput", $start, "web");
+
+            echo sprintf("eclipse_time = %.6f <br/><br/>", self::eclipse_time());
+            echo "性能关键统计:<br/><br/>";
+            echo perfor_log();
+
+            $sqls = Log::sql_log();
+            echo "sql count = " . count($sqls) . "<br/><br/>";
+            foreach ($sqls as $sql) {
+                echo "{$sql}<br/>";
+            }
+        }
+        return true;
+    }
+
+    public static function outsuccess($data, $page = '', $type = NULL)
+    {
+        static $json_clients = ['android', 'ios', 'mini'];
+
+        if (!empty($type)) {
+            $show_type = $type;
+        } else {
+            $show_type = $_SESSION['client_type'];
+        }
+
+        if (in_array($show_type, $json_clients)) {
+            joutput_data($data);
+        } elseif ($show_type == 'wap') {
+            Tpl::clear();
+            if (is_array($data)) {
+                foreach ($data as $key => $val) {
+                    Tpl::output($key, $val);
+                }
+            }
+            if (!empty($page)) {
+                Tpl::showpage($page);
+            }
+        } elseif ($show_type == 'ajax') {
+            $callback = $_GET['callback'];
+            if (!isset($callback) || empty($callback)) {
+                joutput_data($data);
+            } else {
+                echo "{$callback}(";
+                joutput_data($data);
+                echo ");";
+            }
+        } else {
+            echo 'success: return data=<br/>';
+            $start = microtime(true);
+            joutput_data($data, 'web');
+            perfor_period("joutput", $start, "web");
+
+            echo "<br/><br/>";
+            echo sprintf("eclipse_time = %.6f <br/><br/>", self::eclipse_time());
+            echo "性能关键统计:<br/><br/>";
+            echo perfor_log();
+            $sqls = Log::sql_log();
+            echo "sql count = " . count($sqls) . "<br/><br/>";
+
+            foreach ($sqls as $sql) {
+                echo "{$sql}<br/>";
+            }
+        }
+
+        return true;
+    }
+    private static function eclipse_time()
+    {
+        return (microtime(true) - self::$startime);
+    }
+
+    protected function initpage($page_size, $cur_page)
+    {
+        pagecmd('seteachnum', $page_size);
+        pagecmd('setnowpage', $cur_page);
+    }
+}
+
+class mbMerchantControl extends merchantwebControl
+{
+    public $err_code = errcode::Success;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        if (empty($_SESSION['mchid'])) {
+            throw new UnloginException();
+        }
+    }
+
+    public function mchid()
+    {
+        return intval($_SESSION['mchid']);
+    }
+}

+ 264 - 0
mapi/control/mshop.php

@@ -0,0 +1,264 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/6/13
+ * Time: 下午3:51
+ */
+
+use bonus\account;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/index_tab.php');
+require_once(BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/mobile/control/special.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/signaturer.php');
+require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+
+class mshopControl extends specialControl
+{
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $this->topup();
+
+        if(session_helper::need_wechat_author())
+        {
+            $url = BASE_SITE_URL . "/mobile/index.php?act=mshop&op=index";
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+        } else {
+            $url = BASE_SITE_URL . "/mshop/";
+        }
+        Log::record("url={$url}",Log::DEBUG);
+
+        return self::outsuccess(['direct_uri' => $url],"redirect");
+    }
+
+    public function authorOp()
+    {
+        $url = $_GET['url'];
+
+        $msg = "跳转的地址不能为空.";
+        if(empty($url)) {
+            return self::outerr(errcode::ErrParamter,$msg);
+        }
+        $url = urldecode($url);
+        if(empty($url)) {
+            return self::outerr(errcode::ErrParamter,$msg);
+        }
+
+        if(session_helper::need_wechat_author())
+        {
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+        else {
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+    }
+
+    public function tabsOp()
+    {
+        return self::outsuccess(['tabs' => [['special_id' => 0,'name' => "首页"]]]);
+    }
+
+    public function goodsOp()
+    {
+        $this->topup();
+        $goods_id = intval($_GET['goods_id']);
+
+        $relay_id = session_helper::relay_id();
+        fcgi_setcookie("relay_id","{$relay_id}",time() + 86400,'/',COOKIE_DOMAIN);
+
+        if(session_helper::need_wechat_author())
+        {
+            $url = url_helper::mshop_goods($goods_id);
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+        else
+        {
+            if($goods_id <= 0) {
+                $url = BASE_SITE_URL . "/mshop";
+            }
+            else {
+                $url = BASE_SITE_URL . "/mshop/goods_detail?goods_id={$goods_id}";
+            }
+
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+    }
+
+    public function specialOp()
+    {
+        $this->topup();
+
+        $special_id = intval($_GET['special_id']);
+        $title = $_GET['title'];
+
+        $relay_id = session_helper::relay_id();
+        fcgi_setcookie("relay_id","{$relay_id}",time() + 86400,'/',COOKIE_DOMAIN);
+
+        if(session_helper::need_wechat_author())
+        {
+            $url = BASE_SITE_URL . "/mobile/index.php?act=mshop&op=special&special_id={$special_id}&title={$title}";
+            $author = new thrid_author\wxauthor();
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+        else
+        {
+            if($special_id <= 0) {
+                $url = BASE_SITE_URL . "/mshop";
+            }
+            else
+            {
+                if(empty($title)) {
+                    $title = $this->special_name($special_id);
+                    $title = util::base64url_encode($title);
+                }
+
+                $url = BASE_SITE_URL . "/mshop/special?special_id={$special_id}&is_special=true&title={$title}";
+            }
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+    }
+
+    private function special_name($special_id)
+    {
+        $mod = Model('mb_special');
+        $special = $mod->getMbSpecialList(['special_id' => $special_id]);
+        if(empty($special)) return false;
+        return $special[0]['special_desc'];
+    }
+
+    private function special_shareimg($special_id)
+    {
+        $defimg = RESOURCE_SITE_URL . "/mobile/defimg/panda.jpeg";
+
+
+        $mod = Model('mb_special');
+        $special = $mod->getMbSpecialList(['special_id' => $special_id]);
+        if(empty($special)) return $defimg;
+
+        $share_img = $special[0]['share_image'];
+        if(empty($share_img)) {
+            return $defimg;
+        } else {
+            return $share_img;
+        }
+    }
+
+    public function signurlOp()
+    {
+        $sign_url = urldecode($_GET['sign_url']);
+
+        if(empty($sign_url)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        Log::record("signurl={$sign_url}",Log::DEBUG);
+        $result = thrid_author\signaturer::instance()->signurl($sign_url);
+        if($result == false) {
+            return self::outerr(errcode::ErrAuthor);
+        } else {
+            return self::outsuccess($result);
+        }
+    }
+    public function testOp()
+    {
+        return self::outsuccess("",'signature');
+    }
+
+    public function shareOp()
+    {
+        $type  = $_GET['type'];
+        $valid = intval($_GET['data']);
+
+        if(empty($type) || $valid <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $success = false;
+        if($type == 'special')
+        {
+            $url = url_helper::mshop_special($valid);
+
+            $title = $this->special_name($valid);
+            if($title != false) {
+                $success = true;
+                $sub_title = "椰子 内买商城\n\n点击浏览";
+                $img_url = $this->special_shareimg($valid);
+                $mini_url = "pages/special/special?title={$title}&special_id={$valid}";
+            } else {
+                $mini_url = "pages/special/special?special_id={$valid}";
+            }
+        }
+        elseif($type == 'goods')
+        {
+            $url = url_helper::mshop_goods($valid);
+            $goods_info = $this->goods_share($valid);
+            if ($goods_info != false)
+            {
+                $success = true;
+                $name = $goods_info['goods_mobile_name'];
+                if (session_helper::logined()) {
+                    $nick_name = session_helper::nickname();
+                    $title = "{$nick_name}向您推荐 {$name}";
+                } else {
+                    $title = "熊猫美妆向您推荐{$name}";;
+                }
+                $tip = $goods_info['goods_jingle'];
+                if(empty($title)) {
+                    $sub_title = "椰子 内买商城\n\n点击浏览";
+                } else {
+                    $sub_title = "{$tip}\n\n点击浏览";
+                }
+
+                $img_url = $this->img_url($goods_info['goods_image'],$goods_info['store_id']);
+                $mini_url = "pages/details/details?goods_id={$valid}";
+            }
+        }
+
+        if($success == false) {
+            return self::outerr(errcode::ErrParamter);
+        } else {
+            return self::outsuccess(['url' => $url,'title' => $title,'sub_title' => $sub_title,'img_url' => $img_url,'path' => $mini_url]);
+        }
+    }
+
+    private function goods_share($goods_id)
+    {
+        $mod_goods = Model('goods');
+        $info = $mod_goods->getGoodsInfoByID($goods_id);
+        if(empty($info)) {
+            return false;
+        } else {
+            return $info;
+        }
+    }
+    private function img_url($value,$store_id)
+    {
+        return cthumb($value, 240, $store_id);
+    }
+
+    private function topup()
+    {
+        if(session_helper::logined()) {
+            $pred = new account($_SESSION['member_id'],true);
+            $pred->topup_bonus($_SESSION['member_mobile']);
+        }
+    }
+}

+ 32 - 0
mapi/control/mtest.php

@@ -0,0 +1,32 @@
+<?php
+
+defined('InShopNC') or exit('Access Invalid!');
+
+define('MOBILE_SERVER',true);
+
+class mtestControl extends mobileControl
+{
+    public function sqlOp()
+    {
+        $mod_detail = Model('refill_detail');
+        $mod_detail->getDetailInfo(['detail_id' => 1]);
+        return $this->outsuccess([]);
+    }
+
+    public function transOp()
+    {
+        try {
+            $mod_detail = Model('refill_detail');
+            $trans = new trans_wapper($mod_detail,__METHOD__);
+//            $mod_detail->getDetailInfo(['detail_id' => 1]);
+            $trans->commit();
+
+        }
+        catch (Exception $ex)
+        {
+            $trans->rollback();
+        }
+
+        return $this->outsuccess([]);
+    }
+}

+ 44 - 0
mapi/control/patch.php

@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: dell
+ * Date: 2016/2/29
+ * Time: 14:17
+ */
+
+class patchControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function getpatchOp()
+    {
+        $version = trim($_GET['version']);
+        if (!isset($version) || empty($version)) {
+            return joutput_error(errcode::ErrInputParam);
+        }
+
+        $condition = array();
+        $condition['ver_name'] = $version;
+        $condition['enable'] = 1;
+
+        $model = Model('patch');
+        $result = $model->getSingleItemByVerName($condition);
+
+        $ret = array();
+        if (!empty($result)) {
+            $ret['version'] = $version;
+            $ret['patch_code'] = $result['patch_code'];
+            $ret['patch_url'] = $result['patch_url'];
+        } else {
+            $ret['version'] = $version;
+        }
+
+        self::outsuccess($ret);
+    }
+}
+
+

+ 48 - 0
mapi/control/pay_return.php

@@ -0,0 +1,48 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2016/10/17
+ * Time: 下午4:42
+ */
+
+class pay_returnControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function cmbpayOp()
+    {
+        $pay_sn = $_GET['pay_sn'];
+        $order_sn = $_GET['order_sn'];
+        $member_id = intval($_GET['member_id']);
+
+        if(empty($pay_sn) || empty($order_sn) || $member_id <= 0) {
+            return self::outsuccess(array("pay_state" => 'no_order',),"pay/cmbret",'wap');
+        }
+        else
+        {
+            $mod_order = Model('order');
+            $condition = array();
+            $condition['buyer_id'] = $member_id;
+            $condition['pay_sn'] = $pay_sn;
+
+            $order = $mod_order->getNormalOrderList($condition, $this->page_size, '*');
+            if(empty($order)) {
+                return self::outsuccess(array("pay_state" => "no_order"),"pay/cmbret",'wap');
+            }
+            else
+            {
+                $state = intval($order['order_state']);
+                $paied = array(ORDER_STATE_PAY,ORDER_STATE_SEND,ORDER_STATE_SUCCESS);
+                if(in_array($state,$paied)) {
+                    return self::outsuccess(array("pay_state" => "success",'pay_sn' => $pay_sn),"pay/cmbret",'wap');
+                } else {
+                    return self::outsuccess(array("pay_state" => "unpaied",'pay_sn' => $pay_sn),"pay/cmbret",'wap');
+                }
+            }
+        }
+    }
+}

+ 228 - 0
mapi/control/payment.php

@@ -0,0 +1,228 @@
+<?php
+/**
+ * 支付回调
+ *
+ *
+ *
+ *
+ * by 33hao.com 好商城V3 运营版
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class paymentControl extends mobileHomeControl{
+
+    private $payment_code;
+
+	public function __construct() {
+		parent::__construct();
+
+        $this->payment_code = $_GET['payment_code'];
+	}
+
+    public function returnopenidOp(){
+        $payment_api = $this->_get_payment_api();
+        if($this->payment_code != 'wxpay'){
+            output_error('支付参数异常');
+            die;
+        }
+
+        $payment_api->getopenid();
+    }
+
+
+    /**
+     * 支付回调
+     */
+    public function returnOp()
+    {
+        unset($_GET['act']);
+        unset($_GET['op']);
+        unset($_GET['payment_code']);
+
+        $payment_api = $this->_get_payment_api();
+        $payment_config = $this->_get_payment_config();
+
+        $callback_info = $payment_api->getReturnInfo($payment_config);
+
+        if($callback_info)
+        {
+            //验证成功
+            $result = $this->_update_order($callback_info['out_trade_no'], $callback_info['trade_no']);
+            if($result['state']) {
+                Tpl::output('result', 'success');
+                Tpl::output('message', '支付成功');
+            } else {
+                Tpl::output('result', 'fail');
+                Tpl::output('message', '支付失败');
+			}
+        } else {
+			//验证失败
+            Tpl::output('result', 'fail');
+            Tpl::output('message', '支付失败');
+		}
+
+        Tpl::showpage('payment_message');
+    }
+
+    /**
+     * 支付提醒
+     */
+    public function notifyOp()
+    {
+        // 恢复框架编码的post值
+        $_POST['notify_data'] = html_entity_decode($_POST['notify_data']);
+
+        $payment_api = $this->_get_payment_api();
+
+        $payment_config = $this->_get_payment_config();
+
+        $callback_info = $payment_api->getNotifyInfo($payment_config);
+
+        if($callback_info) {
+            //验证成功
+            $result = $this->_update_order($callback_info['out_trade_no'], $callback_info['trade_no']);
+            if($result['state']) {
+                if($this->payment_code == 'wxpay'){
+                    echo $callback_info['returnXml'];
+                    die;
+                }else{
+                    echo 'success';die;
+                }
+
+            }
+		}
+
+        //验证失败
+        if($this->payment_code == 'wxpay'){
+            echo '<xml><return_code><!--[CDATA[FAIL]]--></return_code></xml>';
+            die;
+        }else{
+            echo "fail";die;
+        }
+    }
+
+    /**
+     * 获取支付接口实例
+     */
+    private function _get_payment_api() {
+        $inc_file = BASE_PATH.DS.'api'.DS.'payment'.DS.$this->payment_code.DS.$this->payment_code.'.php';
+
+        if(is_file($inc_file)) {
+            require($inc_file);
+        }
+
+        $payment_api = new $this->payment_code();
+
+        return $payment_api;
+    }
+
+    /**
+     * 获取支付接口信息
+     */
+    private function _get_payment_config() {
+        $model_mb_payment = Model('mb_payment');
+
+        //读取接口配置信息
+        $condition = array();
+        $condition['payment_code'] = $this->payment_code;
+        $payment_info = $model_mb_payment->getMbPaymentOpenInfo($condition);
+        
+        return $payment_info['payment_config'];
+    }
+
+    /**
+     * 更新订单状态
+     */
+    private function _update_order($out_trade_no, $trade_no)
+    {
+        $model_order = Model('order');
+        $logic_payment = Logic('payment');
+
+        $tmp = explode('|', $out_trade_no);
+        $out_trade_no = $tmp[0];
+        if (!empty($tmp[1])) {
+            $order_type = $tmp[1];
+        } else {
+            $order_pay_info = Model('order')->getOrderPayInfo(array('pay_sn'=> $out_trade_no));
+            if(empty($order_pay_info)){
+                $order_type = 'v';
+            } else {
+                $order_type = 'r';
+            }
+        }
+
+        if ($order_type == 'r') {
+            $result = $logic_payment->getRealOrderInfo($out_trade_no);
+            if (intval($result['data']['api_pay_state'])) {
+                return array('state'=>true);
+            }
+            $order_list = $result['data']['order_list'];
+            $result = $logic_payment->updateRealOrder($out_trade_no, $this->payment_code, $order_list, $trade_no);
+
+        } elseif ($order_type == 'v') {
+        	$result = $logic_payment->getVrOrderInfo($out_trade_no);
+	        if ($result['data']['order_state'] != ORDER_STATE_NEW) {
+	            return array('state'=>true);
+	        }
+	        $result = $logic_payment->updateVrOrder($out_trade_no, $this->payment_code, $result['data'], $trade_no);
+        }
+
+        return $result;
+    }
+	
+	/**
+     * 支付回调
+     */
+    public function wxpayreturnOp()
+    {
+        unset($_GET['act']);
+        unset($_GET['op']);
+        unset($_GET['payment_code']);
+
+        $result_code= $_GET['result_code'] ;
+        $out_trade_no=$_GET['out_trade_no'] ;
+        $transaction_id=$_GET['transaction_id'] ;
+
+        if($result_code == "FAIL"){
+            Tpl::output('result', 'fail');
+            Tpl::output('message', '支付失败');
+        }
+        else {
+            //验证成功
+            $result = $this->_update_order($out_trade_no, $transaction_id);
+            if ($result['state']) {
+                Tpl::output('result', 'success');
+                Tpl::output('message', '支付成功');
+            } else {
+                Tpl::output('result', 'fail');
+                Tpl::output('message', '支付失败');
+            }
+        }
+
+        Tpl::showpage('payment_message');
+    }
+	
+    /**
+     * 微信支付提醒
+     */
+    public function wxpaynotifyOp()
+    {
+        // 恢复框架编码的post值
+        $result_code= $_GET['result_code'] ;
+        $out_trade_no=$_GET['out_trade_no'] ;
+        $transaction_id=$_GET['transaction_id'] ;
+
+        if($result_code!= "FAIL") {
+            //验证成功
+            $result = $this->_update_order($out_trade_no, $transaction_id);
+            if($result['state']) {
+                echo 'success';die;
+            }
+        }
+        //验证失败
+        echo "fail";die;
+    }
+}

+ 158 - 0
mapi/control/rank_list.php

@@ -0,0 +1,158 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/7/26
+ * Time: 上午11:00
+ */
+
+class rank_listControl extends mobileControl
+{
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $list_sn = $_GET['list_sn'];
+        if(!isset($list_sn) || empty($list_sn)) {
+            return self::outerr(errcode::ErrParamter,'请输入排行榜序列号.');
+        }
+
+        $items = ranklist_helper::gen_ranklist($list_sn,$userid,$err);
+        if($items == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+
+        $mids = array();
+        $list_infos = array();
+        $rank_num = 1;
+        $mine = null;
+
+        if(!empty($items)) {
+            $list_date = $items[0]['list_date'];
+        } else {
+            $list_date = '';
+        }
+
+        foreach ($items as $item) {
+            $rank = ranklist::create_by_store($item);
+
+            $item = array();
+            $item['supported'] = $this->supported($rank->list_sn());
+            $item['list_sn'] = $rank->list_sn();
+            $item['supports'] = $rank->supports();
+            $item['list_value'] = $rank->money();
+            $item['member_id'] = $rank->member_id();
+            $item['rank'] = $rank_num;
+
+            array_push($list_infos,$item);
+            array_push($mids,$rank->member_id());
+            if($userid == $rank->member_id()) {
+                $mine = $item;
+            }
+            ++$rank_num;
+        }
+
+        $mine_desc = null;
+        $mem_desc = array();
+        $members = Model('member')->getMemberList(array('member_id' => array('in',$mids)));
+        foreach ($members as $val)
+        {
+            $info = new member_info($val);
+            array_push($mem_desc,$info->filter());
+            if($val['member_id'] == $mine['member_id']) {
+                $mine_desc = $info;
+            }
+        }
+
+        $title = $mine_desc->nickname() . "的" . strftime("熊猫美妆%m月%d日红包风云榜",intval($list_date));
+        return self::outsuccess(array('mine' => $mine,'list_infos' => $list_infos,'mem_desc' => $mem_desc,'rank_title' => $title),"bonus/ranklist");
+    }
+
+    public function supportOp()
+    {
+        $list_sn = $_GET['list_sn'];
+        if(!isset($list_sn) || empty($list_sn)) {
+            return self::outerr(errcode::ErrParamter,'请输入排行榜序列号.');
+        }
+
+        $rank = ranklist::create_by_sn($list_sn);
+        if($rank == false) {
+            return self::outerr(errcode::ErrParamter,'该排行榜不存在或者已经过期~');
+        }
+
+
+        if($this->supported($list_sn)) {
+            $rank->unsupport();
+            $_SESSION['rank_list'][$list_sn]['supported'] = false;
+        } else {
+            $rank->support();
+            $_SESSION['rank_list'][$list_sn]['supported'] = true;
+        }
+
+        return self::outsuccess(array('supports' => $rank->supports(),'list_sn' => $rank->list_sn()));
+    }
+
+    private function supported($list_sn)
+    {
+        if(!isset($_SESSION['rank_list'])) {
+            $_SESSION['rank_list'] = array();
+        }
+
+        if(array_key_exists($list_sn,$_SESSION['rank_list']) == false) {
+            $_SESSION['rank_list'][$list_sn] = array();
+            $_SESSION['rank_list'][$list_sn]['supported'] = false;
+        }
+
+        return boolval($_SESSION['rank_list'][$list_sn]['supported']);
+    }
+}
+
+function bonus_output_meminfo($mid,$mdescs)
+{
+    foreach ($mdescs as $info) {
+        if($info['member_id'] == $mid) {
+            return $info;
+        }
+    }
+
+    return false;
+}
+
+function bonus_output_rankitem($item,$mdescs,$mine_id)
+{
+    $mid = $item['member_id'];
+    $minfo = bonus_output_meminfo($mid,$mdescs);
+
+    echo '<div class="list_li overflow">';
+    echo    '<div class="index float_l w-8">' .$item['rank']. '</div>';
+    echo    '<div class="icon_header float_l w-12 margin-r-1">';
+    echo        '<img src="' . $minfo['avatar'] .'" alt=""/>';
+    echo    '</div>';
+    echo    '<div class="msg float_l w-80 relative_li">';
+    echo        '<div class="name text_l w-45 float_l overflow">' . $minfo['nickname'] . '</div>';
+    echo        '<div class="number text_r w-35 float_l">' . $item['list_value'] .'元</div>';
+    if($item['supported'] == true)
+    {
+        if($mid == $mine_id) {
+            echo '<div class="float_l w-20 concern_box concern_box_active mine">';
+        } else {
+            echo '<div class="float_l w-20 concern_box concern_box_active">';
+        }
+    }
+    else
+    {
+        if($mid == $mine_id) {
+            echo    '<div class="float_l w-20 concern_box mine">';
+        } else {
+            echo    '<div class="float_l w-20 concern_box">';
+        }
+    }
+    echo                '<div class="concern">' . $item['supports'] .'</div>';
+    echo            '</div>';
+    echo            '<input type="hidden" class="list_sn" value="' . $item['list_sn'] .'"/>';
+    echo        '</div>';
+    echo '</div>';
+}

+ 59 - 0
mapi/control/room.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/12/14
+ * Time: 上午11:36
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/room/factory_client.php');
+
+class roomControl extends mbMemberControl
+{
+    private $mRoomID;
+    private $mAddr;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->mRoomID = 1;
+
+        global $config;
+        $webaddr = $config['access_addr'];
+        $this->mAddr = $webaddr;
+    }
+
+    public function indexOp()
+    {
+        $user = session_helper::memberid();
+        $ret = room\factory_client::instance()->invite($this->mRoomID,$user);
+        if($ret != false) {
+            $ret['addr'] = $this->mAddr;
+            return self::outsuccess($ret,"room/invite",'wap');
+        } else {
+            return self::outerr(errcode::ErrRoom);
+        }
+    }
+
+    public function shake_bonusOp()
+    {
+        global $config;
+        $shake_room = $config['special_rooms']['shake_bonus'];
+
+        $user = session_helper::memberid();
+        $ret = room\factory_client::instance()->invite($shake_room,$user);
+        if($ret != false) {
+            $ret['addr'] = $this->mAddr;
+            return self::outsuccess($ret,"room/invite",'wap');
+        } else {
+            return self::outerr(errcode::ErrRoom);
+        }
+    }
+
+    public function create_bargainOp()
+    {
+        $result = room\room_client::instance()->create();
+    }
+}

+ 931 - 0
mapi/control/search.php

@@ -0,0 +1,931 @@
+<?php
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/category_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/brand_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/history_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/search/util.php');
+require_once(BASE_ROOT_PATH . '/helper/search_param.php');
+require_once(BASE_ROOT_PATH . '/mobile/control/special.php');
+require_once(BASE_ROOT_PATH . '/helper/ugc_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/text_filter.php');
+require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+
+
+define('MOBILE_SERVER',true);
+
+class searchControl extends mobileHomeControl
+{
+    const def_history_divider = '/mobile/defimg/history_divider.png';
+    const def_hot_divider     = '/mobile/defimg/hot_divider.png';
+    const def_guess_divider   = '/mobile/defimg/guess_like.png';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $param = new search_param($_GET);
+        $params = $param->format($this->page_no(),$this->page_size());
+
+        if($params == false) {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        } else {
+            $result = search\search_client::instance()->get_result($params);
+        }
+
+        if(empty($result))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        }
+
+        $cids = $result['cids'];
+        $model_goods = Model('goods');
+        $items = $model_goods->getGoodsListByColorDistinct(array('goods_commonid' => array('in',$cids)),goods_helper::fieldstr,'','');
+        $page_count = intval($result['page_count']);
+
+        if(empty($items))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_count)));
+        }
+        else
+        {
+            $tmp =[];
+            foreach ($items as $item) {
+                $commonid = intval($item['goods_commonid']);
+                $tmp[$commonid] = $item;
+            }
+
+            $goods_list = [];
+            foreach ($cids as $cid)
+            {
+                if(array_key_exists($cid,$tmp)) {
+                    $goods_list[] = $tmp[$cid];
+                }
+            }
+
+            $blocks = [];
+            if($this->page_no() == 1)
+            {
+                if($param->brand_id() != 0)
+                {
+                    $block = special_formater::format_brand_sale($param->brand_id(),false);
+                    if(!empty($block))
+                    {
+                        $blocks[] = $block;
+                        if($_SESSION['is_lasted']) {
+                            $blocks[] = special_formater::def_divider();
+                        }
+                    }
+                }
+                else
+                {
+                    $block = special_formater::format_brand($result['brands']);
+                    if(!empty($block))
+                    {
+                        $blocks[] = $block;
+                        if($_SESSION['is_lasted']) {
+                            $blocks[] = special_formater::def_divider();
+                        }
+                    }
+                }
+
+                $block = special_formater::format_category($result['hots']);
+                if(!empty($block))
+                {
+                    $blocks[] = $block;
+                    if($_SESSION['is_lasted']) {
+                        $blocks[] = special_formater::def_divider();
+                    }
+                }
+            }
+
+            foreach ($goods_list as $goods) {
+                $goods_id = intval($goods['goods_id']);
+                $goods_ids[] = $goods_id;
+            }
+
+            $helper = new goods_helper($this->price_calcer());
+            $ret = $helper->summary($goods_list,$related_goods);
+
+            $block = special_formater::format_goods($goods_ids,"",$ret['sort_summary']);
+            $blocks[] = $block;
+
+            $spids = $result['spids'];
+            $ugc_blocks = $this->format_special($spids,$ugcs);
+            if(!empty($ugc_blocks))
+            {
+                foreach ($ugc_blocks as $block) {
+                    $blocks[] = $block;
+                }
+            }
+
+            return self::outsuccess(array('special_list' => $blocks,
+                'ugcs' => $ugcs,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page($page_count)));
+        }
+    }
+
+    private function format_special($spids,&$ugcs)
+    {
+        $index = $this->page_no();
+        if(empty($spids) || $index > count($spids)) {
+            $ugcs = [];
+            return [];
+        }
+        else {
+            rsort($spids,SORT_NUMERIC);
+            $spid = $spids[$index - 1];
+            return $this->ugc_block($spid,$ugcs);
+        }
+    }
+
+    private function ugc_block($spid, &$ugcs)
+    {
+        try
+        {
+            $ugcs = [];
+            $mod_special = Model('mb_special');
+            $items = $mod_special->getMbSpecialList(['special_id' => $spid]);
+            if(empty($items)) return [];
+
+            $special = new ugc\special($items[0]);
+            $sender = $special->memberid();
+
+            $mod_member = Model('member');
+            $members = $mod_member->getMemberList(['member_id' => $sender]);
+            if(empty($members)) return [];
+
+            $minfo = new member_info($members[0]);
+
+            $divider = special_formater::def_divider();
+            $result[] = $divider;
+            $block = special_formater::format_ugc($special);
+            $result[] = $block;
+            $divider = special_formater::def_divider();
+            $result[] = $divider;
+
+            $ugc = $this->format_ugc($minfo,$special);
+            $ugcs[] = $ugc;
+
+            return $result;
+        }
+        catch (Exception $ex)
+        {
+            return [];
+        }
+    }
+
+    private function format_ugc(member_info $minfo, ugc\special $special)
+    {
+        $ret['special_id'] = $special->special_id();
+        $ret['member_avatar'] = $minfo->avatar();
+        $ret['member_nickname'] = $minfo->nickname();
+        $ret['has_vote'] = $special->has_vote();
+        $ret['appreciate_num'] = $special->appreciates();
+        $ret['comment_num'] = $special->comments();
+        $ret['clicks'] = $special->clicks();
+        $ret['pubtime'] = $special->editime();
+        $ret['desc'] = $special->description();
+        $supporter = new ugc\special_support($special->special_id(),0);
+        $ret['supported'] = $supporter->supported();
+        $ret['support_num'] = $special->likes();
+        $cid = $special->category_id();
+        $ret['category'] = ugc_helper::category_title($cid);
+
+        $ret['can_del'] = false;
+        if(session_helper::logined())
+        {
+            if($special->memberid() == $_SESSION['member_id']) {
+                $ret['can_del'] = true;
+            }
+        }
+
+        return $ret;
+    }
+
+    public function search_goodsOp()
+    {
+        $param = new search_param($_GET);
+        $params = $param->format($this->page_no(),$this->page_size());
+
+        if($params == false) {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        } else {
+            $result = search\search_client::instance()->get_result($params);
+        }
+
+        if(empty($result))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        }
+
+        $cids = $result['cids'];
+        $model_goods = Model('goods');
+        $items = $model_goods->getGoodsListByColorDistinct(array('goods_commonid' => array('in',$cids)),goods_helper::fieldstr,'','');
+        $page_count = intval($result['page_count']);
+
+        if(empty($items))
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page($page_count)));
+        }
+        else
+        {
+            $tmp =[];
+            foreach ($items as $item) {
+                $commonid = intval($item['goods_commonid']);
+                $tmp[$commonid] = $item;
+            }
+
+            $goods_list = [];
+            foreach ($cids as $cid)
+            {
+                if(array_key_exists($cid,$tmp)) {
+                    $goods_list[] = $tmp[$cid];
+                }
+            }
+
+            foreach ($goods_list as $goods) {
+                $goods_id = intval($goods['goods_id']);
+                $goods_ids[] = $goods_id;
+            }
+
+            $helper = new goods_helper($this->price_calcer());
+            $ret = $helper->summary($goods_list,$related_goods);
+
+            $blocks = special_formater::format_ugc_goods($goods_ids,"",$ret['sort_summary']);
+
+            return self::outsuccess(['special_list' => $blocks,
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling'],
+                'mobile_page' => mobile_page($page_count)]);
+        }
+    }
+
+    public function suggest_wordsOp()
+    {
+        $keyword = $_GET['keyword'];
+        if(empty($keyword)) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        else
+        {
+            $result = search\search_client::instance()->get_words($keyword);
+            if($result == false) {
+                $result = null;
+                $pages = 0;
+            } else {
+                $result = $this->separate_page($result,$pages);
+            }
+            return self::outsuccess(['words' => $result,'mobile_page' => mobile_page($pages)]);
+        }
+    }
+
+    public function historyOp()
+    {
+        $helper = new history_helper();
+        $history = $helper->histories();
+        $hot_search = @explode(',',C('hot_search'));
+
+        $blocks = [];
+        if(!empty($history))
+        {
+            if($_SESSION['is_lasted']) {
+                $blocks[] = self::history_divider();
+            }
+            $blocks[] = special_formater::format_keyword($history,'历史搜索');
+        }
+        if(!empty($hot_search))
+        {
+            if($_SESSION['is_lasted']) {
+                $blocks[] = self::hot_divider();
+            }
+            $blocks[] = special_formater::format_keyword($hot_search,'热门搜索');
+        }
+
+        $guslike = $this->guesslike();
+        if($guslike == false)
+        {
+            return self::outsuccess(['special_list' => $blocks,'mobile_page' => mobile_page(1)]);
+        }
+        else
+        {
+            $gus_blocks = $guslike['special_list'];
+            if(!empty($gus_blocks))
+            {
+                if($_SESSION['is_lasted']) {
+                    $blocks[] = self::guess_divider();
+                }
+                $blocks[] = $gus_blocks[0];
+            }
+
+            $guslike['special_list'] = $blocks;
+            $guslike['mobile_page'] = mobile_page(1);
+
+            return self::outsuccess($guslike);
+        }
+    }
+
+    private static function history_divider()
+    {
+        static $block = [];
+        if(empty($block))
+        {
+            $block['item_type'] = 'divider';
+            $block['item_title'] = '';
+            $block['bg_type'] = 'image';
+            $image = RESOURCE_SITE_URL . self::def_history_divider;
+            $block['bg_data'] = $image;
+            $block['has_margin'] = false;
+            $block['scale'] = special_formater::scale($image);
+        }
+        return $block;
+    }
+    private static function hot_divider()
+    {
+        static $block = [];
+        if(empty($block))
+        {
+            $block['item_type'] = 'divider';
+            $block['item_title'] = '';
+            $block['bg_type'] = 'image';
+            $image = RESOURCE_SITE_URL . self::def_hot_divider;
+            $block['bg_data'] = $image;
+            $block['has_margin'] = false;
+            $block['scale'] = special_formater::scale($image);
+        }
+        return $block;
+    }
+    private static function guess_divider()
+    {
+        static $block = [];
+        if(empty($block))
+        {
+            $block['item_type'] = 'divider';
+            $block['item_title'] = '';
+            $block['bg_type'] = 'image';
+            $image = RESOURCE_SITE_URL . self::def_guess_divider;
+            $block['bg_data'] = $image;
+            $block['has_margin'] = false;
+            $block['scale'] = special_formater::scale($image);
+        }
+        return $block;
+    }
+
+    public function guesslike()
+    {
+        $goods_list = activity_helper::recomoned_goodsids();
+
+        if(empty($goods_list)) {
+            return false;
+        }
+        else
+        {
+            $gids = [];
+            $count = count($goods_list);
+            $len = mt_rand(1,$count);
+
+            for ($i = 0; $i < $len;)
+            {
+                $pos = intval(mt_rand(0,$count - 1));
+                $gid = $goods_list[$pos];
+                if(in_array($gid,$gids)) {
+                    continue;
+                } else {
+                    $gids[] = $gid;
+                }
+                if($len == count($gids)) {
+                    break;
+                }
+            }
+
+            $helper = new goods_helper($this->price_calcer());
+            $ret = $helper->online_summary($gids,$related_goods);
+            $block = special_formater::format_goods($gids,"猜你喜欢",$ret['sort_summary']);
+
+            return array('special_list' => array($block),
+                'summary'  => $ret['summary'],
+                'groupbuy' => $ret['groupbuy'],
+                'limitime' => $ret['limitime'],
+                'bundling' => $ret['bundling']);
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * @return array
+     */
+    private function condition()
+    {
+        $condition = array();
+        //分类查询
+        if (!empty(trim($_GET['gc_id']))) {
+            $condition['gc_id'] = intval($_GET['gc_id']);
+        }
+        // 关键字
+        if (!empty(trim($_GET['keyword']))) {
+            $word = trim(urldecode($_GET['keyword']));
+            $helper = new history_helper();
+            $helper->add_word($word);
+            $condition['goods_name|goods_jingle'] = array('like', '%' . urldecode($_GET['keyword']) . '%');
+        }
+        // 品牌查询
+        if (!empty(trim($_GET['brand_id']))) {
+            $condition['brand_id'] = intval($_GET['brand_id']);
+        }
+        // 功效查询
+        if (!empty(trim($_GET['efficacy_id']))) {
+            $condition['efficacy_id'] = intval($_GET['efficacy_id']);
+        }
+        //重新组合后的分类查询
+        if (!empty(trim($_GET['hot_id']))) {
+            $id = intval($_GET['hot_id']);
+            $cids = category_helper::instance()->cids($id);
+            $condition['gc_id'] = array('in', $cids);
+        }
+        return $condition;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public function goods_listOp()
+    {
+        $model_goods = Model('goods');
+        $condition = $this->condition();
+
+        //排序方式
+        $order = $this->get_order($_GET['key'], $_GET['order']);
+
+        $goods_list = $model_goods->getGoodsListByColorDistinct($condition, goods_helper::fieldstr, $order, $this->page_size());
+        $page_count = $model_goods->gettotalpage();
+        $model_goods->cls();
+
+        $goods_ids = array();
+        foreach($goods_list as $val) {
+            array_push($goods_ids,$val['goods_id']);
+        }
+
+        $helper = new goods_helper($this->price_calcer());
+        $goods_list = $helper->get_infos($goods_ids);
+
+        self::outsuccess(array('goods_list' => $goods_list, 'mobile_page' => mobile_page($page_count)));
+    }
+
+    /**
+     * 商品列表排序方式
+     */
+    private function get_order($key, $order)
+    {
+        $result = 'is_own_shop desc,goods_commonid desc';
+        if (!empty($key))
+        {
+            $sequence = 'desc';
+            if ($order == 1) {
+                $sequence = 'asc';
+            }
+            switch ($key)
+            {
+                case '1' : //销量
+                $result = 'goods_salenum' . ' ' . $sequence;
+                    break;
+                case '2' : //浏览量
+                    $result = 'goods_click' . ' ' . $sequence;
+                    break;
+                case '3' : //价格
+                    $result = 'goods_price' . ' ' . $sequence;
+                    break;
+            }
+        }
+        return $result;
+    }
+
+
+    /**
+     * 商品详细页扩展
+     *
+     * 输入参数:
+     * goods_id:商品id
+     *
+     */
+    public function goods_commonOp()
+    {
+        $goods_id = intval($_GET ['goods_id']);
+        if (empty($_GET ['goods_id']) || $goods_id < 0) {
+            return joutput_error(errcode::ErrParamter, "goods_id = {$goods_id} must be > 0.");
+        }
+        // 商品详细信息
+        $model_goods = Model('goods')->cls();
+        $goods_detail = $model_goods->getGoodsSku($goods_id);
+        if (empty($goods_detail)) {
+            return joutput_error(errcode::ErrGoodsNotExist);
+        }
+        //推荐商品
+        $model_store = Model('store')->cls();
+        $store_info = $model_store->getStoreInfoByID($goods_detail['goods_info']['store_id']);
+        $goods_detail['store_info']['store_id'] = $store_info['store_id'];
+        $goods_detail['store_info']['store_name'] = $store_info['store_name'];
+        $goods_detail['store_info']['member_id'] = $store_info['member_id'];
+        //显示QQ及旺旺 好商城V3
+        $goods_detail['store_info']['store_qq'] = $store_info['store_qq'];
+        $goods_detail['store_info']['store_ww'] = $store_info['store_ww'];
+        $goods_detail['store_info']['store_phone'] = $store_info['store_phone'];
+        $goods_detail['store_info']['member_name'] = $store_info['member_name'];
+        $goods_detail['store_info']['avatar'] = getMemberAvatarForID($store_info['member_id']);
+
+        //商品详细信息处理
+        $goods_detail = $this->_goods_common_extend($goods_detail);
+
+        joutput_data($goods_detail);
+    }
+
+    /**
+     * 商品详细信息处理
+     */
+    private function _goods_common_extend($goods_detail)
+    {
+        //商品链接
+        $goods_detail['goods_info']['goods_url'] = urlShop('goods', 'index', array('goods_id' => $goods_detail['request_goods_id']));
+
+        //整理数据
+        unset($goods_detail['goods_info']['goods_commonid']);
+        unset($goods_detail['goods_info']['gc_id']);
+        unset($goods_detail['goods_info']['gc_name']);
+        unset($goods_detail['goods_info']['store_name']);
+        unset($goods_detail['goods_info']['brand_id']);
+        unset($goods_detail['goods_info']['brand_name']);
+        unset($goods_detail['goods_info']['type_id']);
+        unset($goods_detail['goods_info']['goods_image']);
+        //unset($goods_detail['goods_info']['goods_body']);
+        unset($goods_detail['goods_info']['mobile_body']);
+        unset($goods_detail['goods_info']['goods_state']);
+        unset($goods_detail['goods_info']['goods_stateremark']);
+        unset($goods_detail['goods_info']['goods_verify']);
+        unset($goods_detail['goods_info']['goods_verifyremark']);
+        unset($goods_detail['goods_info']['goods_lock']);
+        unset($goods_detail['goods_info']['goods_addtime']);
+        unset($goods_detail['goods_info']['goods_edittime']);
+        unset($goods_detail['goods_info']['goods_selltime']);
+        unset($goods_detail['goods_info']['goods_show']);
+        unset($goods_detail['goods_info']['goods_commend']);
+        unset($goods_detail['goods_info']['explain']);
+        unset($goods_detail['goods_info']['cart']);
+        unset($goods_detail['goods_info']['buynow_text']);
+        unset($goods_detail['goods_info']['spec_value']);
+        unset($goods_detail['goods_info']['spec_name']);
+        unset($goods_detail['goods_info']['goods_spec']);
+        //unset($goods_detail['goods_info']['goods_attr']);
+
+        unset($goods_detail['groupbuy_info']);
+        unset($goods_detail['xianshi_info']);
+
+        return $goods_detail;
+    }
+
+    /**
+     * 商品详细页
+     *
+     * 输入参数:
+     * goods_id: 商品id
+     * from:目前说明是来自app还是h5
+     */
+    public function goods_detailOp()
+    {
+        $goods_id = intval($_GET ['goods_id']);
+        $from = $_GET['from'];
+
+        // 商品详细信息
+        $model_goods = Model('goods');
+        $goods_detail = $model_goods->getGoodsDetail($goods_id);
+        if (empty($goods_detail)) {
+            return joutput_error(errcode::ErrGoodsNotExist);
+        }
+
+        // 推荐商品
+        $model_store = Model('store');
+        $hot_sales = $model_store->getHotSalesList($goods_detail['goods_info']['store_id'], 6);
+        $goods_commend_list = array();
+        foreach ($hot_sales as $value) {
+            $goods_commend = array();
+            $goods_commend['goods_id'] = $value['goods_id'];
+            $goods_commend['goods_name'] = $value['goods_name'];
+            $goods_commend['goods_price'] = $value['goods_price'];
+            $goods_commend['goods_image_url'] = cthumb($value['goods_image'], 240);
+            $goods_commend_list[] = $goods_commend;
+        }
+        $goods_detail['goods_commend_list'] = $goods_commend_list;
+        $store_info = $model_store->getStoreInfoByID($goods_detail['goods_info']['store_id']);
+        $goods_detail['store_info']['store_id'] = $store_info['store_id'];
+        $goods_detail['store_info']['store_name'] = $store_info['store_name'];
+        $goods_detail['store_info']['member_id'] = $store_info['member_id'];
+        //显示QQ及旺旺 好商城V3
+        $goods_detail['store_info']['store_qq'] = $store_info['store_qq'];
+        $goods_detail['store_info']['store_ww'] = $store_info['store_ww'];
+        $goods_detail['store_info']['store_phone'] = $store_info['store_phone'];
+        $goods_detail['store_info']['member_name'] = $store_info['member_name'];
+        $goods_detail['store_info']['avatar'] = getMemberAvatarForID($store_info['member_id']);
+
+        //商品详细信息处理
+        $goods_detail = $this->_goods_detail_extend($goods_detail);
+
+        if ($from === 'app') {
+            $goods_detail['goods_info']['spec'] = $this->_parse_spec($goods_detail['goods_info']['spec_name'], $goods_detail['goods_info']['spec_value'], $goods_detail['spec_image'], $goods_detail['spec_list']);
+            $goods_detail['goods_info']['attributes'] = $this->_parse_attributes($goods_detail['goods_info']['goods_attr']);
+            $goods_detail['goods_info']['goods_spec_obj'] = $this->_parse_goods_spec($goods_detail['goods_info']['goods_spec']);
+            $goods_detail['UPLOAD_SITE_URL'] = $GLOBALS['setting_config']['upload_site_url'];
+        }
+        //v3-b11 抢购商品是否开始
+        $goods_info = $goods_detail['goods_info'];
+        //print_r($goods_info);
+        $IsHaveBuy = 0;
+        if (!empty($_COOKIE['username'])) {
+            $model_member = Model('member');
+            $member_info = $model_member->getMemberInfo(array('member_name' => $_COOKIE['username']));
+            $buyer_id = $member_info['member_id'];
+
+            $promotion_type = $goods_info["promotion_type"];
+
+            if ($promotion_type == 'groupbuy') {
+                //检测是否限购数量
+                $upper_limit = $goods_info["upper_limit"];
+                if ($upper_limit > 0) {
+                    //查询些会员的订单中,是否已买过了
+                    $model_order = Model('order');
+                    //取商品列表
+                    $order_goods_list = $model_order->getOrderGoodsList(array('goods_id' => $goods_id, 'buyer_id' => $buyer_id, 'goods_type' => 2));
+                    if ($order_goods_list) {
+                        //取得上次购买的活动编号(防一个商品参加多次团购活动的问题)
+                        $promotions_id = $order_goods_list[0]["promotions_id"];
+                        //用此编号取数据,检测是否这次活动的订单商品。
+                        $model_groupbuy = Model('groupbuy');
+                        $groupbuy_info = $model_groupbuy->getGroupbuyInfo(array('groupbuy_id' => $promotions_id));
+                        if ($groupbuy_info) {
+                            $IsHaveBuy = 1;
+                        } else {
+                            $IsHaveBuy = 0;
+                        }
+                    }
+                }
+            }
+        }
+        $goods_detail['IsHaveBuy'] = $IsHaveBuy;
+        //v3-b11 end
+        joutput_data($goods_detail);
+    }
+
+    /**
+     * 商品详细信息处理
+     */
+    private function _goods_detail_extend($goods_detail)
+    {
+        //整理商品规格
+        unset($goods_detail['spec_list']);
+        $goods_detail['spec_list'] = $goods_detail['spec_list_mobile'];
+        unset($goods_detail['spec_list_mobile']);
+
+        //整理商品图片
+        unset($goods_detail['goods_image']);
+        $goods_detail['goods_image'] = implode(',', $goods_detail['goods_image_mobile']);
+        unset($goods_detail['goods_image_mobile']);
+
+        //商品链接
+        $goods_detail['goods_info']['goods_url'] = urlShop('goods', 'index', array('goods_id' => $goods_detail['goods_info']['goods_id']));
+
+        //整理数据
+        unset($goods_detail['goods_info']['goods_commonid']);
+        unset($goods_detail['goods_info']['gc_id']);
+        unset($goods_detail['goods_info']['gc_name']);
+        unset($goods_detail['goods_info']['store_name']);
+        unset($goods_detail['goods_info']['brand_id']);
+        unset($goods_detail['goods_info']['brand_name']);
+        unset($goods_detail['goods_info']['type_id']);
+        unset($goods_detail['goods_info']['goods_image']);
+        unset($goods_detail['goods_info']['goods_body']);
+        unset($goods_detail['goods_info']['mobile_body']);
+        unset($goods_detail['goods_info']['goods_state']);
+        unset($goods_detail['goods_info']['goods_stateremark']);
+        unset($goods_detail['goods_info']['goods_verify']);
+        unset($goods_detail['goods_info']['goods_verifyremark']);
+        unset($goods_detail['goods_info']['goods_lock']);
+        unset($goods_detail['goods_info']['goods_addtime']);
+        unset($goods_detail['goods_info']['goods_edittime']);
+        unset($goods_detail['goods_info']['goods_selltime']);
+        unset($goods_detail['goods_info']['goods_show']);
+        unset($goods_detail['goods_info']['goods_commend']);
+        unset($goods_detail['goods_info']['explain']);
+        unset($goods_detail['goods_info']['cart']);
+        unset($goods_detail['goods_info']['buynow_text']);
+        unset($goods_detail['groupbuy_info']);
+        //unset($goods_detail['xianshi_info']);
+
+        return $goods_detail;
+    }
+
+    /**
+     * 解析spec字段
+     *
+     * @param $spec_name
+     * @param $spec_value
+     * @param array $spec_image
+     * @param array $spec_list
+     * @return array
+     */
+    private function _parse_spec($spec_name, $spec_value, $spec_image = [], $spec_list = [])
+    {
+        $spec = [];
+        foreach ($spec_name as $key => $value) {
+            $spec_item = [];
+            $spec_item['spec_id'] = $key;
+            $spec_item['spec_name'] = $value;
+            if (!empty($spec_value[$key])) {
+                $spec_item['value_list'] = [];
+                foreach ($spec_value[$key] as $v_key => $v) {
+                    $value_item = [];
+                    $value_item['value_id'] = $v_key;
+                    $value_item['value_name'] = $v;
+                    $value_item['value_image'] = empty($spec_image[$v_key]) ? '' : $spec_image[$v_key];
+                    $value_item['value'] = empty($spec_list[$v_key]) ? '' : $spec_list[$v_key];
+                    array_push($spec_item['value_list'], $value_item);
+                }
+            }
+            array_push($spec, $spec_item);
+        }
+        return $spec;
+    }
+
+    /**
+     * 解析商品属性字段
+     *
+     * @param $goods_attr
+     * @return array
+     */
+    private function _parse_attributes($goods_attr)
+    {
+        $attributes = [];
+        foreach ($goods_attr as $key => $value) {
+            $attribute_item = [];
+            $attribute_item['goods_attr_id'] = $key;
+            $attribute_item['goods_attr_value'] = [];
+            if (!empty($value)) {
+                foreach ($value as $v_key => $v) {
+                    $attribute_attr = [];
+                    if ($v_key === 'name') {
+                        $attribute_item['goods_attr_name'] = $v;
+                    } else {
+                        $attribute_attr['value_id'] = $v_key;
+                        $attribute_attr['value_name'] = $v;
+                        array_push($attribute_item['goods_attr_value'], $attribute_attr);
+                    }
+                }
+            }
+            array_push($attributes, $attribute_item);
+        }
+        return $attributes;
+    }
+
+    /**
+     * 解析功效
+     *
+     * @param $goods_attr
+     * @return mixed
+     */
+    private function _parse_for_efficacy($goods_attr)
+    {
+        foreach ($goods_attr as $key => $val) {
+            $attr_item['goods_attr_id'] = intval($key);
+            $attr_item['goods_attr_name'] = $val['name'];
+            if ($attr_item['goods_attr_name'] === '功效') {
+                $goods_attr_value = array();
+                foreach ($val as $id => $name) {
+                    if ($id !== 'name') {
+                        $val_item['value_id'] = intval($id);
+                        $val_item['value_name'] = $name;
+                        array_push($goods_attr_value, $val_item);
+                    }
+                }
+                $attr_item['goods_attr_value'] = $goods_attr_value;
+                break;
+            }
+        }
+        return $attr_item;
+    }
+
+    /**
+     * 商品规格序列化解析
+     *
+     * @param $goods_spec
+     * @return array
+     */
+    private function _parse_goods_spec($goods_spec)
+    {
+        $goods_spec_obj = [];
+        foreach ($goods_spec as $key => $value) {
+            $spec_item = [];
+            $spec_item['spec_value'] = $key;
+            $spec_item['spec_name'] = $value;
+            array_push($goods_spec_obj, $spec_item);
+        }
+        return $goods_spec_obj;
+    }
+
+    /**
+     * 商品详细页(未启用)
+     */
+    public function goods_bodyOp()
+    {
+        return joutput_error(errcode::ErrProtocolDisabled);
+
+        $goods_id = intval($_GET ['goods_id']);
+        $out_type = $_GET ['type'];
+        $model_goods = Model('goods');
+
+        if (empty($_GET ['goods_commonid'])) {
+            $goods_info = $model_goods->getGoodsInfoByID($goods_id, 'goods_commonid');
+        } else {
+            $goods_info['goods_commonid'] = intval($_GET ['goods_commonid']);
+        }
+        $goods_common_info = $model_goods->getGoodeCommonInfoByID($goods_info['goods_commonid']);
+
+        if ($out_type === 'json') {
+            $goods_common_info['goods_attr'] = $this->_parse_attributes(unserialize($goods_common_info['goods_attr']));
+            $goods_common_info['spec_name'] = unserialize($goods_common_info['spec_name']);
+            $goods_common_info['spec_value'] = unserialize($goods_common_info['spec_value']);
+            $goods_common_info['spec'] = $this->_parse_spec($goods_common_info['spec_name'], $goods_common_info['spec_value']);
+            $goods_common_info['goods_body'] = ''; //base64_encode($goods_common_info['goods_body']);
+            $goods_common_info['mobile_body'] = '';//base64_encode($goods_common_info['mobile_body']);
+            joutput_data($goods_common_info);
+        } else {
+            Tpl::output('goods_common_info', $goods_common_info);
+            Tpl::showpage('goods_body');
+        }
+    }
+
+    /**
+     * 获取detail(未启用)
+     */
+    public function detailOp()
+    {
+        $goods_id = intval($_GET['goods_id']);
+        if (empty($_GET['goods_id']) || $goods_id <= 0) {
+            if (!empty($_GET['goods_commonid'])) {
+                $commonid = intval($_GET['goods_commonid']);
+            }
+        } else {
+            $items = Model()->table('goods')->field('goods_commonid')->where(array('goods_id' => $goods_id))->limit(1)->select();
+            if (!empty($items) && count($items) > 0) {
+                $commonid = intval($items[0]['goods_commonid']);
+            }
+        }
+
+        if (isset($commonid) && $commonid > 0) {
+            $items = Model()->table('goods_common')->field('goods_body')->where(array('goods_commonid' => $commonid))->select();
+            if (!empty($items) && count($items) > 0) {
+                Tpl::output('goods_body', $items[0]['goods_body']);
+            }
+        }
+        Tpl::showpage('goods_detail');
+    }
+}

+ 908 - 0
mapi/control/special.php

@@ -0,0 +1,908 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/9/7
+ * Time: 下午3:52
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/activity_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/model_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/user_session/storage.php');
+require_once(BASE_ROOT_PATH . '/helper/ugc_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+
+class specialControl extends mobileHomeControl
+{
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        if($special_id < 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $spitem = spid_helper::instance()->special($special_id);
+        if($spitem == false) {
+            return self::outerr(errcode::ErrParamter,"该专题不存在");
+        }
+
+        QueueClient::push('onClickSpecial',['special_id' => $special_id]);
+        if($spitem->from_user())
+        {
+            if(session_helper::need_wechat_author()) {
+                $author = new thrid_author\wxauthor();
+                $url = author_url::ugc_url($special_id);
+                $url = $author->enter($url);
+                return self::outsuccess(['direct_uri' => $url],"redirect");
+            }
+
+            $ret = $this->pri_special($special_id);
+            $ret['spitem'] = $spitem;
+            $tpl_obj = new tpl_ugc($ret);
+            self::outsuccess(['tpl_obj' => $tpl_obj],'ugc/content');
+        } else {
+            $ret = $this->pub_special($special_id);
+            self::outsuccess($ret);
+        }
+    }
+
+    public function submitOp()
+    {
+        $special_id = intval($_GET['special_id']);
+        $spitem = spid_helper::instance()->special($special_id);
+
+        if($special_id < 0 || $spitem == false) {
+            return self::outerr(errcode::ErrParamter,"该文章不存在");
+        }
+        $content = urldecode($_GET['content']);
+        if(empty($content)) {
+            $options = false;
+        }
+        else {
+            $options = json_decode($content,true);
+            if($options == null) $options = false;
+        }
+
+        $result = ugc_helper::submit($special_id,$options,$err);
+        if($result == false) {
+            return self::outerr($err['code'],$err['msg']);
+        }
+        else
+        {
+            $vote_result = $result['vote_result'];
+            $type_sn = $result['type_sn'];
+            if(!empty($type_sn)) {
+                $url = BASE_SITE_URL . "/mobile/index.php?act=bonusex&op=open&type_sn={$type_sn}";
+                $type = bonus\type::create_by_sn($type_sn);
+                $sender_id = $type->sender_id();
+                $minfo = new member_info($sender_id);
+                $avatar = $minfo->avatar();
+            } else {
+                $url = "";
+                $avatar = '';
+            }
+            $answer_diff = $result['answer_diff'];
+
+            return self::outsuccess(['special_id' => $special_id,
+                'vote_result' => $vote_result,
+                'answer_diff' => $answer_diff,
+                'bonus_url' => $url,
+                'num' => $result['num'],
+                'amount' => $result['amount'],
+                'bonus_type' => $result['bonus_type'],
+                'sender_avatar' => $avatar]);
+        }
+    }
+
+    protected function pub_special($special_id)
+    {
+        $specials = special_manager::instance()->special($special_id,$goods_ids,true);
+        if (!empty($goods_ids))
+        {
+            $helper = new goods_helper($this->price_calcer());
+            $goodsex = $helper->online_summary($goods_ids, $related_goods);
+
+            return array('special_list' => $specials,
+                'tabs' => special_manager::instance()->tabs($special_id),
+                'summary'  => $goodsex['summary'],
+                'groupbuy' => $goodsex['groupbuy'],
+                'limitime' => $goodsex['limitime'],
+                'bundling' => $goodsex['bundling'],
+                'bargain_create' => $goodsex['bargain_create'],
+                'mobile_page' => mobile_page(1));
+        }
+        else
+        {
+            return array('special_list' => $specials,
+                'summary'  => array(),
+                'groupbuy' => array(),
+                'limitime' => array(),
+                'bundling' => array(),
+                'mobile_page' => mobile_page(1));
+        }
+    }
+
+    protected function pri_special($special_id)
+    {
+        $result = special_manager::instance()->special($special_id,$goods_ids,false);
+        if (!empty($goods_ids))
+        {
+            $helper = new goods_helper($this->price_calcer());
+            $goodsex = $helper->online_summary($goods_ids, $related_goods);
+
+            return array('special_list' => $result['specials'],
+                'sender_info' => $result['sender_info'],
+                'special_info' => $result['special_info'],
+                'summary'  => $goodsex['summary'],
+                'groupbuy' => $goodsex['groupbuy'],
+                'limitime' => $goodsex['limitime'],
+                'bundling' => $goodsex['bundling'],
+                'mobile_page' => mobile_page(1));
+        }
+        else
+        {
+            return array('special_list' => $result['specials'],
+                'sender_info' => $result['sender_info'],
+                'special_info' => $result['special_info'],
+                'summary'  => array(),
+                'groupbuy' => array(),
+                'limitime' => array(),
+                'bundling' => array(),
+                'mobile_page' => mobile_page(1));
+        }
+    }
+}
+
+class tpl_ugc
+{
+    private $spitem;
+    private $special_list;
+    private $summary;
+    private $mem_info;
+    private $special;
+    private $mQuestionIndex;
+    private $mVoteIndex;
+    private $mAuthorRelation;
+
+    public function __construct($output)
+    {
+        $this->mQuestionIndex = 0;
+        $this->mVoteIndex = 0;
+        $this->spitem = $output['spitem'];
+        $this->special_list = $output['special_list'];
+        $this->summary = $output['summary'];
+        if(!empty($output['sender_info'])) {
+            $this->mem_info = new member_info($output['sender_info']);
+        } else {
+            $this->mem_info = null;
+        }
+
+        $special_id = $output['special_info']['special_id'];
+        $mod_special = Model('mb_special');
+        $special_info = $mod_special->getMbSpecialByID($special_id,'*',true);
+        if(!empty($special_info)) {
+            $this->special = new ugc\special($special_info);
+        } else {
+            $this->special = null;
+        }
+
+        if(session_helper::logined())
+        {
+            $memberid = session_helper::memberid();
+            if($this->special->memberid() == $memberid) {
+                $this->mAuthorRelation = 2;
+            }
+            else
+            {
+                $ret = relation_helper::subscribed($memberid,$this->special->memberid());
+                $this->mAuthorRelation = $ret == true ? 1 : 0;
+            }
+
+        } else {
+            $this->mAuthorRelation = false;
+        }
+    }
+
+    public function preview()
+    {
+        return $this->special->preview();
+    }
+    public function special_id()
+    {
+        return $this->special->special_id();
+    }
+    public function browse_title()
+    {
+        if(session_helper::isapp()) {
+            return "文章内容";
+        } else {
+            $title = $this->special->share_title();
+            return $title;
+        }
+    }
+
+    public function title() {
+        $title =  $this->special->share_title();
+        $title = str_replace( array( "\n", "\r" ), array( " ", " " ), $title );
+        return $title;
+    }
+
+    public function image() {
+        return $this->special->share_img();
+    }
+    public function url() {
+        $special_id = $this->special_id();
+        return url_helper::ugc_url($special_id);
+    }
+
+    public function sub_title()
+    {
+        $desc = $this->special->description();
+        $desc = str_replace( array( "\n", "\r" ), array( " ", " " ), $desc);
+
+        if(empty($desc)) return "";
+        else
+            return $desc;
+    }
+
+    public function last_title()
+    {
+        $submit_rule = $this->special->submit_rule();
+        if(!empty($submit_rule)) {
+            $submit_rule->avaliable();
+            $desc = "点击领取红包";
+        } else {
+            $desc = "熊猫美妆";
+        }
+        return $desc;
+    }
+    public function show_title()
+    {
+        $title = $this->spitem->share_title();
+        if(!empty($title))
+        {
+            $str = "<div class=\"title\">
+                        <h3>{$title}</h3>
+                    </div>";
+            echo $str;
+        }
+    }
+
+    private function format_time($tm)
+    {
+        $cur_tm = time();
+        $delta = $cur_tm - $tm;
+        if($delta < 600) {
+            return "刚刚";
+        }
+        elseif ($delta < 3600) {
+            $delta = intval($delta / 60);
+            return "{$delta}分钟前";
+        }
+        elseif($delta < 3600 * 24) {
+            $delta = intval($delta / 3600);
+            return "{$delta}小时前";
+        }
+        else {
+            return strftime("%m-%d",$tm);
+        }
+    }
+
+    public function show_sender()
+    {
+        if($this->mem_info != null)
+        {
+            $nick_name = $this->mem_info->nickname();
+            $avatar = $this->mem_info->avatar();
+            $pubtime = $this->special->pubtime();
+            $pubtime = $this->format_time($pubtime);
+
+            $av_str = "<img src=\"{$avatar}\" alt=\"熊猫美妆\">";//
+            $name_str = "<div class=\"author_pro\">
+                            <span>文/{$nick_name}</span >
+                            <span class=\"release_date\">{$pubtime}</span>
+                         </div>";
+            $str = $av_str . $name_str;
+        } else {
+            $str = '';
+        }
+        echo $str;
+    }
+
+    public function show_blocks()
+    {
+        $this->mQuestionIndex = 0;
+        foreach ($this->special_list as $block)
+        {
+            $item_type = $block['item_type'];
+            $items = $block['items'];
+            if($item_type == 'home_ugc' && !empty($items)) {
+                $this->show_items($items);
+            }
+        }
+
+        $this->show_submit();
+        $this->show_answer_page();
+        $this->show_appreciate();
+        $this->show_comment_header();
+    }
+    private function show_submit()
+    {
+        $vote_single = $this->special->vote_single();
+        $submitor = new ugc\special_submitor($this->special_id(),$vote_single);
+        $special = $this->special;
+
+        if(!$submitor->submited())
+        {
+            $rule = $special->submit_rule();
+            if($rule != false) {
+                $avaliable = $rule->avaliable();
+            } else {
+                $avaliable = false;
+            }
+
+            if($special->has_vote() || $special->has_question())
+            {
+                if($special->has_vote() && $special->has_question()) {
+                    $content = "提交";
+                }
+                elseif($special->has_vote()) {
+                    $content = "投票";
+                }
+                else{
+                    $content = "提交";
+                }
+
+                if($rule != false && $avaliable == true)
+                {
+                    $content .= " (领红包)";
+                }
+
+                if($special->has_over()) {
+                    $str = "<button class=\"button_vote button_null\" id=\"submit_btn\" disabled>{$content} 已过期</button>";
+                } else {
+                    $str = "<button class=\"button_vote\" id=\"submit_btn\">{$content}</button>";
+                }
+            }
+            else
+            {
+                if($rule == false) {
+                    return;
+                }
+                else
+                {
+                    if($avaliable)
+                    {
+                        $content = "领红包";
+                        if($special->has_over()) {
+                            $str = "<button class=\"button_vote button_null\" id=\"submit_btn\" disabled>{$content} 已过期</button>";
+                        } else {
+                            $str = "<button class=\"button_vote\" id=\"submit_btn\">{$content}</button>";
+                        }
+                    }
+                }
+            }
+        }
+        else  {
+            $str = "<button class=\"button_vote button_null\" disabled>您已经提交过</button>";
+        }
+        echo $str;
+    }
+
+    private function show_comment_header()
+    {
+        $report_url = BASE_SITE_URL . "/mobile/index.php?act=member_ugc&op=report_page&special_id={$this->special_id()}";
+        $str = '';
+        $clicks = $this->special->clicks();
+        if(!$this->preview())
+        {
+            $str .= "<div class=\"comment\">
+                        <div class=\"pro\">
+                            <div class=\"pro_title\">评论</div>
+                            <div class=\"reading\">浏览数 {$clicks}</div>
+                            <div class=\"complaint\">
+                                <a href=\"{$report_url}\">投诉</a>
+                            </div>
+                        </div>
+                        <div class=\"comment_list\"></div>
+                      </div>";
+        }
+
+        echo $str;
+    }
+
+    private function show_items($items)
+    {
+        foreach ($items as $item)
+        {
+            $show_type = $item['show_type'];
+            if($show_type == 'image') {
+                $this->show_image($item);
+            }
+            elseif($show_type == 'text') {
+                $this->show_text($item);
+            }
+            elseif($show_type == 'vote')
+            {
+                $vote_single = $this->special->vote_single();
+
+                $submitor = new ugc\special_submitor($this->special_id(),$vote_single);
+                if($submitor->submited()) {
+                    $this->show_vote_result($item);
+                } else {
+                    $this->show_vote($item);
+                }
+                $this->mVoteIndex++;
+            }
+            elseif($show_type == 'question') {
+                $this->show_question($item);
+                $this->mQuestionIndex++;
+            }
+            elseif($show_type == 'goods') {
+                $this->show_goods($item);
+            }
+            else {
+
+            }
+        }
+    }
+
+    private function goods_summary($goods_id)
+    {
+        foreach ($this->summary as $summary)
+        {
+            if($summary['goods_id'] == $goods_id) {
+                return $summary;
+            }
+        }
+        return false;
+    }
+
+    private function show_goods($item)
+    {
+        $goods_id = intval($item['data']);
+        $summary = $this->goods_summary($goods_id);
+        if($summary == false) return;
+        $recoment = $item['reserved'];
+
+        if(session_helper::isapp()) {
+            $url = "xmmz://p.lrlz.com/goods/goods?goodsId={$goods_id}";
+        } else {
+            $url = BASE_SITE_URL . "/mshop/goods_detail?goods_id={$goods_id}";
+        }
+
+        if($summary['goods_storage'] <= 0) {
+            $state = '<span class="badge_null">已经售罄</span>';
+        }
+        elseif($summary['act_id'] > 0) {
+            $state = '<span class="badge_limit">限时特价</span>';
+        }
+        elseif($summary['is_new']) {
+            $state = '<span class="badge_new">熊猫新品</span>';
+        }
+        else {
+            $state = '';
+        }
+
+        $goods_price = $summary['goods_price'];
+        $bonus_price = $summary['bonus_price'];
+        $discount = $goods_price - $bonus_price;
+
+        $str = "<div class=\"recommend_goods\">
+                    <div class=\"goods_item\">
+                        <a href=\"{$url}\">
+                            {$state}
+                            <div class=\"goods\">
+                                <div class=\"goods_img\"><img src=\"{$summary['goods_image_url']}\" alt=\"熊猫美妆\"></div>
+                                <div class=\"goods_desc\">
+                                    <p class=\"goods_title\">{$summary['goods_mobile_name']}</p>
+                                    <p class=\"goods_pro\">{$summary['goods_jingle']}</p>
+                                    <p class=\"goods_price\">
+                                        ¥{$bonus_price}
+                                        <span class=\"shoppe\">天猫价 {$goods_price} / 红包抵<span class=\"bonus_price\">{$discount}</span>元</span>
+                                    </p>
+                                </div>
+                            </div>";
+        if(!empty($recoment))
+        {
+            $str        .= "<div class=\"recommend\">
+                                <span class=\"label\">推荐理由:</span><span>{$recoment}</span>
+                            </div>";
+        }
+        $str .=         "</a>
+                    </div>
+                </div>";
+        echo $str;
+    }
+    private function show_question($item)
+    {
+        if(empty($item['data'])) return false;
+        $options = json_decode($item['data'],true);
+
+        $title = $item['title'];
+        $qindex = $this->mQuestionIndex;
+        $i = $qindex + 1;
+        $show_title = "第{$i}题、{$title}";
+
+        $reserved = $item['reserved'];
+        $kv = preg_split('/=/',$reserved);
+        if(!empty($kv))
+        {
+            $k = trim($kv[0]);
+            $v = trim($kv[1]);
+            if(!empty($k) && $k == 'answer_type') {
+                $answer_type = $v;
+            }
+        }
+        $answer_type = intval($answer_type);
+        if($answer_type == 0) {
+            $sanswer_type = '单选';
+            $box = "radio";
+        }
+        else {
+            $sanswer_type = '多选';
+            $box = "checkbox";
+        }
+
+        $header = "<div class=\"question_list\">
+                        <div class=\"question\">
+                            <div class=\"question_pro\">
+                                <div class=\"question_title\">{$show_title}</div>
+                                <div class=\"question_type\" data-type=\"{$answer_type}\">/{$sanswer_type}</div>
+                            </div>
+                            <div class=\"question_options\">";
+        $opindex = 65;
+        $soptions = '';
+        foreach ($options as $val)
+        {
+            $key = $val['id'];
+            $option = $val['text'];
+
+            $si = sprintf("%c",$opindex++);
+            $soptions .=        "<div class=\"question_option\">
+                                     <label>
+                                         <input type=\"{$box}\" value=\"{$key}\" class=\"check\" name=\"question{$qindex}\">
+                                         <span class=\"label\">{$si}、{$option}</span>
+                                     </label>
+                                  </div>";
+        }
+        $end =              '</div>
+                        </div>
+                    </div>';
+
+        $str = "{$header}{$soptions}{$end}";
+        echo $str;
+    }
+
+    private function show_vote($item)
+    {
+        if(empty($item['data'])) return false;
+        $options = json_decode($item['data'],true);
+        if(empty($options)) return false;
+        $title = $item['title'];
+
+        $reserved = $item['reserved'];
+        $kv = preg_split('/=/',$reserved);
+        if(!empty($kv))
+        {
+            $k = trim($kv[0]);
+            $v = trim($kv[1]);
+            if(!empty($k) && $k == 'vote_type') {
+                $vote_type = $v;
+            }
+        }
+
+        $vote_type = intval($vote_type);
+        if($vote_type == 0) {
+            $svote_type = '单选';
+            $box = "radio";
+        }
+        elseif ($vote_type == 1) {
+            $svote_type = '多选';
+            $box = "checkbox";
+        }
+        else {
+            $svote_type = '最多选两项';
+            $box = "checkbox";
+        }
+
+        $index = $this->mVoteIndex + 1;
+        $str = "<div class=\"vote\">
+                    <div class=\"vote_pro\">
+                        <div class=\"vote_question\">投票{$index}: {$title}</div>
+                        <div class=\"vote_type\" data-type=\"{$vote_type}\">/{$svote_type}</div>
+                    </div>
+                    <div class=\"vote_options\">";
+        foreach ($options as $val)
+        {
+            $key = $val['id'];
+            $option = $val['text'];
+            $soption = "<div class=\"vote_option\">
+                            <label>
+                                <input type=\"{$box}\" value=\"{$key}\" class=\"check\" name=\"vote{$this->mVoteIndex}\">
+                                <span class=\"label\">{$option}</span>
+                            </label>
+                        </div>";
+            $str .= $soption;
+        }
+        $str .=     '</div>';
+        $str .= '</div>';
+
+        echo $str;
+    }
+
+    private function show_vote_result($item)
+    {
+        if(empty($item['data'])) return false;
+        $options = json_decode($item['data'],true);
+        if(empty($options)) return false;
+        $title = $item['title'];
+
+        $reserved = $item['reserved'];
+        $kv = preg_split('/=/',$reserved);
+        if(!empty($kv))
+        {
+            $k = trim($kv[0]);
+            $v = trim($kv[1]);
+            if(!empty($k) && $k == 'vote_type') {
+                $vote_type = $v;
+            }
+        }
+
+        $vote_type = intval($vote_type);
+        if($vote_type == 0) {
+            $svote_type = '单选';
+        }
+        elseif ($vote_type == 1) {
+            $svote_type = '多选';
+        }
+        else {
+            $svote_type = '最多选两项';
+        }
+
+        $str = "<div class=\"vote\">
+                    <div class=\"vote_pro\">
+                        <div class=\"vote_question\">{$title}</div>
+                        <div class=\"vote_type\" data-type=\"{$vote_type}\">/{$svote_type}</div>
+                    </div>";
+
+        $str .=    '<div class="results">';
+        $vote_result = $this->special->vote_result();
+
+        $result = $vote_result[$this->mVoteIndex];
+        $total = 0;
+        foreach ($result as $key => $val) {
+            $total += $val;
+        }
+
+        foreach ($options as $val)
+        {
+            $id = $val['id'];
+            $title = $val['text'];
+
+            $count = $result[$id];
+            if($total > 0) {
+                $per = intval($count * 100 / $total + 0.5);
+            } else {
+                $per = 0;
+            }
+
+            $option =   "<div class=\"result\">
+                            <div class=\"result_option\">{$title}</div>
+                            <div class=\"status\">
+                                <div class=\"status_line\">
+                                    <div class=\"stat\"></div>
+                                    <div class=\"status_bg\"></div>
+                                </div>
+                                <span class=\"num\">{$count}票</span>
+                                <span class=\"percentage\">{$per}%</span>
+                            </div>
+                          </div>";
+            $str .= $option;
+        }
+        $str .=     '</div>';
+        $str .= '</div>';
+
+        echo $str;
+    }
+
+    private function show_text($item)
+    {
+        $data  = $item['data'];
+        echo "<article>{$data}</article>";
+    }
+
+    private function show_image($item)
+    {
+        $image = $item['show_data'];
+        $type  = $item['type'];
+        $title = $item['title'];
+
+        if($type == 'url')
+        {
+            $url  = $item['data'];
+            $str = "<div class=\"thumbnail\">
+                        <a href=\"{$url}\">
+                            <div class=\"thumbnail_image\">
+                                <img src=\"/data/resource/mobile/ugc/images/picLazy_load.png\" data-original=\"{$image}\" alt=\"熊猫美妆\">
+                            </div>                     
+                        </a>                        
+                        <div class=\"thumbnail_pro\">{$title}</div>
+                    </div>";
+        }
+        elseif($type == 'video')
+        {
+            $video  = $item['data'];
+            $str = "<div class=\"thumbnail\">
+                        <div class=\"video_box\" data-poster=\"{$image}\" data-src=\"{$video}\"></div>
+                        <div class=\"thumbnail_pro\">$title</div>
+                    </div>";
+        }
+        else
+        {
+            $str = "<div class=\"thumbnail\">
+                        <div class=\"thumbnail_image\">
+                             <img src=\"/data/resource/mobile/ugc/images/picLazy_load.png\" data-original=\"{$image}\" alt=\"熊猫美妆\">
+                        </div>
+                        <div class=\"thumbnail_pro\">{$title}</div>
+                    </div>";
+        }
+        echo $str;
+    }
+
+    public function show_comments()
+    {
+        if($this->preview()) return;
+        $supporter = new ugc\special_support($this->special_id(),0);
+        $supported = $supporter->supported();
+
+        $str = "<div class=\"bottom_flex\">
+                    <div class=\"msg_btn\">我来说两句</div>";
+        if($supported) {
+            $str .= "<a href=\"javascript:void(0)\" class=\"like_btn active\">
+                        <span class=\"like_icon_null like_icon\"></span>
+                    </a>";
+        } else {
+            $str .= "<a href=\"javascript:void(0)\" class=\"like_btn active\">
+                        <span class=\"like_icon_null\"></span>
+                    </a>";
+        }
+
+        $str .= "<a href=\"javascript:void(0)\" class=\"comment_label\">
+                        <span class=\"msg_icon_null\"></span>";
+        $comments = $this->special->comments();
+        if($comments > 0) {
+            $str .= "<span class=\"superscript\">{$comments}</span>";
+        }
+        $str .= "</a>";
+
+        if(session_helper::isapp())
+        {
+            $str .=    "<a href=\"javascript:void(0)\">
+                            <span class=\"share_icon_null\"></span>
+                        </a>
+                    </div>";
+        } else {
+            $str .= "<a href=\" \" class=\"open_app_btn\">打开APP</a></div>";
+        }
+
+        echo $str;
+    }
+    private function show_appreciate()
+    {
+        $fappreciate = $this->special->has_appreciate();
+        if($fappreciate == false) return;
+
+        $nums = $this->special->appreciates();
+        $header = "<div class=\"appreciate\">
+                        <p class=\"appreciate_pro\">如果你喜欢该文章,请随意打赏。</p >
+                        <div class=\"appreciate_box\">
+                            <div class=\"btn_appreciate\">";
+        if($nums > 0)
+        {
+            $header .=          "打赏<span class=\"appreciate_num\"> | 已有{$nums}次打赏</span>";
+            $header .=      "</div>
+                        </div>
+                        <div class=\"appreciate_users\">";
+
+            $avatars = $this->appreciate_avatars($this->special_id(),20);
+            $sAvatars = '';
+            foreach ($avatars as $avatar) {
+                $sAvatars .= "<img src=\"{$avatar}\">";
+            }
+            $header .= $sAvatars;
+            $header .= '</div>';
+            if($nums > 20) {
+                $header .= '<div class="appreciate_label">....超20人打赏</div>';
+            }
+        }
+        else {
+            $header .=          "打赏";
+            $header .=     "</div>";
+            $header .=  "</div>";
+        }
+        $header .='</div>';
+        echo $header;
+    }
+
+    private function appreciate_avatars($special_id,$count)
+    {
+        $mod = Model('appreciate');
+        $items = $mod->getTopAppreciate($special_id,'*',$count);
+
+        $uids = [];
+        foreach ($items as $item) {
+            $uid = intval($item['member_id']);
+            $uids[] = $uid;
+        }
+
+        $avatars = [];
+        if(!empty($uids))
+        {
+            $mod_member = Model('member');
+            $mInfos = $mod_member->getMemberList(array('member_id' => ['in',$uids]));
+
+            foreach ($mInfos as $info) {
+                $minfo = new member_info($info);
+                $avatar = $minfo->avatar();
+                $avatars[] = $avatar;
+            }
+        }
+
+        return $avatars;
+    }
+    private function show_answer_page()
+    {
+        $specialid = $this->special_id();
+        if($specialid <= 0) return;
+
+        $special = $this->special;
+        if($special->has_question()) {
+            $answer_page = true;
+        }
+
+        if(isset($answer_page) && $answer_page == true)
+        {
+            $mod_answer = Model('ugc_answer');
+            $count = $mod_answer->counts($specialid);
+            if($count > 0) {
+                $url = BASE_SITE_URL . "/mobile/index.php?act=member_ugc&op=answer_page&client_type=wap&special_id={$specialid}";
+                $str = "<p class=\"look_question_result\" style=\"margin-top:40px; color: #FF4E4E; line-height: 70px; text-align: center;font-size: 26px;\"><a href=\"{$url}\">查看答题情况>></a></p >";
+                echo $str;
+                return;
+            }
+        }
+
+        $rule = $this->special->submit_rule();
+        if(!empty($rule))
+        {
+            $type_sn = $rule->type_sn();
+            if(!empty($type_sn)) {
+                $url = BASE_SITE_URL . "/mobile/index.php?act=bonusex&op=detail&client_type=wap&type_sn={$type_sn}";
+                $str = "<p class=\"look_question_result\" style=\"margin-top:40px; color: #FF4E4E; line-height: 70px; text-align: center;font-size: 26px;\"><a href=\"{$url}\">查看红包领取情况>></a></p >";
+                echo $str;
+                return;
+            }
+        }
+    }
+
+    public function show_relation()
+    {
+        if($this->mAuthorRelation == 0) {
+            echo '<div class="focus">+关注</div>';
+        }
+        elseif($this->mAuthorRelation == 1) {
+            echo '<div class="focus active">已关注</div>';
+        }
+        else {
+
+        }
+    }
+}

+ 43 - 0
mapi/control/umeng.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * umeng 推送服务
+ *
+ ***/
+
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class umengControl extends mbMemberControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 更新device_token数据
+     */
+    public function updateOp()
+    {
+        $member_id = $_SESSION['member_id'];
+        $data = array();
+        $data['upush_device_token'] = trim($_GET['device_token']);
+        $data['updatetime'] = time();
+
+        // 判断用户是否存在
+        $ret = Model()->table('device_binding')->where(array('member_id' => $member_id))->select();
+
+        if (!empty($ret)) {
+            $ret = Model()->table('device_binding')->where(array('member_id' => $member_id))->update($data);
+        } else {
+            $data['member_id'] = $member_id;
+            $ret = Model()->table('device_binding')->insert($data);
+        }
+
+        if ($ret) {
+            self::outsuccess(array('result' => 'true'));
+        } else {
+            self::outerr(errcode::ErrDB);
+        }
+    }
+}

+ 29 - 0
mapi/control/uploader.php

@@ -0,0 +1,29 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/9/26
+ * Time: 上午11:19
+ */
+
+require_once (BASE_ROOT_PATH . '/helper/algorithm.php');
+require_once (BASE_ROOT_PATH . '/helper/login_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/sms_helper.php');
+
+class uploaderControl extends mobileControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function __destruct()
+    {
+        parent::__destruct(); // TODO: Change the autogenerated stub
+    }
+    public function upfileOp()
+    {
+
+    }
+}

+ 219 - 0
mapi/control/user_index.php

@@ -0,0 +1,219 @@
+<?php
+/**
+ * 我的商城
+ *
+ *
+ *
+ *
+ * by 33hao.com 好商城V3 运营版
+ */
+
+//use Shopnc\Tpl;
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_ROOT_PATH . '/mobile/control/member_relation.php');
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/special_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/index_tab.php');
+require_once(BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/mobile/control/special.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/room_helper.php');
+
+
+class user_indexControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * 用户详情@扫码进入 登录未知
+     * @微信场景 需要授权
+     * @app场景 需要登录
+     */
+    public function indexOp()
+    {
+        if(empty($_GET['member_id'])) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $memkey = urldecode($_GET['member_id']);
+        $idolid = intval(util::decrypt_data($memkey));
+        if($idolid <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        if(session_helper::need_wechat_author()) {
+            $author = new thrid_author\wxauthor();
+            $url = url_helper::member_index($idolid);
+            $url = $author->enter($url);
+            return self::outsuccess(['direct_uri' => $url],"redirect");
+        }
+
+        if(session_helper::logined() == false)
+        {
+            if(session_helper::isapp()) {
+
+            }
+            else
+            {
+                if(wechat_helper::invite_bonus_tag()) {
+                    wechat_helper::clear_invite_bonus();
+                }
+
+                $type_sn = account_helper::invite_bonus($idolid);
+                if($type_sn == false) {
+                    return self::outerr(errcode::ErrBonus,"生成邀请红包失败.");
+                }
+                else {
+                    $ref_url = url_helper::bonus_open_url($type_sn);
+                    return self::outsuccess(['direct_uri' => $ref_url],"redirect");
+                }
+            }
+        }
+        else
+        {
+            return $this->open_page($idolid,['from_type' => '来自二维码']);
+        }
+    }
+
+    private function open_page($idolid,$output = [])
+    {
+        try
+        {
+            $member_id = session_helper::memberid();
+            $output['is_self'] = $idolid == $member_id ? true : false;
+
+            $relation = new relation\mem_relation($member_id);
+            $isfriend = $relation->is_friends($idolid);
+
+            if(strpos($output['scene'],'applyer') === false)
+            {
+                $output['scene'] = $isfriend ? 'friends' : 'stranger';
+            }
+
+            $minfo = new member_info($idolid);
+            $output['member_info'] = $minfo->filter();
+            $output['is_friend'] = $isfriend;
+
+            $output['member_info']['common_rooms'] = count(room_helper::common_rooms($idolid,$member_id));
+
+            return self::outsuccess($output,"member/index",'wap');
+        }
+        catch (Exception $ex)
+        {
+            Log::record(__METHOD__ . " {$ex->getMessage()}",Log::ERR);
+            return false;
+        }
+    }
+
+    /**
+     * 用户详情@app点击进入 一般为登录状态
+     * @群聊->群详情页面->点击头像
+     * @群聊/单聊->点击头像
+     */
+    public function detailOp()
+    {
+        if(!session_helper::logined()) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+        $idolid = intval($_GET['member_id']);
+        if($idolid <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+        $from = $this->room_name($_GET['room_id']);
+
+        return $this->open_page($idolid,['from_type' => $from]);
+    }
+
+    private function room_name($room_id)
+    {
+        if($room_id > 0)
+        {
+            $room = room_helper::room($room_id);
+            if($room == false) {
+                $from = "来自于群聊";
+            } else {
+                $name = $room->name();
+                $name = util::ellipsis($name);
+                $from = "来自于群聊 {$name}";
+            }
+        }
+        else {
+            $from = '来自于聊天';
+        }
+
+        return $from;
+    }
+
+    /**
+     * 查看好友申请
+     * param msg_id int 消息记录id
+     */
+    public function friend_applyOp()
+    {
+        if(!session_helper::logined()) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+        $msg_id = $_GET['msg_id'];
+        $item = room_helper::message($msg_id);
+        if($item == false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $msg = json_decode($item['orgmsg'],true);
+        $idolid = intval($msg['from']['userid']);
+        if($idolid <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        if($msg['type'] == 'apply_friend') {
+            return $this->open_page($idolid,['from_type' => "来自于好友申请",'scene' => 'friend_applyer','note' => $msg['note'],"msg_id"=>$msg_id]);
+        } elseif($msg['type'] == 'apply_room') {
+            $room = room_helper::room($msg['room_id']);
+            return $this->open_page($idolid,['from_type' => "来自于入群申请",'scene' => 'room_applyer','note' => $msg['note'],"msg_id"=>$msg_id,"room_name"=>util::ellipsis($room->name())]);
+        } else {
+            return self::outerr(errcode::ErrParamter);
+        }
+    }
+
+
+    /**
+     * 群详情页面/申请加群页面  @扫码进入
+     */
+
+    /**
+     * 群聊详情页面/单聊详情页面  一般为登录状态
+     * @群聊/单聊 右上角详情按钮
+     */
+
+    /**
+     * 查看入群申请
+     * @return bool
+     */
+    public function room_applyOp()
+    {
+        if(!session_helper::logined()) {
+            return self::outerr(errcode::ErrUnLogin);
+        }
+        $msg_id = $_GET['msg_id'];
+        $item = room_helper::message($msg_id);
+        if($item == false) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        $msg = json_decode($item['orgmsg'],true);
+        $idolid = intval($msg['from']['userid']);
+        if($idolid <= 0) {
+            return self::outerr(errcode::ErrParamter);
+        }
+
+        return $this->open_page($idolid,['from_type' => '来自于好友申请','scene' => 'applyer','note' => $msg['note']]);
+    }
+}

+ 141 - 0
mapi/control/webpush.php

@@ -0,0 +1,141 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/10/31
+ * Time: 下午4:11
+ */
+
+defined('InShopNC') or exit('Access Invalid!');
+
+require_once (BASE_ROOT_PATH . '/helper/schema_helper.php');
+
+
+class webpushControl extends mobileHomeControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function fcodeOp()
+    {
+        $fc_id = intval($_GET['fc_id']);
+        return self::outsuccess(['tpl' => new tpl_wpush_fcode($fc_id,$this->price_calcer())],"webpush/fcode",'wap');
+    }
+    public function updateOp()
+    {
+        return self::outsuccess(['tpl' => new tpl_wpush_update()],"webpush/fcode",'wap');
+    }
+
+    public function bonusOp()
+    {
+
+    }
+}
+
+class tpl_wpush_fcode
+{
+    private $mFcode;
+    private $mPriceCalcer;
+    public function __construct($fc_id,bonus\IPriceCalculate $price_calcer)
+    {
+        $this->mPriceCalcer = $price_calcer;
+        $mod_fcode = Model('goods_fcode');
+        $this->mFcode = $mod_fcode->getGoodsFCode(['fc_id' => $fc_id],true);
+    }
+
+    private function schema() {
+        $common_id = $this->mFcode['goods_commonid'];
+        $batch_code = $this->mFcode['batch_code'];
+        $mobile = $this->mFcode['mobile'];
+
+        $url = BASE_SITE_URL . "/mobile/index.php?act=fcode&op=index&common_id={$common_id}&batch_code={$batch_code}&mobile={$mobile}";
+        $schema = schema_helper::openurl("购物首单礼",$url);
+        return $schema;
+    }
+    private function summary()
+    {
+        $common_id = intval($this->mFcode['goods_commonid']);
+        $helper = new goods_helper($this->mPriceCalcer,false);
+        $gids = commonid_helper::instance()->goods_ids($common_id);
+        $ret = $helper->get_spu($common_id,$gids[0],$err);
+
+        $summarys = $ret['summary'];
+        foreach ($summarys as $summary)
+        {
+            if($common_id == $summary['goods_commonid'])
+                return $summary;
+        }
+        return false;
+    }
+
+    public function show()
+    {
+        $schema = $this->schema();
+        $summary = $this->summary();
+
+        $price = intval($summary['goods_price'] * 100 + 0.5) / 100;
+        $marketprice = intval($summary['goods_marketprice'] * 100 + 0.5) / 100;
+
+        $str = "<div class=\"push_content\">
+                    <a href=\"{$schema}\" class=\"schema_link\">
+                        <p class=\"push_label\">恭喜您获得新客专享礼</p>
+                        <h3 class=\"push_title\">{$summary['goods_mobile_name']}</h3>
+                        <div class=\"goods_img\">
+                            <img src=\"{$summary['goods_image_url']}\" class=\"img\">
+                            <div class=\"label\">
+                                <p class=\"sale_price\">{$price}元购</p>
+                                <p class=\"original_price\"><span>天猫价{$marketprice}</span></p>
+                            </div>
+                        </div>
+                        <div class=\"btn\"><span class=\"look_btn\">查看详情</span></div>
+                    </a>
+                </div>";
+        return $str;
+    }
+}
+
+class tpl_wpush_update
+{
+    public function __construct()
+    {
+    }
+    public function show()
+    {
+        $head_img = RESOURCE_SITE_URL . "/mobile/push/update/head_img.png";
+        echo   "<div class=\"push_content\">
+                    <a href=\" \" class=\"schema_link\">
+                    <div class=\"head_img\">
+                        <img src=\"{$head_img}\" class=\"img\">
+                    </div>
+                    <div class=\"push_title t_center\">升级到新版本</div>";
+
+        echo       "<div class=\"updata_focus\">";
+        $tips = $this->tips();
+        if(count($tips) == 1){
+            echo "<p>{$tips[0]}</p >";
+        }else{
+            $i = 1;
+            foreach ($tips as $tip) {
+                echo "<p>{$i}.{$tip}</p >";
+                ++$i;
+            }
+        }
+
+        echo       "</div>
+                    <div class=\"btn updata_btn\">
+                        <span class=\"look_btn\">立即升级</span>
+                    </div>
+                    </a>
+                    <span class=\"close_btn\"><img src=\"" . RESOURCE_SITE_URL . "/mobile/push/fcode/close.png\" class=\"img\"></span>
+                </div>";
+    }
+
+    private function tips()
+    {
+        $tips = $GLOBALS['setting_config']['mobile_update_tips'];
+        $artips = explode('#',$tips);
+        return $artips;
+    }
+}

+ 61 - 0
mapi/dispatch_notify.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 16/1/22
+ * Time: 上午10:22
+ */
+
+require_once(BASE_ROOT_PATH . '/helper/kdn_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/account_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/pay_helper.php');
+
+fcgi_header("Content-Type: text/plain; charset=UTF-8");
+try
+{
+    //tid-订单号,status-1,consign_time-发货时间,logistics_no-快递流水,logistics_company-快递公司
+    $order_sn = trim($_POST['tid']);
+    $status = intval($_POST['status']);
+    $consign_time = urldecode(trim($_POST['consign_time']));
+    $ship_time = strtotime($consign_time);
+    $logistics_no = trim($_POST['logistics_no']);
+    $logistics_company = trim(urldecode($_POST['logistics_company']));
+
+    Log::record("dispatch notify value: order_sn = {$order_sn},status={$status},consign_time = {$consign_time} logistics_no = {$logistics_no} logistics_company = {$logistics_company}.", Log::DEBUG);
+    $express = Model('express')->field('id')->where(array('e_name' => $logistics_company))->select();
+    if (empty($express) || count($express) == 0) {
+        echo 'FAIL';
+        return;
+    }
+
+    $express_id = $express[0]['id'];
+    $remote_addr = $_SERVER['REMOTE_ADDR'];
+
+    if (!empty($order_sn) && !empty($logistics_no))
+    {
+        if ($status == 1)
+        {
+            $ret = pay_helper::OnOmsNotify($order_sn,$express_id,$logistics_no,$logistics_company);
+            if ($ret) {
+                QueueClient::push('subscribeKDN',['order_sn'=>$order_sn]);
+                Log::record("push oms success",Log::DEBUG);
+                echo 'SUCCESS';
+            } else {
+                Log::record("push oms error",Log::DEBUG);
+                echo 'SUCCESS';
+            }
+        }
+        else
+        {
+            QueueClient::push('subscribeKDN',['order_sn'=>$order_sn]);
+            echo 'SUCCESS';
+        }
+    } else {
+        echo 'FAIL';
+    }
+}
+catch (Exception $e)
+{
+    Log::record($e->getMessage(), Log::ERR);
+    echo 'AGAIN';
+}

+ 124 - 0
mapi/framework/function/function.php

@@ -0,0 +1,124 @@
+<?php
+/**
+ * mobile公共方法
+ *
+ * 公共方法
+ *
+ */
+defined('InShopNC') or exit('Access Invalid!');
+
+
+require_once(BASE_CORE_PATH . '/framework/libraries/model.php');
+require_once(BASE_DATA_PATH . '/model/member.model.php');
+require_once(BASE_MOBILE_PATH . '/util/errcode.php');
+
+function output_data($datas, $extend_data = array(),$code = 200) 
+{
+    $data = array();
+    $data['code'] = $code;
+
+    if(!empty($extend_data)) {
+        $data = array_merge($data, $extend_data);
+    }
+
+    $data['datas'] = $datas;
+
+    if(!empty($_GET['callback'])) {
+        echo $_GET['callback'].'('.json_encode($data).')';
+    } else {
+        echo json_encode($data);
+    }
+}
+
+function output_error($message, $extend_data = array(),$code = 200) {
+    $datas = array('error' => $message);
+    output_data($datas, $extend_data,$code);
+}
+
+function joutput_data($datas,$type='')
+{
+    $data = [];
+
+    $code = errcode::Success;
+    $data['code'] = $code;
+    $data['message'] = errcode::msg($code);
+
+    $data['datas'] = $datas;
+
+    if($_SESSION['client_type'] != 'ajax')
+    {
+        $contents = ob_get_clean();
+        if(!empty($contents)) {
+            Log::record($contents,Log::ERR);
+        }
+        ob_start();
+    }
+
+    if(!empty($type) && $type == 'web') {
+        echo(json_encode($data,JSON_UNESCAPED_UNICODE));
+    } else {
+        echo(json_encode($data));
+    }
+}
+
+function joutput_error($code,$message = '',$type='')
+{
+    if(empty($message)) {
+        $message = errcode::msg($code);
+    }
+
+    $data = array();
+    $data['code'] = $code;
+    $data['message'] =  $message;
+    $data['datas'] = null;
+
+    if($_SESSION['client_type'] != 'ajax')
+    {
+        $contents = ob_get_clean();
+        if(!empty($contents)) {
+            Log::record($contents,Log::ERR);
+        }
+        ob_start();
+    }
+    Log::record("code = {$code} message = {$message}",Log::ERR);
+
+    if(!empty($type) && $type == 'web') {
+        echo(json_encode($data,JSON_UNESCAPED_UNICODE));
+    } else {
+        echo(json_encode($data,JSON_UNESCAPED_UNICODE));
+    }
+}
+
+function mobile_page($page_count,$totalnum = false)
+{
+    $extend_data = array();
+    $current_page = intval($_GET['curpage']);
+    if($current_page <= 0) {
+        $current_page = 1;
+    }
+    if($current_page >= $page_count) {
+        $extend_data['hasmore'] = false;
+    } else {
+        $extend_data['hasmore'] = true;
+    }
+    $extend_data['page_total'] = $page_count;
+    if($totalnum !== false) {
+        $extend_data['total_num'] = $totalnum;
+    }
+
+    return $extend_data;
+}
+
+/**
+ * 过滤html标签,js代码,css样式标签
+ * @param $str
+ * @return mixed
+ */
+function remove_tags($str) {
+    $str = preg_replace( "@<script(.*?)</script>@is", "", $str );
+    $str = preg_replace( "@<iframe(.*?)</iframe>@is", "", $str );
+    $str = preg_replace( "@<style(.*?)</style>@is", "", $str );
+    $str = preg_replace( "@<(.*?)>@is", "", $str );
+
+    return $str;
+}

+ 1 - 0
mapi/framework/index.html

@@ -0,0 +1 @@
+ 

+ 9 - 0
mapi/index.php

@@ -0,0 +1,9 @@
+<?php
+/**
+ * 手机接口初始化文件
+ *
+ *
+ */
+require_once(BASE_PATH . '/util/errcode.php');
+require_once(BASE_PATH . '/framework/function/function.php');
+require_once(BASE_PATH . '/control/control.php');

+ 3 - 0
mapi/innercb.php

@@ -0,0 +1,3 @@
+<?php
+
+echo ('SUCCESS');

+ 46 - 0
mapi/kdniao_notify.php

@@ -0,0 +1,46 @@
+<?php
+//ini_set("display_errors",1);
+// member_info(E_ALL);
+
+defined('BASE_ROOT_PATH') or define('BASE_ROOT_PATH',str_replace('/mobile','',dirname(__FILE__)));
+require_once(BASE_DATA_PATH . '/logic/delivery.logic.php');
+require_once(BASE_ROOT_PATH . '/helper/kdn_helper.php');
+
+Log::record("快递鸟回调:", Log::DEBUG);
+$requestData = isset($_POST['RequestData']) ? $_POST['RequestData'] : null;  // 快递鸟数据
+
+if (!empty($requestData))
+{
+    $deliver_info = json_decode(urldecode($requestData),true);
+
+    $success = true;
+    $reson = '';
+
+    //数据不正确, 记录并退出
+    if ($deliver_info === false || empty($deliver_info))
+    {
+        $success = false;
+        $reson = 'data is empty.';
+        Log::record("kdniao_notify:cannot query delivery info from kuaidn.",Log::ERR);
+    }
+    else
+    {
+        Log::record("start handle....",Log::DEBUG);
+        $count = intval($deliver_info['Count']);
+        if($count <= 0 || $deliver_info['EBusinessID'] != kdn_helper::cur_businessid()) {
+            $success = false;
+            $reson = "count={$count} or EBusinessID = {$deliver_info['EBusinessID']} != " . kdn_helper::cur_businessid();
+        }
+        else
+        {
+            foreach($deliver_info['Data'] as $item) {
+                kdn_helper::onCallback($item);
+            }
+        }
+    }
+
+    echo (json_encode(['EBusinessID' => kdn_helper::cur_businessid(),
+                       'UpdateTime' => strftime("%Y-%m-%d %H:%M:%S",time()),
+                       'Success' => $success,
+                       'Reason' => $reson]));
+}

+ 0 - 0
mapi/language/index.html


+ 10 - 0
mapi/language/zh_cn/mobile.php

@@ -0,0 +1,10 @@
+<?php
+defined('InShopNC') or exit('Access Invalid!');
+
+$lang['order_state_cancel'] = '已取消';
+$lang['order_state_new'] = '待付款';
+$lang['order_state_pay'] = '待发货';
+$lang['order_state_send'] = '待收货';
+$lang['order_state_success'] = '交易完成';
+$lang['order_state_eval'] = '已评价';
+

+ 73 - 0
mapi/mobile_run.php

@@ -0,0 +1,73 @@
+<?php
+
+define('APP_ID', 'mobile');
+define('MOBILE_SERVER',true);
+define('SUPPORT_PTHREAD',true);
+
+define('BASE_ROOT_PATH', str_replace('/mobile', '', dirname(__FILE__)));
+define('BASE_PATH', BASE_ROOT_PATH . '/mobile');
+
+require_once(BASE_ROOT_PATH . '/global.php');
+require_once(BASE_ROOT_PATH . '/fooder.php');
+require_once(BASE_PATH . '/index.php');
+
+Log::record(__FILE__,Log::DEBUG);
+
+require_once(BASE_ROOT_PATH . '/helper/session.php');
+require_once(BASE_ROOT_PATH . '/helper/img_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/message/msgstates.php');
+require_once(BASE_ROOT_PATH . '/helper/message/msgutil.php');
+require_once(BASE_ROOT_PATH . '/helper/message/subscriber.php');
+require_once(BASE_ROOT_PATH . '/helper/index_tab.php');
+require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/sms_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/model_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/category_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/brand_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once(BASE_ROOT_PATH . '/helper/search/util.php');
+require_once(BASE_ROOT_PATH . '/helper/search_param.php');
+require_once(BASE_ROOT_PATH . '/helper/goods_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/session_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/login_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/third_author/wxauthor.php');
+require_once(BASE_ROOT_PATH . '/helper/fcode/present_manager.php');
+require_once(BASE_ROOT_PATH . '/helper/url_helper.php');
+require_once(BASE_ROOT_PATH . '/helper/activity_helper.php');
+require_once(BASE_HELPER_PATH . '/fcgisrv/MobileServer.php');
+require_once(BASE_HELPER_PATH . '/refill/util.php');
+
+
+function all_channels() {
+    return ['ch_index','activity','goods'];
+}
+
+Base::mobile_init();
+$trdid = Thread::getCurrentThreadId();
+Log::record("thread id = {$trdid}",Log::INFO);
+
+$gMessageStates = new MsgStates();
+StatesHelper::init();
+$listener = new message\subscriber($gMessageStates);
+$listener->start();
+
+function sig_handler($signo)
+{
+    Log::record("queue quit at sig_handler.",Log::DEBUG);
+    switch($signo) {
+        case SIGINT:
+        case SIGHUP:
+        case SIGQUIT:
+        case SIGTERM:
+        default:
+            break;
+    }
+}
+
+pcntl_signal(SIGINT,  'sig_handler');
+pcntl_signal(SIGHUP,  'sig_handler');
+pcntl_signal(SIGQUIT, 'sig_handler');
+pcntl_signal(SIGTERM, 'sig_handler');
+
+fcgisrv\MobileServer::instance()->run_looper();

+ 96 - 0
mapi/pub_wxnotify.php

@@ -0,0 +1,96 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 15/12/10
+ * Time: 下午6:01
+ */
+
+ini_set('date.timezone','Asia/Shanghai');
+error_reporting(E_ERROR);
+
+define('APP_ID','wxpay');
+define('OPEN_WXPAY_PATH', BASE_DATA_PATH.'/api/pub_wxpay');
+require_once(OPEN_WXPAY_PATH . '/lib/WxPay.Api.php');
+require_once(OPEN_WXPAY_PATH . '/lib/WxPay.Config.php');
+require_once(OPEN_WXPAY_PATH . '/lib/WxPay.Data.php');
+require_once(OPEN_WXPAY_PATH . '/lib/WxPay.Exception.php');
+require_once(OPEN_WXPAY_PATH . '/lib/WxPay.Notify.php');
+require_once(BASE_DATA_PATH  . '/logic/delivery.logic.php');
+require_once(BASE_ROOT_PATH  . '/helper/pay_helper.php');
+
+
+//xml格式
+//$content = '<xml><appid><![CDATA[wx24c5645aa986234a]]></appid>
+//<attach><![CDATA[120503418859341217]]></attach>
+//<bank_type><![CDATA[CFT]]></bank_type>
+//<cash_fee><![CDATA[1]]></cash_fee>
+//<fee_type><![CDATA[CNY]]></fee_type>
+//<is_subscribe><![CDATA[N]]></is_subscribe>
+//<mch_id><![CDATA[1279745801]]></mch_id>
+//<nonce_str><![CDATA[smzubtf1eul75d7snt7qzqyh258hwns3]]></nonce_str>
+//<openid><![CDATA[o-E2Rw9BKvBKnHgp41VYdxAHMJqg]]></openid>
+//<out_trade_no><![CDATA[127974580120151214143419]]></out_trade_no>
+//<result_code><![CDATA[SUCCESS]]></result_code>
+//<return_code><![CDATA[SUCCESS]]></return_code>
+//<sign><![CDATA[F43C02BBBB3B5E341D78EE477D67F598]]></sign>
+//<time_end><![CDATA[20151214143425]]></time_end>
+//<total_fee>1</total_fee>
+//<trade_type><![CDATA[APP]]></trade_type>
+//<transaction_id><![CDATA[1002150763201512142078937308]]></transaction_id>
+//</xml>';
+
+fcgi_header("Content-Type: text/html; charset=UTF-8");
+
+try
+{
+    $content = $_SERVER['post_content'];
+    Log::record("content = {$content}",Log::DEBUG);
+    $result = WxPayResults::Init($content);
+    $ret_wx = [];
+    $ret_code = $result['result_code'];
+    Log::record("result_code= {$ret_code}",Log::DEBUG);
+    if($ret_code == 'SUCCESS')
+    {
+        $out_trade_no = $result['out_trade_no'];
+        $pay_sn = $result['attach'];
+        $trade_no = $result['transaction_id'];
+
+        Log::record("out_trade_no={$out_trade_no} and pay_sn={$pay_sn} and trade_no = {$trade_no}",Log::DEBUG);
+
+        $payer = new pay_helper($pay_sn);
+        $cb_info = $payer->update_order($trade_no,pay_helper::PUBWX_PAYMENT);
+        if($cb_info['state'] == false) {
+            Log::record('wxpay error.',Log::DEBUG);
+        }
+        else
+        {
+            Log::record('wxpay success.',Log::DEBUG);
+            if(is_pushoms()) {
+                $logic_delivery = Logic('delivery');
+                $ret = $logic_delivery->putOrder($pay_sn, $trade_no);
+            }
+            $payer->OnSuccess();
+        }
+
+        $ret_wx['return_code'] = 'SUCCESS';
+        $ret_wx['return_msg'] = 'OK';
+    }
+    else {
+        Log::record('wxpay error 2.',Log::DEBUG);
+        $ret_wx['return_code'] = 'FAIL';
+        $ret_wx['return_msg'] = 'Error.';
+    }
+
+    $retoper = new OpenWxPayResults();
+    $retoper->FromArray($ret_wx);
+    $xml = $retoper->ToXml();
+    Log::record("return to wx= {$xml}",Log::DEBUG);
+
+    echo($xml);
+} catch (OpenWxPayException $e){
+    Log::record($e->getTraceAsString(),Log::ERR);
+    $msg = $e->errorMessage();
+    return false;
+}
+

+ 36 - 0
mapi/signature.php

@@ -0,0 +1,36 @@
+<?php
+
+//Log::record("This is signatrue file.");
+//
+//$signature = $_GET["signature"];
+//$timestamp = $_GET["timestamp"];
+//$nonce = $_GET["nonce"];
+//$echostr = $_GET["echostr"];
+$data = json_encode($_POST);
+$sign = $_SERVER['HTTP_SIGN'];
+$addr = $_SERVER['REMOTE_ADDR'];
+$content = $_SERVER['post_content'];
+$xmldata=file_get_contents("php://input");
+$squery = $_SERVER['QUERY_STRING'];
+
+Log::record("request ip:{$addr}",Log::DEBUG);
+Log::record("signature data : {$data}",Log::DEBUG);
+Log::record("content data : {$content}",Log::DEBUG);
+Log::record("query_string data : {$squery}",Log::DEBUG);
+Log::record("HTTP_SIGN : {$sign}",Log::DEBUG);
+Log::record("XML_DATA : {$xmldata}",Log::DEBUG);
+echo ('SUCCESS');
+//var_dump($_POST);
+//echo("{$echostr}");
+//
+//$token = 'stanleykinghelloworld';
+//$tmpArr = [$token, $timestamp, $nonce];
+//sort($tmpArr, SORT_STRING);
+//$tmpStr = implode( $tmpArr );
+//$tmpStr = sha1( $tmpStr );
+//
+//if( $tmpStr == $signature ){
+//    return true;
+//}else{
+//    return false;
+//}

+ 176 - 0
mapi/templates/default/activity/limit_entra.php

@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="UTF-8">
+        <script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js?<?php echo bonus_version(); ?>"></script>
+        <title>限时购</title>
+        <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/activity/css/count_down.css?<?php echo bonus_version(); ?>"/>
+    </head>
+    <body>
+        <div class="maincontent" id="count_goods_box">
+            <div class="count_down_content">
+                <div class="time_box">
+                    <div class="hour" id="hour"></div>
+                    <span>:</span>
+                    <div class="min" id="min"></div>
+                    <span>:</span>
+                    <div class="second" id="second"></div>
+                </div>
+                <h3>
+                    <?php
+                        $price_cent = intval($output['goods_price'] * 100 + 0.5);
+                        if($price_cent > 0) {
+                            $promotion_cent = intval($output['goods_promotion_price'] * 100 + 0.5);
+                            $discount = intval(($promotion_cent / $price_cent) * 100 + 0.5) / 10;
+                            echo( "{$discount}");
+                            echo '<span style="font-size:0.6rem;padding-left:0.12rem;vertical-align: middle;font-weight: 600;">折</span>';
+                        } else {
+                            echo("点击进入");
+                        }
+                    ?>
+                </h3>
+                <div class="count_goods_name"><?php echo($output['goods_name']); ?> </div>
+                <div class="count_goods_price">
+                    <span class="gount_price">¥<?php echo($output['goods_promotion_price']); ?></span>
+                    <span class="purchase_price"><?php echo($output['goods_price']); ?></span>
+                </div>
+            </div>
+            <div class="count_down_image">
+                <img src="<?php echo ($output['goods_image_url']); ?>" alt="限时购"/>
+            </div>
+            <input type="hidden" id="server_local_time" value="<?php echo $output['local_time']; ?>"/>
+            <input type="hidden" id="server_start_time" value="<?php echo $output['act_time']; ?>"/>
+        </div>
+        <script src="<?php echo RESOURCE_SITE_URL; ?>/mobile/activity/js/zepto.min.js?<?php echo bonus_version(); ?>"></script>
+        <script src="<?php echo RESOURCE_SITE_URL; ?>/mobile/activity/js/app_count_down.js?<?php echo bonus_version(); ?>"></script>
+    </body>
+
+    <script type="text/javascript">
+        function init_ios_bridge(callback)
+        {
+            if (window.WebViewJavascriptBridge) {
+                return callback(WebViewJavascriptBridge);
+            }
+
+            if (window.WVJBCallbacks) {
+                return window.WVJBCallbacks.push(callback);
+            }
+
+            window.WVJBCallbacks = [callback];
+            var WVJBIframe = document.createElement('iframe');
+            WVJBIframe.style.display = 'none';
+            WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
+            document.documentElement.appendChild(WVJBIframe);
+            setTimeout(function() {
+                document.documentElement.removeChild(WVJBIframe);
+            }, 0);
+        }
+
+        function init_android_bridge()
+        {
+            if (window.WebViewJavascriptBridge)
+            {
+                WebViewJavascriptBridge.init();
+            }
+            else
+            {
+                document.addEventListener(
+                    'WebViewJavascriptBridgeReady'
+                    , function() {
+                        WebViewJavascriptBridge.init();},
+                    false);
+            }
+        }
+
+        function call_native_handler(handler, data)
+        {
+            if (window.WebViewJavascriptBridge)
+            {
+                window.WebViewJavascriptBridge.callHandler(handler,
+                    data,
+                    null);
+            }
+            else
+            {
+                document.addEventListener(
+                    'WebViewJavascriptBridgeReady'
+                    , function()
+                    {
+                        window.WebViewJavascriptBridge.callHandler(
+                            handler,
+                            data,
+                            null,
+                            false);
+                    }
+                );
+            }
+        }
+        function register_js_hander(name,callback)
+        {
+            if (window.WebViewJavascriptBridge)
+            {
+                window.WebViewJavascriptBridge.registerHandler(name,
+                    callback);
+            }
+            else
+            {
+                document.addEventListener(
+                    'WebViewJavascriptBridgeReady'
+                    , function()
+                    {
+                        window.WebViewJavascriptBridge.registerHandler(name,callback);
+                    }
+                );
+            }
+        }
+
+        var isMobile = {
+            Android: function() {
+                return navigator.userAgent.match(/Android/i);
+            },
+            BlackBerry: function() {
+                return navigator.userAgent.match(/BlackBerry/i);
+            },
+            iOS: function() {
+                return navigator.userAgent.match(/iPhone|iPad|iPod/i);
+            },
+            Opera: function() {
+                return navigator.userAgent.match(/Opera Mini/i);
+            },
+            Windows: function() {
+                return navigator.userAgent.match(/IEMobile/i);
+            },
+            any: function() {
+                return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
+            }
+        };
+
+        if(isMobile.iOS()) {
+            init_ios_bridge(function(bridge) { });
+        } else {
+            init_android_bridge();
+        }
+        register_js_hander('on_js_click',function(data,callback) {
+            callback('{"action":"groupbuy","params":null}');
+        });
+
+        $('#count_goods_box').on('click',function() {
+            call_native_handler('on_native_click','{"action":"groupbuy","params":null}');
+        });
+
+        var server_time = parseInt($('#server_local_time').val());
+        var start_time  = parseInt($('#server_start_time').val());
+        var countDowner = new CountDowner();
+        countDowner.init(server_time,start_time);
+
+        setInterval(function ()
+        {
+            if(countDowner.isEnd() == false) {
+                countDowner.run();
+            } else {
+                location.reload();
+            }
+        },1000);
+
+    </script>
+</html>

+ 75 - 0
mapi/templates/default/article/show.php

@@ -0,0 +1,75 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta content="initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" name=viewport>
+    <title>精选文章</title>
+    <meta name="format-detection" content="telephone=no" />
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/article/css/common.css?<?php echo bonus_version(); ?>"/>
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/article/css/article.css?<?php echo bonus_version(); ?>"/>
+</head>
+<body>
+    <div class="maincontent">
+        <h3 class="title">
+            <?php echo $output['article']['article_title']?>
+        </h3>
+        <div class="time">
+            <?php
+             $article_publish_time=date("Y年m月d日",$output['article']['article_publish_time']);
+             echo $article_publish_time;
+            ?>更新
+        </div>
+        <div>
+            <?php echo $output['article']['article_content'];?>
+        </div>
+        <div class="line"></div>
+    </div>
+</body>
+
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/bridge.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/js/jquery.js" charset="utf-8"></script>
+<script>
+    window.onload=function()
+    {
+        var imgArray  = document.getElementsByTagName('img');
+        var imgLength = imgArray.length;
+
+        for(var i=0; i<imgLength; i++)
+        {
+            (function(i) {
+                imgArray[i].onclick=function(){
+                    var clickImg=imgArray[i].getAttribute('src').toString();
+
+                    var reg =new RegExp("\\?goods_id=(\\d{1,9})$");
+                    var matches=clickImg.match(reg);
+                    if(matches == null) {
+                        return;
+                    }
+                    var goods_id = matches[1];
+                    if(goods_id > 0) {
+                        call_native_handler('on_native_click','{"action":"goods_detail","params":{"goods_id":"' + goods_id + '"}}');
+                    }
+                }
+            })(i);
+        }
+        (function()
+        {
+            var imgArray=$('img');
+            for(var i=0;i<imgArray.length;i++)
+            {
+                if (imgArray.eq(i).attr('width') == 750) {
+                    $('img').eq(i).addClass('img_full');
+                }
+            }
+            $('a').css({"display":"block","font-size":"14px","color":"#7E7E7E","text-align":'center',"margin-top":"-17px"}).attr('href','javascript:void(0)');
+        })();
+    };
+    if(isMobile.iOS()) {
+        init_ios_bridge(function(bridge) { });
+    } else if (isMobile.Android) {
+        init_android_bridge();
+    } else {
+        alert("请在移动设备登录!");
+    }
+
+</script>

+ 448 - 0
mapi/templates/default/bargain/bargain.php

@@ -0,0 +1,448 @@
+<?php defined('InShopNC') or exit('Access Invalid!'); ?>
+<!DOCTYPE html>
+
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>砍价团</title>
+    <meta name="viewport" content="width=750,user-scalable=no,target-densitydpi=device-dpi">
+    <meta name="format-detection" content="telephone=no">
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/css/main.css?<?php echo bonus_version(); ?>"/>
+</head>
+<body>
+
+<div class="maincontent" id="wrapper">
+    <div class="main">
+        <div class="content">
+            <div class="bargain_details">
+                <?php echo $output['tpl']->show_creator();?>
+                <?php $output['tpl']->show_goods(); ?>
+            </div>
+
+            <div class="bargain_handle">
+                <?php echo $output['tpl']->show_button(); ?>
+            </div>
+
+            <div class="bargain_users">
+                <div class="title">我的砍价帮</div>
+                <div class="slide_container">
+                    <ul class="users_list" id="slide_list">
+                        <?php $output['tpl']->show_friends();?>
+                    </ul>
+                </div>
+            </div>
+        </div>
+        <div class="rules_box">
+            <img src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/images/rules.png" class="rules">
+        </div>
+    </div>
+</div>
+<div class="fixed_bottom" id="fixed_bottom">
+    <div class="send_input">
+        <p>我想说几句</p>
+    </div>
+    <div>
+        <div class="send_msg">发送</div>
+    </div>
+    <div>
+        <?php if(!session_helper::isapp()) { ?>
+            <button class="download_app" id="download_app">下载app</button>
+        <?php } ?>
+    </div>
+</div>
+
+<div class="pop hide">
+    <div class="bargain_pop scale">
+        <span class="close_btn"></span>
+        <p class="bargain_msg">您已成功帮砍<span class="ret_bargain"></span>元</p>
+        <p class="bargain_goods_msg">还差<span class="balance"></span>元他就可以拿下心仪商品</p>
+        <span class="join_btn_2"></span>
+    </div>
+</div>
+
+<div class="input_pop hide">
+    <div class="answer_comments">
+        <div class="comments_box">
+            <textarea id="send_msg" cols="30" rows="10" maxlength="150" minlength="1" class="comments" placeholder="我来说几句"></textarea>
+        </div>
+        <div class="comments_submit">
+            <button type="button" id="send_btn" class="comments_submit submit">发送</button>
+        </div>
+        <span class="close_btn"></span>
+    </div>
+</div>
+
+<div class="affirm_pop hide">
+    <div class="affirm_box scale">
+        <span class="affirm_btn"></span>
+        <span class="affirm_close_btn"></span>
+    </div>
+</div>
+
+<?php echo $output['tpl']->show_close_pop(); ?>
+
+
+<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/wx_share.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/shake/js/zepto.min.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/animate.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/iscroll.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/websocket.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/websocket_handles.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/new_bridge.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/qzact/common/share/share.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript">
+
+    var url         = "<?php echo $output['tpl']->share_url(); ?>";
+    var title       = "<?php echo $output['tpl']->share_title(); ?>";
+    var img_url     = "<?php echo $output['tpl']->share_image(); ?>";
+    var sub_title   = "<?php echo $output['tpl']->share_subtitle(); ?>\n\n点击领取";
+    var from_app = <?php $t = session_helper::isapp(); echo $t ? 'true' : 'false'; ?>;
+    var online = true;
+    var bridge = new Bridge();
+
+    weiXinShare.init({
+        title:title,
+        desc:sub_title,
+        link:url,
+        imgUrl:img_url
+    });
+    var jsInit = {
+        action:"view_init",
+        params: {
+            can_share:true,
+            title:title,
+            sub_title:sub_title,
+            img_url:img_url,
+            url:url
+        }
+    };
+    bridge.call_native_handler('on_native_click',JSON.stringify(jsInit));
+
+    $('#invite_btn').on('click',function(){
+        var jsonobject = {
+            action:"share_page",
+            params: {
+                title:title,
+                sub_title:sub_title,
+                img_url:img_url,
+                url:url
+            }
+        };
+        bridge.call_native_handler('on_native_click',JSON.stringify(jsonobject));
+    });
+
+    if(from_app) {
+        $('.send_input').css('width','560px');
+    }
+
+    var myScroll = new IScroll('#wrapper',{
+        click: true,
+        taps:true
+    });
+
+    var barrage = new Barrage();
+    function ret_join(datas){
+        websocket.setMeId(datas.content.me);
+    }
+    //倒计时
+    var count_down_time = <?php echo $output['tpl']->left_time(); ?>;
+    var bargain_count_down = setInterval(function(){
+         count_down_time = count_down_time - 1;
+        formatDuring(count_down_time);
+    },1000);
+
+    function formatDuring(mss) {
+        var days = parseInt( mss / 60 / 60 / 24, 10); //计算剩余的天数
+        var hours = parseInt(mss / 60 / 60 % 24, 10); //计算剩余的小时
+        var minutes = parseInt(mss / 60 % 60, 10);//计算剩余的分钟
+        var seconds = parseInt(mss % 60, 10);//计算剩余的秒数
+
+        if(days <= 0 && hours <= 0 && minutes <= 0 && seconds <= 0) {
+            clearInterval(bargain_count_down);
+            $('.show_count_down').addClass('hide');
+            $('.bargain_over').removeClass('hide');
+            $('#bargain_btn').addClass('hide');
+            $('#join_btn').removeClass('hide');
+            return;
+        }
+        if(days < 10) {
+            days = '0' + days;
+        }
+        if(hours < 10) {
+            hours = '0' + hours;
+        }
+        if(minutes < 10) {
+            minutes = '0' + minutes;
+        }
+        if(seconds < 10) {
+            seconds = '0' + seconds;
+        }
+        $('.days').text(days);
+        $('.hours').text(hours);
+        $('.minutes').text(minutes);
+        $('.seconds').text(seconds);
+    }
+
+
+    //消息滚动
+    var SlideMsgs = function ($parent){
+        this.slide_play = null;
+        this.init = function(){
+            this.play();
+        };
+        this.play = function(){
+            if($parent.children('li').length <= 5){
+                 return;
+            }
+            else {
+                this.slide_play = setInterval(function(){
+                    var $first = $parent.find('li').first();
+                    var height = $first.height();
+                    $first.animate({
+                        marginTop: -height + 'px'
+                    },'ease-out',function(){
+                        $parent.append($first.css('marginTop',0));
+                    })
+                },2000);
+            }
+        };
+        this.addChild = function(msg){
+            var avatar = msg.content.from.avatar;
+            var nickname = msg.content.from.nickname;
+            var value = msg.content.value;
+            this.stop();
+            var sub_html = '<li>' +
+                               '<div class="head_portrait">' +
+                                    '<img src="'+avatar+'">' +
+                                '</div>'+
+                                '<div class="user">' +
+                                    '<div class="user_name">'+nickname+'</div> '+
+                                    '<div class="user_msg">'+this.usermsg()+'</div>'+
+                                '</div>'+
+                                '<div class="bargain_msg">'+
+                                    '<span class="msg">砍掉'+value+'元</span>'+
+                                '</div>'+
+                          '</li>';
+            $parent.append(sub_html);
+            setTimeout(function () {
+                myScroll.refresh();
+            },0);
+            return this;
+        };
+        this.stop = function(){
+            clearInterval(this.slide_play);
+            return this;
+        };
+        this.usermsg = function(){
+            var msgs = ['绑架老板打劫福利',
+                '专治各种买不起',
+                '撸起袖子助你一臂之力',
+                '斧头帮伙计来也',
+                '拔刀相助,在所不辞',
+                '砍得多,全靠俺的一声吼',
+                '看我的青龙偃月刀',
+                '花钱买,不如砍价免费拿',
+                '感情深,刀法稳',
+                '关系好不好,一刀见分晓',
+                '放开那价,让我来',
+                '一刀出手往死里砍'];
+            var Range = 12;
+            var Rand = Math.random();
+            var num = Math.round(Rand * Range); //四舍五入
+            return msgs[num];
+        }
+    };
+
+    var slideMsgs = new SlideMsgs($('#slide_list'));
+    slideMsgs.init();
+
+    //价格变更
+    var priceAnimated = false;
+        function priceChange(nprice){
+        if(priceAnimated) {
+            return;
+        }
+        priceAnimated = true;
+        $('.stamp').removeClass('hide');
+        document.getElementById('stamp').addEventListener('webkitAnimationEnd',function()
+        {
+            setTimeout(function(){
+                $('.stamp').addClass('hide');
+            },500);
+
+            setTimeout(function(){
+                var current_price = document.querySelector('#current_price').innerHTML;
+                var price = current_price.replace('现价',"");
+                document.querySelector('#current_price').innerHTML = "现价¥"+(nprice.toFixed(2));
+                $('.current_price').addClass('scale');
+                document.getElementById('current_price').addEventListener('webkitAnimationEnd',function(){
+                    $('.current_price').removeClass('scale');
+                    priceAnimated = false;
+                });
+            },500);
+        });
+    };
+
+    $('.close_btn').on('click',function(){
+        $('.pop').addClass('hide');
+    });
+
+    //判断用户设备下载app
+    function download_app(){
+        if(bridge.isMobile.iOS()) {
+            window.location.href = 'itms-apps://itunes.apple.com/app/id945609424';
+        }
+        else if(bridge.isMobile.Android()) {
+            window.location.href = "<?php echo BASE_SITE_URL . "/hfive/android_down/index.html"; ?>";
+        }
+    }
+    $('#download_app').on('click',function(){
+        download_app();
+    });
+    $('.join_btn_2').on('click',function(){
+        download_app();
+    });
+    $('.join_btn').on('click',function()
+    {
+        download_app();
+    });
+
+    var room    =  <?php echo $output['room']['room']; ?>;
+    var roomkey = "<?php echo $output['room']['room_key']; ?>";
+    var addr    = "<?php echo $output['room']['addr']; ?>";
+    var room_msgs = {
+        room    : room,
+        roomkey :roomkey
+    };
+    var callbacks = {
+        onOpen:sOpen,
+        onClose:sClose
+    };
+    var msg_handler = {
+        room_info:ret_join,
+        message:message
+    };
+    var websocket = new WebsocketConnect(addr,true,true,callbacks,room_msgs,msg_handler);
+
+    function sOpen(){
+    }
+    function sClose(){
+        online = false;
+    }
+
+    function message(datas)
+    {
+        var msg_type = datas.op;
+        console.log(datas);
+        try
+        {
+            var goods_price  = $('#goods_price').val();
+            var lowest_price = $('#lowest_price').val();
+
+            if(msg_type == 'bargain') {
+                var discount = datas.content.discount;
+                priceChange(goods_price - discount);
+                slideMsgs.addChild(datas).play();
+            }
+            else if(msg_type =='ret_bargain') {
+                var ret_bargain_price = datas.content.value;
+                var discount = datas.content.discount;
+
+                var image = new Image();
+                image.src = "<?php echo RESOURCE_SITE_URL; ?>/mobile/bargain/images/bargain_pop.jpg";
+                image.onload = function(){
+                    $('.bargain_pop').removeClass('hide');
+                };
+                $('.ret_bargain').text(ret_bargain_price);
+
+                var gap = goods_price - lowest_price - discount;
+                gap = (parseInt(gap * 100 + 0.5) / 100).toFixed(2);
+                $('.balance').text(gap);
+                $('.pop').removeClass('hide');
+            }
+            else if(msg_type == 'message') {
+                var msg = datas.content.content;
+                var avatar = datas.content.from.avatar;
+                var nickname = datas.content.from.nickname;
+                barrage.add({
+                    avatar: avatar,
+                    nickname : nickname,
+                    msg: msg
+                }).send();
+            }
+            else if(msg_type == 'bargain_close') {
+                count_down_time = -1;
+            }
+        }
+        catch (e) {
+            alert(e.message)
+        }
+    }
+
+    //砍价按钮
+    $('#bargain_btn').on('click',function(){
+        if(!online) {
+            alert('网络连接失败!请刷新重试');
+            return;
+        }
+        $(this).addClass('hide');
+        $('.join_btn').removeClass('hide');
+        websocket.bargain();
+        myScroll.refresh();
+    });
+
+    //我的砍价按钮
+    $('#mine_bargain_btn').on('click',function(){
+        if(!online) {
+            alert('网络连接失败!请刷新重试');
+            return;
+        }
+        $(this).addClass('hide');
+        websocket.bargain();
+        myScroll.refresh();
+    });
+
+    //发送信息
+    $('#send_btn').on('click',function(){
+        var sendMsg = $('#send_msg').val();
+        if(!sendMsg){return;}
+        websocket.send(sendMsg);
+        $('#send_msg').val('');
+        $('.input_pop').addClass('hide');
+    });
+    //弹起输入框
+    $('.send_input').on('click',function(){
+        $('.input_pop').removeClass('hide');
+        $('#send_msg').focus();
+    });
+    $('.send_msg').on('click',function(){
+        $('.input_pop').removeClass('hide');
+        $('#send_msg').focus();
+    });
+    //关闭输入框
+    $('.close_btn').on('click',function(){
+        $('.input_pop').addClass('hide');
+    });
+
+    $('#just_buy').on('click',function(){
+        $('.affirm_pop').removeClass('hide');
+    });
+
+    $('.affirm_btn').on('click',function(){
+        if(!online) {
+            alert('网络连接失败!请刷新重试');
+            return;
+        }
+        websocket.bargain_over();
+        window.location.reload();
+    });
+
+    $('.affirm_close_btn').on('click',function(){
+        $('.affirm_pop').addClass('hide');
+    });
+
+</script>
+</body>
+</html>
+

+ 91 - 0
mapi/templates/default/bonus/bind.php

@@ -0,0 +1,91 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>熊猫美妆红包</title>
+    <meta name="format-detection" content="telephone=no" />
+    <script src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/flexible.js?<?php echo bonus_version(); ?>"></script>
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/css/common_rem.css?<?php echo bonus_version(); ?>"/>
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/css/content_rem.css?<?php echo bonus_version(); ?>"/>
+</head>
+<body>
+<div class="maincontent center">
+    <div class="top">
+        <div class="top_bg">
+            <?php
+                if($_SESSION['is_app'] == true) {
+                    echo '<img src="' . RESOURCE_SITE_URL . '/mobile/bonus/imgaes/content_bg_top.png">';
+                }
+            ?>
+            <img src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/imgaes/content_bg.png">
+        </div>
+        <div class="logo">
+            <p><?php if($_SESSION['is_app'] != true) echo "熊猫美妆"; ?></p>
+        </div>
+        <div class="sender_head">
+            <img src="<?php echo bonus_output_sender_header($output); ?>"/>
+        </div>
+    </div>
+    <?php bonus_output_type($output); ?>
+    <?php bonus_output_mine($output); ?>
+
+    <div class="linqu_box" id="bind_link">
+        <div>
+            <p class="prompt tel_pro"><?php bonus_out_bindtimeout($output); ?></p>
+        </div>
+        <div class="tel_box">
+            <div class="tel">
+                <input type="tel" placeholder="手机号" id="tel_number"/>
+            </div>
+            <div class="yanz">
+                <div class="yanz_num">
+                    <input type="tel" placeholder="请输入短信验证码" id="yanz"/>
+                </div>
+                <button id="hack">获取验证码</button>
+            </div>
+        </div>
+        <div class="just_button">
+            <p id="bind">提交领取</p>
+        </div>
+    </div>
+
+    <?php bonus_output_bindedinfo($output); ?>
+    <?php echo bonus_out_rule(); ?>
+</div>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/js/zepto.min.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/js/tel.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/wx_share.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/qzact/common/share/share.js?<?php echo bonus_version(); ?>"></script>
+<script>
+    function app()
+    {
+        var app=navigator.userAgent.toLowerCase(),//判断设备
+            app_nav=navigator.appVersion.toLowerCase(),
+            href='';
+        if (app_nav.indexOf('iphone')>-1&&app.indexOf('iphone')){
+            href='http://a.app.qq.com/o/simple.jsp?pkgname=com.lrlz.beautyshop';
+        } else if (app.indexOf('micromessenger')>-1 && app_nav.indexOf('android')>-1) {
+            href = "<?php echo BASE_SITE_URL . "/hfive/android_down/index.html"; ?>";
+        }
+        else {
+            href="javascript:void(0)";
+        }
+        return href;
+    }
+
+    $('#link').attr('href',app());
+    var url         = "<?php echo share_url($output); ?>";
+    var bonus_title = "<?php echo share_title($output); ?>";
+    var img_url     = "<?php echo share_image($output); ?>";
+    var sub_title   = "<?php echo share_subtitle($output); ?>\n\n点击领取";
+
+    weiXinShare.init({
+        title:bonus_title,
+        desc:sub_title,
+        link:url,
+        imgUrl:img_url
+    });
+</script>
+</body>
+</html>

+ 101 - 0
mapi/templates/default/bonus/detail.php

@@ -0,0 +1,101 @@
+<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>熊猫美妆红包</title>
+    <meta name="format-detection" content="telephone=no" />
+    <script src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/flexible.js?<?php echo bonus_version(); ?>"></script>
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/css/common_rem.css?<?php echo bonus_version(); ?>"/>
+    <link rel="stylesheet" href="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/css/content_rem.css?<?php echo bonus_version(); ?>"/>
+</head>
+<body>
+<div class="maincontent center">
+    <div class="top">
+        <div class="top_bg">
+            <?php
+            if($_SESSION['is_app'] == true) {
+//                echo '<img src="' . RESOURCE_SITE_URL . '/mobile/bonus/imgaes/content_bg_top.png">';
+            }
+            ?>
+            <img src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/imgaes/n_content_bg.png">
+        </div>
+
+        <div class="sender_head">
+            <img src="<?php echo bonus_output_sender_header($output); ?>"/>
+        </div>
+    </div>
+
+    <?php bonus_output_type($output); ?>
+    <?php bonus_output_mine($output); ?>
+    <?php bonus_output_present($output); ?>
+    <?php bonus_output_bindedinfo($output); ?>
+    <?php bonnus_out_goods($output); ?>
+    <?php bonus_out_rule(); ?>
+    <?php bonus_out_download(); ?>
+</div>
+
+<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/wx_share.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/js/zepto.min.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/bonus/js/tel.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/mobile/comm/bridge.js?<?php echo bonus_version(); ?>"></script>
+<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/qzact/common/share/share.js?<?php echo bonus_version(); ?>"></script>
+<script>
+    function app()
+    {
+        var app=navigator.userAgent.toLowerCase(),//判断设备
+            app_nav=navigator.appVersion.toLowerCase(),
+            href='';
+        if (app_nav.indexOf('iphone')>-1&&app.indexOf('iphone')){
+            href='http://a.app.qq.com/o/simple.jsp?pkgname=com.lrlz.beautyshop';
+        } else if (app.indexOf('micromessenger')>-1 && app_nav.indexOf('android')>-1) {
+            href = "<?php echo BASE_SITE_URL . "/hfive/android_down/index.html"; ?>";
+        }
+        else {
+            href="javascript:void(0)";
+        }
+
+        return href;
+    }
+
+    $('#link').attr('href',app());
+    var url   = "<?php echo share_url($output); ?>";
+    var bonus_path = "<?php echo share_path($output); ?>";
+    var title = "<?php echo share_title($output); ?>";
+    var img_url    = "<?php echo share_image($output); ?>";
+    var sub_title  = "<?php echo share_subtitle($output); ?>\n\n点击领取";
+
+    weiXinShare.init({
+        title:title,
+        desc:sub_title,
+        link:url,
+        imgUrl:img_url,
+        path:bonus_path
+    });
+
+    if(isMobile.iOS()) {
+        init_ios_bridge(function(bridge) { });
+    } else if (isMobile.Android) {
+        init_android_bridge();
+    } else {
+    }
+
+    window.onload = function ()
+    {
+        var can_share = <?php echo bonus_canshare($output); ?>;
+        var jsonobject = {
+            action:"view_init",
+            params: {
+                can_share:can_share,
+                title:title,
+                sub_title:sub_title,
+                img_url:img_url,
+                url:url,
+                path:bonus_path
+            }
+        };
+        call_native_handler('on_native_click',JSON.stringify(jsonobject));
+    }
+</script>
+</body>
+</html>

+ 0 - 0
mapi/templates/default/bonus/end.php


Some files were not shown because too many files changed in this diff