|
@@ -262,7 +262,7 @@ class Customer extends Start_Controller {
|
|
|
$this->data['wlshop'] = $wlshop;
|
|
$this->data['wlshop'] = $wlshop;
|
|
|
$this->_Template('customer',$this->data);
|
|
$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']);
|
|
$user = $this->user->get_api($_SESSION['api']);
|
|
|
$lv_yjtj = 0;
|
|
$lv_yjtj = 0;
|
|
@@ -3152,4 +3152,213 @@ class Customer extends Start_Controller {
|
|
|
|
|
|
|
|
return $child;
|
|
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);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|