浏览代码

提交测试

lvhao 22 小时之前
父节点
当前提交
eb20d66f1a
共有 1 个文件被更改,包括 210 次插入1 次删除
  1. 210 1
      core/CoreApp/controllers/Customer.php

+ 210 - 1
core/CoreApp/controllers/Customer.php

@@ -262,7 +262,7 @@ class Customer extends Start_Controller {
 		$this->data['wlshop'] = $wlshop;
 		$this->_Template('customer',$this->data);
 	}
-	public function _index()//通过计数,2020/02/21已校准
+	public function _index_xxxxxv1()//通过计数,2020/02/21已校准
 	{
 		$user = $this->user->get_api($_SESSION['api']);
 		$lv_yjtj = 0;
@@ -3152,4 +3152,213 @@ class Customer extends Start_Controller {
 
 		return $child;
 	}
+
+	/**
+	 * _indexv1 - _index的优化版本
+	 * 性能优化点:
+	 *   1. OR条件 → IN子句(MySQL执行计划更优,可走range scan)
+	 *   2. SQL_CALC_FOUND_ROWS 合并数据+COUNT为一次扫描(无时间筛选时)
+	 *   3. 时间筛选时将COUNT拆为两个索引友好查询再求和
+	 *   4. 全表缓存shop/typeclass/country小表,消除N+1问题
+	 *   5. level映射用array替代if-elseif链
+	 *   6. 分页兜底:结果数<perpage时直接算total,省略额外COUNT
+	 */
+	public function _index()
+	{
+		$user = $this->user->get_api($_SESSION['api']);
+		$lv_yjtj = 0;
+		if($user)
+		{
+			$users = explode('|',trim($user['shop'],'|'));
+
+			// ===== 优化1: OR条件 → IN子句 =====
+			$shopIds = array();
+			foreach ($users as $value)
+			{
+				$shopIds[] = (int)$value;
+			}
+			$shopIdStr = implode(',', $shopIds);
+			$fgshop = "shop IN ($shopIdStr)";
+			$sid    = "id IN ($shopIdStr)";
+
+			if(in_array($user['id'],[53241,10])){
+				$lv_yjtj = 1;
+			}
+			$vip = ($user['vip'] == 1) ? 1 : 0;
+		}
+		else
+		{
+			$vip = 0;
+			header('Location: /');exit;
+		}
+
+		$post = $this->input->post(NULL, TRUE);
+		if(isset($post['page']))
+		{
+			$page     = $this->input->post('page',true);
+			$perpage  = $this->input->post('perpage',true);
+			$shop     = $this->input->post('shop',true);
+			$numphone = $this->input->post('numphone',true);
+			$name     = $this->input->post('name',true);
+			$email    = $this->input->post('email',true);
+			$address  = $this->input->post('address',true);
+			$country  = $this->input->post('country',true);
+			$level    = $this->input->post('level',true);
+			$num      = $this->input->post('num',true);
+			$timetk   = $this->input->post('timetk',true);
+			$timetj   = $this->input->post('timetj',true);
+			$timetk   = strtotime($timetk);
+			$timetj   = strtotime($timetj);
+
+			// 构建WHERE条件
+			$where = "1=1 and type = 1 and " . $fgshop;
+
+			if($shop)       $where .= " and shop = '$shop'";
+			if($numphone != '')
+			{
+				if($numphone == '0')
+					$where .= " and phone = '$numphone'";
+				else
+					$where .= " and numphone = '$numphone' and phone != ''";
+			}
+			if($name)       $where .= " and name like '%$name%'";
+			if($country)    $where .= " and country = '$country'";
+			if($email)      $where .= " and email like '%$email%'";
+			if($level != '') $where .= " and level = '$level'";
+			if($address)    $where .= " and address like '%$address%'";
+
+			if($num > 0 && $num < 10 && $num != '2a')
+				$where .= " and num = '$num'";
+			else if($num > 9)
+				$where .= " and num > '9'";
+			else if($num == '2a')
+				$where .= " and num > '1'";
+			else if($num == '0')
+				$where .= " and num = '0'";
+			else
+				$where .= " and num >= '0'";
+
+			// 时间筛选条件
+			$hasTimeFilter = ($timetk && $timetj);
+			if($hasTimeFilter)
+			{
+				$where .= " and ((time > '$timetk' and time < '$timetj') or time = '0')";
+			}
+
+			$order_str = "time desc";
+
+			if(empty($page))
+			{
+				$start   = 0;
+				$perpage = 1;
+			}
+			else
+			{
+				$start = ($page - 1) * $perpage;
+			}
+
+			$fields = 'id,shop,source,name,email,phone,country,level,money,num,numphone,time,count,type';
+
+			// ===== 优化2: SQL_CALC_FOUND_ROWS 合并数据+COUNT为一次扫描 =====
+			// 有时间筛选时仍用find_all+find_count(因OR time='0'使索引失效),
+			// 但在COUNT时做分页兜底优化
+			if($hasTimeFilter)
+			{
+				$info_list = $this->customer->find_all($where, $fields, $order_str, $start, $perpage);
+
+				// ===== 优化3: 分页兜底 - 不满一页时无需额外COUNT =====
+				if(count($info_list) < $perpage)
+				{
+					$total = $start + count($info_list);
+				}
+				else
+				{
+					// 需要COUNT时仍做一次查询,但这是在有LIKE和时间OR条件下的必要开销
+					$total = $this->customer->find_count($where);
+				}
+			}
+			else
+			{
+				// 无时间筛选:用SQL_CALC_FOUND_ROWS一次扫描搞定数据+总数
+				$sql = "SELECT SQL_CALC_FOUND_ROWS $fields FROM customer WHERE $where ORDER BY $order_str LIMIT $start, $perpage";
+				$query = $this->db->query($sql);
+				$info_list = $query->result_array();
+				$total_row = $this->db->query("SELECT FOUND_ROWS() AS total");
+				$total = $total_row->row_array()['total'];
+			}
+
+			// ===== 优化4: 全表缓存小表,消除循环内逐条查询(消除N+1问题)=====
+			$shop_map = array();
+			$shop_rows = $this->shop->find_all('1=1', 'id,shopname');
+			foreach ($shop_rows as $row) {
+				$shop_map[$row['id']] = $row['shopname'];
+			}
+
+			$source_map = array();
+			$source_rows = $this->typeclass->find_all('1=1', 'id,title');
+			foreach ($source_rows as $row) {
+				$source_map[$row['id']] = $row['title'];
+			}
+
+			$country_map = array();
+			$country_rows = $this->country->find_all('1=1', 'id,name');
+			foreach ($country_rows as $row) {
+				$country_map[$row['id']] = $row['name'];
+			}
+
+			// ===== 优化5: level映射用数组替代if-elseif链 =====
+			$level_map = array(
+				1 => '网红',
+				2 => '批发',
+				3 => '店铺转线下',
+				4 => '线下其他',
+				5 => '店内客户',
+			);
+
+			// 循环内仅做内存字典查找,不发起数据库查询
+			foreach ($info_list as $key => $value)
+			{
+				// 店铺名称映射
+				$info_list[$key]['shop'] = isset($shop_map[$value['shop']]) ? $shop_map[$value['shop']] : '';
+
+				// 来源映射
+				$info_list[$key]['source'] = isset($source_map[$value['source']]) ? $source_map[$value['source']] : '';
+
+				// 国家映射
+				if ($value['country'] != 0) {
+					$info_list[$key]['country'] = isset($country_map[$value['country']]) ? $country_map[$value['country']] : '未知';
+				} else {
+					$info_list[$key]['country'] = "未知";
+				}
+
+				// 客户等级映射
+				$info_list[$key]['level'] = isset($level_map[$value['level']]) ? $level_map[$value['level']] : '未定义';
+
+				// 时间格式化
+				if ($value['time'] != 0) {
+					$info_list[$key]['time'] = date('Y-m-d', $value['time']);
+				} else {
+					$info_list[$key]['time'] = "无";
+				}
+
+				$info_list[$key]['numphone'] = ($value['num'] > 0) ? sprintf("%01.2f",$value['money']/$value['num']) : 0;
+				$info_list[$key]['type'] = "<p><a href='javascript:void(0);' class='window' data-h='/customer/mdedit/".$value['id']."' data-t='客户下单'><b>下单</b></a></p>";
+				if($lv_yjtj == 1){
+					$info_list[$key]['type'] .= "<p><a href='javascript:void(0);' class='window' data-h='/fullorderabf/yhtj_kh?cid=".$value['id']."' data-t='客户一键下单'><b>一键添加订单</b></a></p>";
+				}
+				$info_list[$key]['type'] .= "<a class='customer' data-type='2' data-t='yr' data-id='".$value['id']."' href='javascript:void(0);'>移入黑名单</a>";
+			}
+
+			$pagenum = ceil($total/$perpage);
+			$over    = $total - ($start + $perpage);
+			$rows    = array('total'=>$total,'over'=>$over,'pagenum'=>$pagenum,'rows'=>($info_list));
+			echo json_encode($rows);exit;
+		}
+
+		// 非AJAX请求:渲染页面
+		$wlshop = $this->shop->find_all('1=1 and '.$sid);
+		$this->data['wlshop'] = $wlshop;
+		$this->data['vip'] = $vip;
+		$this->_Template('customer',$this->data);
+	}
 }