public function query_map($param)
 {
     $users_where = array();
     $events_where = array();
     // $param = san($param);
     if (!empty($param['where'])) {
         $users_where[] = $events_where[] = $param['where'];
     }
     $users_where[] = "type != 'ind'";
     if (!empty($param['type'])) {
         if ($param['type'] == 'excsr' || $param['type'] == 'csr') {
             //special case #1: ind events belongs to csr
             $users_where[] = "type='csr'";
             $events_where[] = "(type='csr' or type='ind')";
         } else {
             if ($param['type'] == 'csr') {
                 $users_where[] = $events_where[] = "type='csr'";
             } else {
                 if ($param['type'] == 'exngo' || $param['type'] == 'ngo') {
                     //special case #2: fund belongs to extended ngo concept
                     $users_where[] = $events_where[] = "(type='ngo' or type='fund')";
                 } else {
                     $users_where[] = $events_where[] = "type='" . $param['type'] . "'";
                 }
             }
         }
     }
     //领域限制
     if (!empty($param['field'])) {
         $events_where[] = "item_field like '%" . $param['field'] . "%'";
         $users_where[] = "work_field like '%" . $param['field'] . "%'";
     }
     //省份限制
     if (!empty($param['province'])) {
         $users_where[] = $events_where[] = "province like '%" . $param['province'] . "%'";
     }
     if (!empty($param['medal_name'])) {
         $users_where[] = "medals like '%" . x($param['medal_name']) . "%'";
     }
     if (!empty($param['medal'])) {
         $medal_model = new MedalModel();
         $user_ids = $medal_model->select_user_ids_by_medal_id($param['medal']);
         $events_where[] = "user_id in (" . implode(',', $user_ids) . ")";
         $users_where[] = "id in (" . implode(',', $user_ids) . ")";
     }
     //资源标签限制
     if (!empty($param['res_tags'])) {
         $events_where[] = "res_tags like '%" . $param['res_tag'] . "%'";
     }
     if (!empty($param['res_tags2'])) {
         $events_where[] = "res_tags like '%" . $param['res_tag2'] . "%'";
     }
     if (!empty($param['key'])) {
         $events_where[] = "(name like '%" . $param['key'] . "%' or description like '%" . $param['key'] . "%')";
         $users_where[] = "(name like '%" . $param['key'] . "%' or introduction like '%" . $param['key'] . "%')";
     }
     if (!empty($param['start_lon'])) {
         $events_where[] = "longitude > " . $param['start_lon'];
         $users_where[] = "longitude > " . $param['start_lon'];
     }
     if (!empty($param['end_lon'])) {
         $events_where[] = "longitude < " . $param['end_lon'];
         $users_where[] = "longitude < " . $param['end_lon'];
     }
     if (!empty($param['start_lat'])) {
         $events_where[] = "latitude > " . $param['start_lat'];
         $users_where[] = "latitude > " . $param['start_lat'];
     }
     if (!empty($param['end_lat'])) {
         $events_where[] = "latitude < " . $param['end_lat'];
         $users_where[] = "latitude < " . $param['end_lat'];
     }
     //进度限制
     if (!empty($param['progress'])) {
         $today = date('Y-m-d');
         switch ($param['progress']) {
             case 'planning':
                 $events_where[] = "events.begin_time>'{$today}'";
                 break;
             case 'running':
                 $events_where[] = "events.begin_time<'{$today}' and events.end_time>'{$today}'";
                 break;
             case 'finished':
                 $events_where[] = "events.end_time<'{$today}'";
                 break;
             case 'delayed':
                 $events_where[] = "events.progress=1";
                 break;
             case 'failed':
                 //尚未考虑拖延一定时间自动失败
                 $events_where[] = "events.progress=2";
                 break;
             case 'daily':
                 $events_where[] = "events.progress=3";
                 break;
         }
     }
     // if it is not expert mode, only show checked items
     if (!isset($param['expert_mode'])) {
         $events_where[] = $users_where[] = 'is_checked=1';
     }
     $events_where[] = $users_where[] = 'enabled=1';
     $order = "";
     if (!empty($param['order'])) {
         $order = ' order by ' . $param['order'];
     }
     if (isset($param['expert_mode'])) {
         $order = ' order by is_checked, create_time desc';
     }
     $limit = "";
     if (!empty($param['limit'])) {
         $limit = ' limit ' . $param['limit'];
     }
     $sql_list = array();
     if (!empty($param['user_fields'])) {
         $sql_list[] = '(select ' . $param['user_fields'] . ' from users where ' . implode(" and ", $users_where) . ')';
     }
     if (!empty($param['event_fields'])) {
         $sql_list[] = '(select ' . $param['event_fields'] . ' from events where ' . implode(" and ", $events_where) . ')';
     }
     $sql = implode(' union ', $sql_list) . $order . $limit;
     $result = $this->query($sql);
     if (!$result) {
         $result = array();
     }
     return $result;
 }