# coding=utf-8
from __future__ import absolute_import, print_function, unicode_literals

import json
import logging
import datetime
import urlparse
from datetime import timedelta
from itertools import chain
import time
import requests
from django.conf import settings
from django.db.models import Q, Count, Sum, Max
from django.utils import timezone
from gm_types.gaia import ORDER_STATUS, REFUND_STATUS, ADVER_MANAGEMENT_POSITION_TYPE, HOSPITAL_TYPE
from requests.exceptions import RequestException

from api.business.tag import TagControl
from api.models import Order, SingleRecord, Service, Tag
from api.models.advertise_management import AdvertiseManagement
from api.models.tickets import Punishment

from .es import tzlc, to_epoch
from .transfer import get_area_tag_info, MAX_TIME
from doris.models import ServiceStat
from rpc.cache import data_transfer_cache
from rpc.cache import search_dic_cache
from rpc.context import get_gaia_local_invoker
from search.utils.dic import DIC_CACHE_KEY
from social.models import UserFollow
from talos.abstractviews.diary import get_service_diary_count
from trans2es.doris.service import get_service_stat
from hippo.tool.merchant_tool import doctor_merchant_map
from search.utils.area import get_nearby_city_tag
from helios.rpc.internal.default_invoker import create_default_invoker
from rpc.context import get_rpc_remote_invoker
from rpc.cache import common_cache as redis_client
from search.utils.es import get_es, es_index_adapt, es_indices_analyze
import traceback

MARS_API_HOST = settings.DATA_TRANSFER_MARS_API_HOST
MARS_AUTH_KEY = settings.DATA_TRANSFER_MARS_AUTH_KEY

ORDER_BOUGHT_STATUS = [
    ORDER_STATUS.PAID,
    ORDER_STATUS.USED,
    ORDER_STATUS.REFUNDED,
    ORDER_STATUS.SETTLED,
    ORDER_STATUS.WAIT_REFUNDED,
]


class MarsDataError(Exception):
    def __init__(self, api=None, http_status=None, error_code=None, message=''):
        self.api = api
        self.http_status = http_status
        self.error_code = error_code
        self.message = message

    def __str__(self):
        return 'api[%s] http_status[%s] error_code[%s] message[%s]' % (
            self.api, self.http_status, self.error_code, self.message)


def _get_cache(cache_key):
    cache_res = data_transfer_cache.get(cache_key)
    if cache_res is not None:
        return json.loads(cache_res)
    else:
        return None


def _set_cache(cache_key, value, expire=86400):
    """cached in one day
    """
    value = json.dumps(value)
    return data_transfer_cache.setex(cache_key, expire, value)


def _get_cur_date():
    now = tzlc(timezone.now())
    if now.hour >= 12:  # 超过12点取昨天
        return now - timedelta(days=1)
    else:
        return now - timedelta(days=2)


def mars_call(method, params, from_cache=False):
    raise MarsDataError()
    if from_cache:
        # read from cache
        cache_key_params = '#'.join([
            k + ':' + str(v) for k, v in sorted(params.items())
        ])
        cache_key = method + '#' + cache_key_params
        cache_res = _get_cache(cache_key)
        if cache_res is not None:
            return cache_res

    payload = params.copy()
    payload['gmauth_key'] = MARS_AUTH_KEY
    url = urlparse.urlunparse(('http', MARS_API_HOST, method, '', '', ''))

    try:
        resp = requests.post(url, data=payload, allow_redirects=False)
        if resp.status_code != 200:
            raise MarsDataError(api=url, http_status=resp.status_code)
        res = resp.json()
        if res['error'] != 0:
            raise MarsDataError(api=url, http_status=200, error_code=res['error'])
        res = res['data']
    except RequestException as e:
        raise MarsDataError(
            api=url,
            http_status=None,
            error_code=None,
            message='request exception: %s' % e)

    if from_cache:
        # set cache
        _set_cache(cache_key, res)
    return res


def get_service_quality_score(s):
    res = 0.0

    gengmei_price = s.lowest_gengmei_price
    discount_price = s.lowest_discount
    if gengmei_price > 0:
        res += float(discount_price) / gengmei_price  # 抽成评分

    res += s.rating / 5.0  # 美购评价

    return res / 2


def get_doctor_quality_score(s):
    doctor = s.doctor
    if not doctor:
        return 0.0

    res = 0.0

    if doctor.big:
        res += 1.0  # 大牌

    doctor_license = doctor.get_doctor_lincence('', '')
    if doctor_license['show_v'] == '1':
        res += 1.0  # 双证齐全

    res += float(doctor.rate) / 5.0  # 医生评分

    return res / 3


def get_service_popularity_score(s, date_str):
    res = 0.0

    time_thres = timezone.now() - timedelta(days=30)
    order_base = Order.objects.filter(created_time__gte=time_thres, service=s)
    m = order_base.filter(validated=True).count()  # 近30天验证数
    n = order_base.filter(Q(status=ORDER_STATUS.REFUNDED) |  # 近30天退款数
                          Q(refund__status=REFUND_STATUS.REFUNDED)).count()
    p = order_base.filter(status__in=(  # 近30天支付数
        ORDER_STATUS.PAID,
        ORDER_STATUS.USED,
        ORDER_STATUS.REFUNDED,
        ORDER_STATUS.SETTLED,
        ORDER_STATUS.WAIT_REFUNDED,
        ORDER_STATUS.AUDITING,
        ORDER_STATUS.SETTLING,
    )).count()
    if p > 0:
        res += float(m - n) / p  # 验证支付比评分
    else:
        verify = mars_call('/api/service/verify_30day_avg',
                           params={'record_time': date_str}, from_cache=True)['verify_rate']
        res += verify

    pv = mars_call('/api/service/pv',
                   params={'record_time': date_str, 'service_id': s.id})['pv_cnt']
    pv_max = mars_call('/api/service/pv_max',
                       params={'record_time': date_str}, from_cache=True)['pv_cnt_max']
    if pv_max > 0:
        res += float(pv) / pv_max  # pv评分

    diary_cnt = mars_call('/api/service/diary_cnt_30day',
                          params={'record_time': date_str, 'service_id': s.id})['diary_cnt']
    diary_cnt_max = mars_call('/api/service/diary_cnt_30day_max',
                              params={'record_time': date_str}, from_cache=True)['diary_cnt_max']
    if diary_cnt_max > 0:
        res += float(diary_cnt) / diary_cnt_max  # 日记帖数评分

    return res / 3


def get_doctor_popularity_score(s, date_str):
    def get_max_follow_cnt(date_str):
        cache_key = 'mxflwcnt#' + date_str
        cache_res = _get_cache(cache_key)
        if cache_res is not None:
            return cache_res
        mx_cnt = UserFollow.objects.filter(bond=True) \
            .values('follow').annotate(follow_cnt=Count('follow')) \
            .order_by('-follow_cnt')[0]['follow_cnt']
        _set_cache(cache_key, mx_cnt)
        return mx_cnt

    doctor = s.doctor
    if not doctor or not doctor.user:
        return 0.0

    res = 0.0

    follow_cnt = UserFollow.objects.filter(follow_id=doctor.user_id, bond=True).count()
    max_follow_cnt = get_max_follow_cnt(date_str)
    if max_follow_cnt > 0:
        res += follow_cnt / max_follow_cnt

    pv = mars_call('/api/doctor/pv',
                   params={'record_time': date_str, 'doctor_id': doctor.id})['pv']
    pv_max = mars_call('/api/doctor/pv_max',
                       params={'record_time': date_str}, from_cache=True)['pv_max']
    if pv_max > 0:
        res += float(pv) / pv_max  # 医生pv评分

    diary_cnt = mars_call('/api/doctor/diary_cnt_30day',
                          params={'record_time': date_str, 'doctor_id': doctor.id})['diary_cnt']
    diary_cnt_max = mars_call('/api/doctor/diary_cnt_30day_max',
                              params={'record_time': date_str}, from_cache=True)['diary_cnt']
    if diary_cnt_max > 0:
        res += float(diary_cnt) / diary_cnt_max  # 医生日记贴数pv评分

    msg_user_cnt = mars_call('/api/doctor/msg_user_cnt_30day',
                             params={'record_time': date_str, 'doctor_id': doctor.id})['user_cnt']
    msg_user_cnt_max = mars_call('/api/doctor/msg_user_cnt_30day_max',
                                 params={'record_time': date_str}, from_cache=True)['user_cnt_max']
    if msg_user_cnt > 0:
        res += float(msg_user_cnt) / msg_user_cnt_max  # 回复私信用户评分

    return res / 3


def get_smart_rank(s):
    try:
        smart_rnk = s.smartrank.smart_rank
    except Service.smartrank.RelatedObjectDoesNotExist:
        smart_rnk = 0.0
    return smart_rnk


def get_smart_rank_new(s):
    try:
        smart_rnk = s.smartrank.new_smart_rank
    except Service.smartrank.RelatedObjectDoesNotExist:
        smart_rnk = 0.0
    return smart_rnk


def get_smart_rank_v4(s):
    try:
        smart_rnk = s.smartrank.smart_rank_v4
    except Service.smartrank.RelatedObjectDoesNotExist:
        smart_rnk = 0.0
    return smart_rnk


def get_recommend_rank(s):
    recommend_rank = {
        'is_recommend': False,
        'rank': 999999,
    }
    try:
        if s.recommend.is_delete is True:
            return recommend_rank
        recommend_rank = {
            'is_recommend': s.recommend.is_recommend,
            'rank': s.recommend.rank,
        }
    except Service.recommend.RelatedObjectDoesNotExist:
        pass

    return recommend_rank


def get_single_record_count(s):
    """
    获取飞单记录
    """
    now_time = _get_cur_date()
    start_time = now_time - timedelta(days=60)
    now_time = now_time.strftime("%Y-%m-%d")
    start_time = start_time.strftime("%Y-%m-%d")
    single_record_count = SingleRecord.objects.filter(
        service=s, single_date__range=[start_time, now_time]
    ).count()
    return single_record_count


def get_valited_rate(s):
    """
    获取验证总价比例
    """
    now_time = _get_cur_date()
    start_time = now_time - timedelta(days=30)

    cache_key = "service_max_price:%s" % now_time.strftime("%y%m%d")
    now_time = now_time.strftime("%Y-%m-%d")
    start_time = start_time.strftime("%Y-%m-%d")
    max_price = _get_cache(cache_key)
    if max_price is None:
        service_max_price = Order.objects.filter(
            validated=True, validate_time__range=[start_time, now_time]
        ).values(
            'service__id'
        ).annotate(sum_payment=Sum('real_payment')).aggregate(Max('sum_payment'))
        max_price = service_max_price['sum_payment__max']
        _set_cache(cache_key, max_price)

    total_price = Order.objects.filter(
        service=s, validated=True, validate_time__range=[start_time, now_time]
    ).aggregate(Sum('real_payment'))

    try:
        rate = total_price['real_payment__sum'] / float(max_price)
    except:
        rate = 0.0
        pass
    return rate


def get_discount_rate(s):
    """
    获取抽成比例
    """
    now_time = _get_cur_date()
    start_time = now_time - timedelta(days=30)

    cache_key = "service_max_discount:%s" % now_time.strftime("%y%m%d")
    now_time = now_time.strftime("%Y-%m-%d")
    start_time = start_time.strftime("%Y-%m-%d")
    max_discount = _get_cache(cache_key)
    if max_discount is None:
        service_max_discount = Order.objects.filter(
            validated=True, validate_time__range=[start_time, now_time]
        ).values(
            'service__id'
        ).annotate(sum_discount=Sum('service__discount')).aggregate(Max('sum_discount'))
        max_discount = service_max_discount['sum_discount__max']
        _set_cache(cache_key, max_discount)

    discount = Order.objects.filter(
        service=s, validated=True, validate_time__range=[start_time, now_time]
    ).values(
        'service__id'
    ).aggregate(sum_discount=Sum('service__discount'))
    try:
        rate = discount['sum_discount'] / float(max_discount)
    except:
        rate = 0.0
        pass
    return rate


def get_advertise_info(s):
    """ a tuple of (advertise_position, advertise_searchwords, advertise_info)
    """
    # 只选出未过期的广告
    now = timezone.now()
    ad_positions = set()
    ad_searchwords = set()
    ad_info = []
    ads = AdvertiseManagement.objects.filter(
        service=s, is_online=True, end_time__gt=now)
    for ad in ads:
        show_positions = set(ad.get_show_position)
        ad_positions.update(show_positions)
        if ADVER_MANAGEMENT_POSITION_TYPE.SREACH_RESULT in show_positions:
            ad_searchwords.update(set(ad.get_search_words))
        ad_tags = TagControl.get_descendants(initial_set=ad.tags.all(),
                                             exclude_init=False,
                                             is_online_only=True)
        ad_info.append({
            'id': ad.id,
            'position': list(show_positions),
            'start_time_epoch': to_epoch(tzlc(ad.start_time)),
            'end_time_epoch': to_epoch(tzlc(ad.end_time) if ad.end_time else MAX_TIME),
            'searchwords': ad.get_search_words,
            'ordering': ad.ordering,
            'ad_tag_ids': [tag.id for tag in ad_tags],
            "show_city_tags": ad.show_city_tags()
        })
    return (list(ad_positions), list(ad_searchwords), ad_info)


def wordrel_synonym_list(analyze_res, total_match_synonym=False, ori_quey=""):
    try:
        synonym_term_list = set()

        for item in analyze_res["tokens"]:
            if "type" in item and item["type"] == "SYNONYM" and "token" in item:
                if total_match_synonym:
                    if "start_offset" in item and item["start_offset"] == 0 \
                            and "end_offset" in item and item["end_offset"] == len(ori_quey):
                        synonym_term_list.add(item["token"])
                else:
                    synonym_term_list.add(item["token"])

        return list(synonym_term_list)
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return []


def get_old_new_tag_mapping():
    try:
        old_new_mapping_dict = {
            "三点定位双眼皮": "双眼皮",
            "埋线双眼皮": "埋线双眼皮",
            "切开双眼皮": "切开双眼皮",
            "韩式双眼皮": "微创双眼皮",
            "双眼皮修复": "双眼皮修复",
            "眼综合": "眼综合",
            "外切去眼袋": "祛眼袋",
            "内切去眼袋": "祛眼袋",
            "激光去眼袋": "祛眼袋",
            "框格释放": "祛眼袋",
            "开外眼角": "开眼角",
            "开内眼角": "开眼角",
            "玻尿酸祛黑眼圈": "祛黑眼圈",
            "激光祛黑眼圈": "祛黑眼圈",
            "胶原蛋白填充祛黑眼圈": "祛黑眼圈",
            "下眼下至术": "眼睑下至",
            "自体脂肪丰卧蚕": "卧蚕",
            "玻尿酸丰卧蚕": ["卧蚕", "玻尿酸丰卧蚕"],
            "玻尿酸丰泪沟": "玻尿酸填充泪沟",
            "埋线隆鼻": "隆鼻",
            "自体真皮隆鼻": "隆鼻",
            "硅胶隆鼻": "隆鼻",
            "肋软骨隆鼻": "隆鼻",
            "假体垫鼻基底": "鼻基底",
            "玻尿酸垫鼻基底": "鼻基底",
            "肉毒素缩鼻头": "缩小鼻头",
            "鼻小柱延长": "鼻小柱延长",
            "隆鼻修复": "鼻修复",
            "鼻综合": "鼻综合",
            "溶脂针瘦脸": "溶脂针瘦脸",
            "肉毒素瘦脸": "瘦脸针",
            "磨骨手术": "磨骨",
            "线雕": "面部提升",
            "pst": "面部提升",
            "自体脂肪填充": "自体脂肪全面部填充",
            "玻尿酸丰太阳穴": "玻尿酸丰太阳穴",
            "玻尿酸全面部填充": "玻尿酸全脸填充",
            "玻尿酸丰面颊": "玻尿酸全脸填充",
            "玻尿酸丰额头": "玻尿酸全脸填充",
            "玻尿酸丰眼窝": "玻尿酸全脸填充",
            "面吸": "面部吸脂",
            "取颊脂垫瘦脸": "面部吸脂",
            "玻尿酸丰下巴": "玻尿酸丰下巴",
            "膨体垫下巴": "假体下巴",
            "上下颚手术": "下颌角切除术",
            "下颌角手术": "下颌角切除术",
            "V-LINE瓜子脸手术": "下颌角切除术",
            "下颌缘提升": "下颌缘提升",
            "人中缩短术": "人中缩短",
            "颧骨内推": "颧骨降低",
            "颧骨颧弓整形术": "颧骨内推",
            "颧弓内推": "颧弓内推",
            "玻尿酸丰苹果肌": "玻尿酸填充丰苹果肌",
            "抽脂": "吸脂",
            "溶脂针注射": "溶脂针",
            "韩国V-Line溶脂针": "溶脂针",
            "溶脂": "溶脂",
            "火凤凰溶脂": "溶脂",
            "热立塑": "溶脂",
            "UltraShape优立塑": "溶脂",
            "针灸减肥": "埋线减肥",
            "冷冻溶脂": "冷冻溶脂",
            "酷塑冷冻溶脂": "冷冻溶脂",
            "射频溶脂瘦脸": "射频溶脂",
            "隔空溶脂": "射频溶脂",
            "冷冻除毛": "脱毛",
            "脱毛": "脱毛",
            "毛发移植": "毛发移植",
            "FUE植发": "毛发移植",
            "半永久发际线": "种植发际线",
            "种植发际线": "种植发际线",
            "吸脂瘦手臂": "吸脂瘦手臂",
            "Vaser超声吸脂": "吸脂",
            "水动力吸脂": "吸脂",
            "吸脂瘦大腿": "大腿吸脂",
            "吸脂瘦腰部": "腰腹吸脂",
            "腹壁成形术": "腹壁成形术",
            "冷冻溶脂瘦腰部": "腹壁成形术",
            "射频溶脂瘦腰部": "腹壁成形术",
            "肉毒素瘦肩肌": ["腹壁成形术", "瘦肩针"],
            "瘦肩针": "瘦肩针",
            "假体丰臀": "丰臀",
            "自体脂肪丰臀": "丰臀",
            "玻尿酸": "玻尿酸",
            "水光针注射": "水光针",
            "种植面膜": "水光针",
            "光子嫩肤": "光子嫩肤",
            "DPL精准嫩肤": "光子嫩肤",
            "飞顿II号": "光子嫩肤",
            "美白针治疗": "美白针",
            "热玛吉": ["热玛吉", "热拉提"],
            "调Q激光净肤": "祛斑",
            "超声刀": "超声刀",
            "韩国Doublo-M超声刀": "超声刀",
            "皮秒": "皮秒",
            "蜂巢皮秒": "皮秒",
            "果酸焕肤": "果酸焕肤",
            "水杨酸焕肤": "果酸焕肤",
            "杏仁酸焕肤": "果酸焕肤",
            "化学换肤": "果酸焕肤",
            "水杨酸祛痘": "祛痘",
            "红蓝光": "祛痘",
            "针清祛痘": "祛痘",
            "微针": "微针",
            "点阵": "点阵激光",
            "小气泡": "小气泡",
            "Hydromax小气泡": "小气泡",
            "水氧活肤": "小气泡",
            "Enlighten皮秒": "皮秒激光",
            "探索皮秒": "皮秒激光",
            "Pico four皮秒": "皮秒激光",
            "音波提拉": "拉皮",
            "伊肤泉微针": "黄金微针",
            "白瓷娃娃": "白瓷娃娃",
            "星际行者": "白瓷娃娃",
            "肉毒注射": "肉毒素",
            "黑脸娃娃": "黑脸娃娃",
            "童颜针": "童颜针",
            "胶原蛋白注射": "童颜针",
            "少女针注射": "童颜针",
            "童颜针注射": "童颜针",
            "无针水光针": "无针水光",
            "玻尿酸导入": "无针水光",
            "射频": "射频",
            "玻尿酸去法令纹": ["玻尿酸除法令纹", "玻尿酸全脸填充"],
            "祛疤针": "祛疤",
            "激光治疗": "激光祛斑",
            "点痣": "点痣",
            "乳房悬吊术": "胸部下垂矫正",
            "假体隆胸": "假体隆胸",
            "自体脂肪隆胸": "自体脂肪隆胸",
            "隆胸": "丰胸",
            "乳晕漂红": "乳晕漂红",
            "激光紧缩阴道": "女性私密紧致",
            "私处整形": "私密整形",
            "缩阴术": "缩阴术",
            "阴蒂整形": "阴蒂整形",
            "私密漂红": "私密漂红",
            "包皮手术": "男性私密",
            "托槽矫正": "牙齿矫正",
            "隐形矫正": "牙齿矫正",
            "龅牙矫正": "牙齿矫正",
            "冷光美白": "牙齿美白",
            "洗牙": "洗牙",
            "贵金属烤瓷牙": "补牙",
            "镶牙": "种植牙",
            "厚唇改薄": "厚唇改薄术",
            "嘴角上扬术": "M唇",
            "玻尿酸丰唇": "玻尿酸丰唇",
            "嘴综合": "凸嘴矫正",
            "嗨体注射": "嗨体",
            "半永久纹眉": ["纹眉", "半永久"],
            "提眉术": "提眉",
            "植眉": "植眉",
            "晶钻焕肤": "晶钻焕肤",
            "全切双眼皮去皮": "全切双眼皮去皮",
            "全切双眼皮去脂": "全切双眼皮去脂",
            "孕睫术": "孕睫术",
            "非剥落点阵": "非剥落点阵",
            "二氧化碳点阵": "二氧化碳点阵",
            "注射物取出": "注射物取出",
            "针灸": "针灸",
            "狐臭手术": "狐臭手术",
            "斜视矫正": "斜视矫正",
            "激光去纹身": "激光去纹身",
            "排毒养颜针": "排毒养颜针",
            "素颜针": "素颜针",
            "海藻针": "海藻针",
            "超声波洁牙": "超声波洁牙",
            "牙齿检查": "牙齿检查",
            "肤质测试": "肤质测试",
            "植皮": "植皮",
            "半永久纹身": "半永久纹身",
            "全切双眼皮修复": "全切双眼皮修复",
            "飞秒": "飞秒",
            "眼部提肌": "眼部提肌",
            "拔罐减肥": "拔罐减肥",
            "修复手术": "修复手术",
            "半永久纹唇": "半永久纹唇",
            "阴唇整形": "阴唇整形",
            "G点注射": "G点注射",
            "乳头再造": "乳头再造",
            "根管治疗": "根管治疗",
            "正颌手术": "正颌手术",
            "取颊脂垫": "取颊脂垫",
            "激光洗眼线": "激光洗眼线",
            "激光洗唇线": "激光洗唇线",
            "丽芙莎EPT自体抗衰": "丽芙莎EPT自体抗衰",
            "中医减肥": "中医减肥",
            "飞梭镭射": "飞梭镭射",
            "剥落点阵": "剥落点阵",
            "拉皮手术": "拉皮手术",
            "招风耳矫正": "招风耳矫正",
            "三文鱼水光针": "三文鱼水光针",
            "染料激光": "染料激光",
            "无针线雕": "无针线雕",
            "刮痧": "刮痧",
            "埋线避孕": "埋线避孕",
            "半永久睫毛线": "半永久睫毛线",
            "深蓝射频": "深蓝射频",
            "丽肤美": "丽肤美",
            "肉毒素去狐臭": "肉毒素去狐臭",
            "美提塑": "美提塑",
            "肉毒素治疗多汗": "肉毒素治疗多汗",
            "小腿神经阻断术": "小腿神经阻断术",
            "背部吸脂": "背部吸脂",
            "吸脂去副乳": "吸脂去副乳",
            "肉毒素瘦小腿": "肉毒素瘦小腿",
            "肉毒素去面部细纹": "肉毒素去面部细纹",
            "肉毒素去动态纹": "肉毒素去动态纹",
            "肉毒素去鼻背纹": "肉毒素去鼻背纹",
            "肉毒素去木偶纹": "肉毒素去木偶纹",
            "肉毒素去川字纹": "肉毒素去川字纹",
            "肉毒素去鱼尾纹": "肉毒素去鱼尾纹",
            "肉毒素去法令纹": "肉毒素去法令纹",
            "假体垫眉弓": "假体垫眉弓",
            "玻尿酸丰耳垂": "玻尿酸丰耳垂",
            "下巴截骨术": "下巴截骨术",
            "面部不对称矫正": "面部不对称矫正",
            "假体丰太阳穴": "假体丰太阳穴",
            "假体丰额头": "假体丰额头",
            "鹰钩鼻矫正": "鹰钩鼻矫正",
            "自体软骨垫鼻尖": "自体软骨垫鼻尖",
            "耳软骨复合隆鼻": "耳软骨复合隆鼻",
            "月光脱毛": "月光脱毛",
            "上眼睑去脂": "上眼睑去脂",
            "变性手术": "变性手术",
            "大脚骨矫正": "大脚骨矫正",
            "耳再造": "耳再造",
            "种植胡须": "种植胡须",
            "种植睫毛": "种植睫毛",
            "提可塑": "提可塑",
            "术唯可水光针": "术唯可水光针",
            "英国离子刀": "英国离子刀",
            "小切口手术提升": "小切口手术提升",
            "内窥镜手术提升": "内窥镜手术提升",
            "射频紧肤": "射频紧肤",
            "线肽水光": "线肽水光",
            "胎盘素注射": "胎盘素注射",
            "乳晕缩小术": "乳晕缩小术",
            "乳房缩小术": "乳房缩小术",
            "干细胞疗法": "干细胞疗法",
            "牙齿贴面": "牙齿贴面",
            "牙周治疗": "牙周治疗",
            "离子刀": "离子刀",
            "动氧瘦身": "动氧瘦身",
            "黄金焕肤": "黄金焕肤",
            "面部除皱术": "面部除皱术",
            "露龈笑矫正": "露龈笑矫正",
            "正骨术": "正骨术"
        }

        return old_new_mapping_dict
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return dict()


def get_fresh_tag_set():
    try:
        fresh_tag_list = ['瘦脸针',
                          '水光针',
                          '光子嫩肤',
                          '热玛吉',
                          '瘦腿针',
                          '超声刀',
                          '面部吸脂',
                          '瘦肩针',
                          '皮秒',
                          '果酸焕肤',
                          '热拉提',
                          '微针',
                          '牙齿矫正',
                          '超皮秒',
                          '点阵激光',
                          '植发',
                          '小气泡',
                          '双眼皮修复',
                          '自体脂肪隆胸',
                          '鼻翼缩小',
                          '假体隆胸',
                          '玻尿酸丰下巴',
                          '埋线双眼皮',
                          '纹眉',
                          '颧骨内推',
                          '拉皮',
                          '玻尿酸隆鼻',
                          '女性私密紧致',
                          '嗨体',
                          '溶脂针瘦脸',
                          '黄金微针',
                          '磨骨',
                          '肋骨鼻',
                          '洗牙',
                          '植发际线',
                          '光纤溶脂',
                          '点痣',
                          '下颌角切除',
                          '切开双眼皮',
                          '腰腹吸脂',
                          '激光祛斑',
                          '白瓷娃娃',
                          '大腿吸脂',
                          '假体下巴',
                          '除皱针注射',
                          '溶解酶',
                          '吸脂瘦手臂',
                          '微针祛痘坑',
                          '厚唇改薄',
                          '玻尿酸',
                          '大分子玻尿酸',
                          '耳软骨',
                          '鼻中隔软骨',
                          '肋软骨',
                          '硅胶',
                          '膨体',
                          '假体',
                          '自体真皮',
                          '自体脂肪',
                          '自体软骨',
                          '自体血清',
                          '溶解酶',
                          '嗨体',
                          '胶原蛋白',
                          '双美胶原蛋白',
                          '黄金',
                          '药物',
                          '生长因子',
                          '肉毒素',
                          '埋线提升',
                          '悦升线',
                          '蛋白线',
                          '水杨酸',
                          '果酸',
                          '杏仁酸',
                          '奥美定',
                          '干细胞',
                          '纳米树脂',
                          '黑脸娃娃',
                          '眼睑下至',
                          '童颜针',
                          '微笑唇',
                          '减肥',
                          '瘦身',
                          '隆鼻',
                          'V脸',
                          '祛斑',
                          '祛痣',
                          '祛黑头',
                          '祛疤',
                          '祛痘',
                          '溶脂',
                          '吸脂',
                          '嘟嘟唇',
                          '丰唇',
                          '丰下巴',
                          '丰胸',
                          '皮秒',
                          '蜂巢皮秒',
                          '超皮秒',
                          '深蓝射频',
                          '美瞳',
                          '提眉',
                          '纹眉',
                          '孕睫',
                          '瓷贴面',
                          '全瓷牙',
                          '美容冠',
                          '黄金微雕',
                          '微雕',
                          '削骨',
                          '截骨',
                          '脂肪胶',
                          'prp',
                          '轮廓针',
                          '水光针',
                          '婴儿针',
                          '三文鱼针',
                          '少女针',
                          '素颜针',
                          '瘦脸针',
                          '熊猫针',
                          '瘦腿针',
                          '小气泡',
                          '正颌',
                          '一针降颧骨',
                          '脱毛',
                          '近视',
                          '面部提升',
                          '嫩肤',
                          '镭射净肤',
                          '红蓝光',
                          '二氧化碳点阵',
                          '狐臭',
                          '清洁',
                          '补水',
                          '内窥镜',
                          '热立塑',
                          '威塑',
                          '优立塑',
                          '酷塑',
                          '调Q激光',
                          'DPL',
                          '染料激光',
                          '体检',
                          '产后',
                          '正骨术',
                          '隔空溶脂',
                          'pst',
                          '唇裂',
                          '塑身',
                          '微晶瓷',
                          'ICL晶体植入',
                          '全飞秒',
                          '半飞秒',
                          '根管治疗',
                          '抗衰',
                          '紧致',
                          '飞梭雷射',
                          '三点双眼皮',
                          '颊脂垫',
                          '嫩红',
                          '眶隔脂肪释放',
                          '针清',
                          '美白',
                          '冷光美白',
                          '美白仓',
                          '小腿神经阻断',
                          '正畸',
                          '变性',
                          '干细胞疗法',
                          '月光脱毛',
                          '火凤凰溶脂',
                          '微拉美',
                          '剥落点阵',
                          '非剥落点阵',
                          '面部',
                          '全身',
                          '大腿',
                          '小腿',
                          '毛孔',
                          '敏感肌',
                          '鸡皮肤',
                          '轮廓',
                          '腿型',
                          'o型腿',
                          '背部',
                          '手臂',
                          '脂肪粒',
                          '痘痘',
                          '痘印',
                          '痘坑',
                          '色素',
                          '大脚骨',
                          '骨骼',
                          '疤痕',
                          '腰腹',
                          '腹壁',
                          '肩膀',
                          '皮肤',
                          '牙齿',
                          '口腔',
                          '视力',
                          '龋齿',
                          '嘴唇',
                          '人中',
                          '私处',
                          '臀部',
                          '内眼角',
                          '外眼角',
                          '眼角',
                          '眼睑',
                          '眼袋',
                          '眼纹',
                          '眼线',
                          '上眼睑',
                          '下眼睑',
                          '双眼皮',
                          '眼泡',
                          '黑头',
                          '黑眼圈',
                          '太阳穴',
                          '卧蚕',
                          '颧骨',
                          '泪沟',
                          '眼睛',
                          '酒窝',
                          '眉毛',
                          '睫毛',
                          '鼻毛',
                          '唇毛',
                          '瓜子脸',
                          '皱纹',
                          '妊娠纹',
                          '苹果肌',
                          '发际线',
                          '头发',
                          '胡须',
                          '下颌',
                          '下颚',
                          '下巴',
                          '双颚',
                          '痣',
                          '眉弓',
                          '颧弓',
                          '额头',
                          '嘴巴',
                          '黄褐斑',
                          '鼻子',
                          '鼻尖',
                          '鼻翼',
                          '鼻骨',
                          '鼻孔',
                          '鼻背',
                          '鼻基底',
                          '鼻小柱',
                          '驼峰鼻',
                          '宽鼻',
                          '歪鼻',
                          '鹰钩鼻',
                          '朝天鼻',
                          '红血丝',
                          '泪腺',
                          '耳朵',
                          '招风耳',
                          '唇珠',
                          '唇弓',
                          '咬肌',
                          '嘴角',
                          '面颊', "阴道", "阴蒂", "大阴唇", "小阴唇", "G点", "包皮", "阴茎", "性腺", "处女膜", "比基尼线",
                          "抬头纹", "川字纹", "法令纹", "动态纹", "颈纹", "细纹", "鱼尾纹",
                          "双下巴", "长下巴", "短下巴", "下颌角切除术", "M唇", "瘦身",
                          "抽脂", "隆胸", "丰乳房", "孕睫术", "眶隔脂肪释放术", "小腿神经阻断术"]

        return set(fresh_tag_list)
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return set()


def get_fresh_tag_dict():
    try:
        fresh_tag_dict = {
            "双眼皮": "双眼皮",
            "埋线双眼皮": "双眼皮",
            "切开双眼皮": "双眼皮",
            "微创双眼皮": "双眼皮",
            "双眼皮修复": "双眼皮",
            "眼综合": "眼部",
            "祛眼袋": "眼袋",
            "开眼角": "眼角",
            "祛黑眼圈": "黑眼圈",
            "眼睑下至": "眼睑",
            "眼袋修复": "眼部",
            "卧蚕手术修复": "眼部",
            "卧蚕": "眼部",
            "提眉修复": "眼部",
            "开眼角修复": "眼部",
            "玻尿酸填充泪沟": "泪沟",
            "隆鼻": "鼻",
            "鼻基底": "鼻基底",
            "鼻骨内推": "鼻",
            "鼻翼缩小": "鼻翼",
            "缩小鼻头": "鼻头",
            "鼻小柱延长": "鼻小柱",
            "鼻修复": "鼻",
            "鼻综合": "鼻",
            "吸脂瘦脸": "脸",
            "溶脂针瘦脸": "脸",
            "瘦脸针": "脸",
            "磨骨": "脸",
            "面部提升": "脸",
            "射频提升": "脸",
            "面部填充": "脸",
            "面吸": "脸",
            "自体脂肪全面部填充": "脸",
            "玻尿酸丰太阳穴": "脸",
            "玻尿酸全脸填充": "脸",
            "削骨": "脸",
            "轮廓针": "脸",
            "面部吸脂": "脸",
            "玻尿酸丰下巴": "下巴",
            "假体下巴": "下巴",
            "硅胶垫下巴": "下巴",
            "吸脂祛双下巴": "下巴",
            "下颌角切除术": "下颌角",
            "下颌缘提升": "下颌角",
            "人中缩短": "人中",
            "颧骨降低": "颧骨",
            "颧骨内推": "颧骨",
            "颧弓内推": "颧骨",
            "玻尿酸填充丰苹果肌": "颧骨",
            "太阳穴填充": "太阳穴",
            "吸脂": ["腿", "身体"],
            "脂肪填充": "身体",
            "溶脂针": "身体",
            "溶脂": "身体",
            "光纤溶脂": "身体",
            "自体脂肪": "身体",
            "埋线减肥": "身体",
            "全身吸脂": "身体",
            "冷冻溶脂": "身体",
            "射频溶脂": "身体",
            "全身美白": "身体",
            "脱毛": "毛发",
            "激光脱毛": "毛发",
            "毛发移植": "毛发",
            "种植发际线": "毛发",
            "植发": "毛发",
            "吸脂瘦手臂": "手臂",
            "瘦腿针": "腿",
            "大腿吸脂": "腿",
            "小腿神经阻断术": "腿",
            "小腿吸脂": "腿",
            "腰腹吸脂": "腰腹",
            "腹壁成形术": "腰腹",
            "瘦肩针": "肩",
            "丰臀": "臀",
            "臀部吸脂": "",
            "玻尿酸": "皮肤",
            "水光针": "皮肤",
            "光子嫩肤": "皮肤",
            "美白针": "皮肤",
            "热玛吉": "皮肤",
            "热拉提": "皮肤",
            "祛斑": "皮肤",
            "超声刀": "皮肤",
            "皮秒": "皮肤",
            "果酸焕肤": "皮肤",
            "祛痘": "皮肤",
            "微针": "皮肤",
            "超皮秒": "皮肤",
            "点阵激光": "皮肤",
            "小气泡": "皮肤",
            "小气泡美肤": "皮肤",
            "皮秒激光": "皮肤",
            "拉皮": "皮肤",
            "黄金微针": "皮肤",
            "白瓷娃娃": "皮肤",
            "肉毒素": "皮肤",
            "除皱针注射": "皮肤",
            "黑脸娃娃": "皮肤",
            "童颜针": "皮肤",
            "无针水光": "皮肤",
            "埋线提升": "皮肤",
            "埋线": "皮肤",
            "除皱针": "皮肤",
            "射频": "皮肤",
            "深蓝射频": "皮肤",
            "黄金微雕": "皮肤",
            "玻尿酸除法令纹": "皮肤",
            "美瞳线": "皮肤",
            "酒窝成形术": "皮肤",
            "婴儿针": "皮肤",
            "胶原蛋白注射": "皮肤",
            "prp": "皮肤",
            "祛疤": "皮肤",
            "激光祛疤": "皮肤",
            "激光祛斑": "皮肤",
            "点痣": "皮肤",
            "激光点痣": "皮肤",
            "胸部下垂矫正": "胸",
            "假体隆胸": "胸",
            "自体脂肪隆胸": "胸",
            "丰胸": "胸",
            "乳晕漂红": "胸",
            "乳头缩小": "胸",
            "女性私密紧致": "私密",
            "私密整形": "私密",
            "缩阴术": "私密",
            "阴蒂整形": "私密",
            "私密漂红": "私密",
            "处女膜修复": "私密",
            "小阴唇手术": "私密",
            "私密脱毛": "私密",
            "男性私密": "私密",
            "牙齿矫正": "牙齿",
            "牙齿美白": "牙齿",
            "洗牙": "牙齿",
            "补牙": "牙齿",
            "冷光美白": "牙齿",
            "种植牙": "牙齿",
            "厚唇改薄术": "唇",
            "微笑唇": "唇",
            "丰唇": "唇",
            "M唇": "唇",
            "玻尿酸丰唇": "唇",
            "嘟嘟唇": "唇",
            "凸嘴矫正": "唇",
            "嗨体": "颈",
            "纹眉": "眉",
            "半永久": "眉",
            "洗眉": "眉",
            "提眉": "眉",
            "切眉": "眉",
            "植眉": "眉",
            "晶钻焕肤": "脸",
            "肉毒素颏肌放松": "下巴",
            "全切双眼皮去皮": "双眼皮",
            "全切双眼皮去脂": "双眼皮",
            "孕睫术": "眼部",
            "非剥落点阵": "皮肤",
            "二氧化碳点阵": "皮肤",
            "注射物取出": "修复",
            "针灸": "中医",
            "狐臭手术": "腋下",
            "斜视矫正": "眼",
            "激光去纹身": "纹绣",
            "排毒养颜针": "皮肤",
            "素颜针": "皮肤",
            "海藻针": "皮肤",
            "超声波洁牙": "牙齿",
            "牙齿检查": "牙齿",
            "肤质测试": "皮肤",
            "植皮": "皮肤",
            "半永久纹身": "纹绣",
            "全切双眼皮修复": "双眼皮",
            "飞秒": "眼",
            "眼部提肌": "眼",
            "拔罐减肥": "中医",
            "修复手术": "修复",
            "半永久纹唇": "唇",
            "阴唇整形": "私密",
            "G点注射": "私密",
            "乳头再造": "胸",
            "根管治疗": "牙齿",
            "正颌手术": "牙齿",
            "取颊脂垫": "脸",
            "激光洗眼线": "纹绣",
            "激光洗唇线": "纹绣",
            "丽芙莎EPT自体抗衰": "抗衰",
            "中医减肥": "其他",
            "飞梭镭射": "皮肤",
            "剥落点阵": "皮肤",
            "拉皮手术": "抗衰",
            "招风耳矫正": "耳",
            "三文鱼水光针": "皮肤",
            "染料激光": "皮肤",
            "无针线雕": "抗衰",
            "刮痧": "中医",
            "埋线避孕": "其他",
            "半永久睫毛线": "纹绣",
            "丽肤美": "皮肤",
            "肉毒素去狐臭": "腋下",
            "美提塑": "皮肤",
            "肉毒素治疗多汗": "腋下",
            "背部吸脂": "背部",
            "吸脂去副乳": "胸",
            "肉毒素瘦小腿": "腿",
            "肉毒素去面部细纹": "脸",
            "肉毒素去动态纹": "抗衰",
            "肉毒素去鼻背纹": "抗衰",
            "肉毒素去木偶纹": "抗衰",
            "肉毒素去川字纹": "抗衰",
            "肉毒素去鱼尾纹": "抗衰",
            "肉毒素去法令纹": "抗衰",
            "假体垫眉弓": "眉",
            "玻尿酸丰耳垂": "耳",
            "玻尿酸丰卧蚕": "眼",
            "下巴截骨术": "下巴",
            "面部不对称矫正": "脸",
            "假体丰太阳穴": "太阳穴",
            "假体丰额头": "脸",
            "鹰钩鼻矫正": "鼻矫正",
            "自体软骨垫鼻尖": "鼻头",
            "耳软骨复合隆鼻": "鼻",
            "月光脱毛": "毛发",
            "上眼睑去脂": "眼睑",
            "变性手术": "其他",
            "大脚骨矫正": "其他",
            "耳再造": "耳",
            "种植胡须": "毛发",
            "种植睫毛": "毛发",
            "提可塑": "皮肤",
            "术唯可水光针": "皮肤",
            "英国离子刀": "皮肤",
            "小切口手术提升": "抗衰",
            "内窥镜手术提升": "脸",
            "射频紧肤": "皮肤",
            "线肽水光": "皮肤",
            "胎盘素注射": "皮肤",
            "乳晕缩小术": "胸",
            "乳房缩小术": "胸",
            "干细胞疗法": "皮肤",
            "牙齿贴面": "牙齿",
            "牙周治疗": "牙齿",
            "离子刀": "皮肤",
            "动氧瘦身": "身体",
            "黄金焕肤": "皮肤",
            "面部除皱术": "脸",
            "露龈笑矫正": "牙齿",
            "正骨术": "脸"
        }

        return fresh_tag_dict
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return dict()


def get_old_tag_mapping_new_tag(fresh_tag_name_set, service_info_word):
    try:
        if service_info_word and len(service_info_word) > 0:
            es = get_es()
            body = {
                'text': service_info_word,
                'analyzer': "gm_default_index"
            }
            synonym_es_res = es_indices_analyze(doc_type="service", body=body, es=es)
            synonym_term_list = wordrel_synonym_list(analyze_res=synonym_es_res, total_match_synonym=True,
                                                     ori_quey=service_info_word)
            tag_mapping_dict = get_old_new_tag_mapping()

            for synonym_term in synonym_term_list:
                if synonym_term in tag_mapping_dict:
                    if isinstance(tag_mapping_dict[synonym_term], list):
                        for term_key in tag_mapping_dict[synonym_term]:
                            fresh_tag_name_set.add(term_key)
                    else:
                        fresh_tag_name_set.add(tag_mapping_dict[synonym_term])
        return True
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return False


def get_fresh_tag_name_list(fresh_tag_name_set, service_info_word):
    try:
        if service_info_word and len(service_info_word) > 0:
            es = get_es()
            body = {
                'text': service_info_word,
                'analyzer': "gm_default_index"
            }
            synonym_es_res = es_indices_analyze(doc_type="service", body=body, es=es)
            synonym_term_list = wordrel_synonym_list(synonym_es_res)
            fresh_tag_set = get_fresh_tag_set()

            for synonym_term in synonym_term_list:
                if synonym_term in fresh_tag_set:
                    fresh_tag_name_set.add(synonym_term)

            for fresh_tag in fresh_tag_set:
                find_index = service_info_word.find(fresh_tag)
                if find_index >= 0:
                    fresh_tag_name_set.add(fresh_tag)

        return True
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())
        return False


def get_service(instance):
    def get_hospital_info(s):
        h = {
            'id': s.hospital.id,
            'name': s.hospital.name,
        }
        # hospital position info
        if s.hospital.city:
            h['city_name'] = s.hospital.city.name
            h['city_province_name'] = s.hospital.city.province.name
            h.update(get_area_tag_info(s.hospital.city))
        return h

    def hospital_type2(s):
        try:
            # check if type is oversea
            b = s.doctor.hospital.city.province.country_id != 'china'
            b = b or s.doctor.hospital.city.province_id in ('aomen', 'xianggang', 'taiwan')
            if b:
                return '9'

            else:
                return s.doctor.hospital.hospital_type

        except:
            return s.doctor.hospital.hospital_type

    def get_doctor_info(s):
        d = {
            'id': s.doctor.id,
            'name': s.doctor.name,
            'name_by_standard_analyzer': s.doctor.name,
            'title': s.doctor.title,
            'famous_doctor': s.doctor.big,
        }
        # doctor hospital info
        if s.doctor.hospital:
            d['hospital'] = {
                'id': s.doctor.hospital.id,
                'name': s.doctor.hospital.name,
                'name_by_standard_analyzer': s.doctor.hospital.name,
                'hospital_type': s.doctor.hospital.hospital_type,
                'city_count': s.doctor.hospital.city_count,
                'chain_count': s.doctor.hospital.chain_count,
                'area_count': s.doctor.hospital.area_count,
                'hospital_type2': hospital_type2(s),
                'is_high_quality': s.doctor.hospital.is_high_quality,
            }
            # doctor hospital position info
            if s.doctor.hospital.city:
                h = d['hospital']
                h['city_name'] = s.doctor.hospital.city.name
                h['city_province_name'] = s.doctor.hospital.city.province.name
                h['city_name_by_standard_analyzer'] = s.doctor.hospital.city.name
                h['city_province_name_by_standard_analyzer'] = s.doctor.hospital.city.province.name
                h.update(get_area_tag_info(s.doctor.hospital.city))
            if s.doctor.hospital.officer:
                h = d['hospital']
                h['officer_name'] = s.doctor.hospital.officer.name
                h['officer_name_by_standard_analyzer'] = s.doctor.hospital.officer.name

        return d

    # alias
    s = instance

    if not s.check_is_valid_for_es():
        return {
            'id': s.id,
            'is_online': False,
        }

    res = {
        'id': s.id,
        'is_online': True,  # 如果有任何会导致 is_online 为 False的，应该在上面check_is_valid_for_es直接处理掉
        'name': s.name,
        'is_sink': s.is_sink,
        'short_description': s.short_description,
        'short_description_by_standard_analyzer': s.short_description,
        'short_description_pre': s.short_description,
        'detail_description': s.detail_description,
        'ordering': s.ordering,
        'start_time': tzlc(s.start_time),
        'end_time': tzlc(s.end_time) if s.end_time else MAX_TIME,
        'start_time_long': int(time.mktime(tzlc(s.start_time).timetuple())),
        'is_can_be_sold': s.is_can_be_sold_for_es(),
        'channel': s.channel,
        'is_floor_price': s.is_floor_price,
        'share_get_cashback': s.share_get_cashback,
        'rating': s.rating,
        'tip': s.tip,
        'is_stage': s.is_stage,
        'is_insurance': s.is_support_insurance,
        'is_fenqi': s.is_support_renmai_no_pay,
        # 医生医院自定义排序默认值
        'doctor_customize_sort': 9223372036854775807,  # 2**63-1
        'hospital_customize_sort': 9223372036854775807,  # 2**63-1
    }
    if s.end_time:
        res['end_time_long'] = int(time.mktime(tzlc(s.end_time).timetuple()))
    else:
        res['end_time_long'] = 2147483647
    # http://wiki.wanmeizhensuo.com/pages/viewpage.action?pageId=5479952
    core_words = search_dic_cache.get(DIC_CACHE_KEY)
    if core_words:
        # TODO: cached in thread_local
        objs = json.loads(core_words)
        w = chain(objs['doctor_dict'], objs['hospital_dict'])
        sd = s.short_description
        for i in w:
            # in case empty string
            i = i.strip()
            if not i or len(i) < 2:
                continue

            if i in sd:
                sd = sd.replace(i, ' ')

        res['short_description'] = sd

    # sink
    if s.tickets_result:
        tzlc_ticket_sink_start_time = tzlc(s.tickets_result.start_sink)
        res['ticket_sink_start_time'] = tzlc_ticket_sink_start_time
        talc_ticket_sink_end_time = tzlc(s.tickets_result.end_sink)
        res['ticket_sink_end_time'] = talc_ticket_sink_end_time
        res["ticket_sink_start_time_long"] = int(time.mktime(tzlc_ticket_sink_start_time.timetuple()))
        res["ticket_sink_end_time_long"] = int(time.mktime(talc_ticket_sink_end_time.timetuple()))

    # pv
    try:
        date_str = _get_cur_date()
        date_str = date_str.strftime('%Y-%m-%d')
        res['pv'] = mars_call('/api/service/pv',
                              params={'record_time': date_str, 'service_id': s.id}, from_cache=True)['pv_cnt']
    except MarsDataError as e:
        logger = logging.getLogger('mars_call')
        logger.warning('Mars call error for service_id[%s]: %s' % (s.id, e))
        res['pv'] = 0

    # 销量使用假数据
    # res['sales_count'] = s.get_dajiadouzaimai_rank_for_es()
    res['sales_count'] = s.sell_amount_display

    # hospital info
    if s.hospital:
        res['hospital'] = get_hospital_info(s)

    # doctor info
    if s.doctor and s.doctor.is_online:
        res['doctor'] = get_doctor_info(s)
        # 医生自定义的排序
        doc_custom_sort = s.doctor.service_ranks.filter(service_id=s.id)
        if doc_custom_sort:
            res['doctor_customize_sort'] = doc_custom_sort[0].rank

    # location info
    if s.doctor and s.doctor.hospital:
        res['location'] = {
            'lon': s.doctor.hospital.baidu_loc_lng,
            'lat': s.doctor.hospital.baidu_loc_lat,
        }
        # 医院自定义的排序
        officer = s.doctor.get_officer()
        if officer:
            hos_custom_sort = officer.service_ranks.filter(service_id=s.id)
            if hos_custom_sort:
                res['hospital_customize_sort'] = hos_custom_sort[0].rank

    # closure tags
    closure_tags = TagControl.get_ancestors(
        initial_set=s.tags.filter(is_online=True),
        exclude_init=False,
        is_online_only=True)

    # 添加公立／私立TAG
    try:
        tag_id = settings.PUBLIC_TAG_ID if s.doctor.hospital.hospital_type == HOSPITAL_TYPE.PUBLIC else settings.PRIVATE_TAG_ID
        closure_tags.append(
            Tag.objects.get(pk=tag_id)
        )
    except AttributeError:
        # 医生未关联Hospital
        pass

    # 添加地域TAG
    try:
        closure_tags.append(
            Tag.objects.get(pk=s.doctor.hospital.city.tag_id)
        )
    except (Tag.DoesNotExist, AttributeError):
        pass

    res['closure_tag_ids'] = [t.id for t in closure_tags]
    res['closure_tags'] = [t.name for t in closure_tags]
    res['closure_tags_by_standard_analyzer'] = [t.name for t in closure_tags]

    # discount
    if hasattr(s, 'discount_price'):
        res['discount'] = s.discount_price[1] * 1.0 / s.discount_price[0]
    else:
        res['discount'] = 1.0

    # seckill
    res['seckill_time'] = [{
        'start_time': tzlc(t['seckill_start_time']),
        'end_time': tzlc(t['seckill_end_time']),
    } for t in s.seckill_time_range_for_es()]

    # case count
    service_diary_count = get_service_diary_count([s.id])
    res['case_count'] = service_diary_count[0]['diary_count']

    # special rank
    specialitems = s.get_special_rank_for_es()
    res['special_rank'] = [{
        'special_id': special_id,
        'rank': special_info['rank'],
    } for (special_id, special_info) in specialitems.items()]

    # special info
    res['special'] = [{
        'id': special_id,
        'item_id': special_info['item_id'],
        'sku_id': special_info['sku_id'],
        'position': special_info['position'],
        'has_pos': special_info['has_pos'],
    } for special_id, special_info in specialitems.items()]

    res['floor_id'] = []
    for _, special_info in specialitems.items():
        res['floor_id'].extend(special_info.get("floor_id", []))

    # 智能排序rank
    res['smart_rank'] = get_smart_rank(s)
    res['smart_rank2'] = get_smart_rank_new(s)
    res["smart_rank_v4"] = get_smart_rank_v4(s)
    # recommend service rank
    # http://wiki.gengmei.cc/pages/viewpage.action?pageId=3362398
    res['recommend_rank'] = get_recommend_rank(s)

    # 价格
    price_info = s.get_price_range_for_es()
    res['periodic_price'] = [{
        'start_time': tzlc(p['start_time']),
        'end_time': tzlc(p['end_time']),
        'price': p['price'],
    } for p in price_info[0]]
    res['lowest_price'] = [{
        'start_time': tzlc(p['start_time']),
        'end_time': tzlc(p['end_time']),
        'end_time_long': int(time.mktime(tzlc(p['end_time']).timetuple())),
        'start_time_long': int(time.mktime(tzlc(p['start_time']).timetuple())),
        'price': p['price'],
    } for p in price_info[1]]

    res["can_sold_time_range"] = [{
        "start_time": tzlc(p[0]),
        "end_time": tzlc(p[1])
    } for p in s.can_be_sold_time_range_list_for_es()]

    sku_price_range_list = s.get_sku_price_range_list_for_es()
    sku = []
    fresh_tag_name_set = set()
    get_fresh_tag_name_list(fresh_tag_name_set=fresh_tag_name_set, service_info_word=s.short_description)
    for p in sku_price_range_list:
        from api.models.service import ServiceItem
        parent_id = ServiceItem.objects.filter(id=p['sku_id'], parent_id=0).values_list("parent_id", flat=True).first()
        logging.info("get parent_id:%s" % parent_id)

        if parent_id == 0:
            data = {
                'sku_id': p['sku_id'],
                'start_time': tzlc(p['start_time']),
                'end_time': tzlc(p['end_time']),
                "price": p['price'],
                "name": p['name'],
                "name_by_standard_analyzer": p['name'],
                "sku_rank": p['sku_rank'],
                "price_type": p['price_type'],
            }

            sku.append(data)
            logging.info("get data:%s" % data)

        get_fresh_tag_name_list(fresh_tag_name_set=fresh_tag_name_set, service_info_word=p["name"])

    res['sku_list'] = sku
    for old_tag_name in res['closure_tags']:
        # get_old_tag_mapping_new_tag(fresh_tag_name_set=fresh_tag_name_set,service_info_word=old_tag_name)
        get_fresh_tag_name_list(fresh_tag_name_set=fresh_tag_name_set, service_info_word=old_tag_name)

    new_sku = []
    for p in sku_price_range_list:
        from api.models.service import ServiceItem
        parent_id = ServiceItem.objects.filter(id=p['sku_id'], is_delete=False).values_list("parent_id",
                                                                                            flat=True).first()
        is_delete_judg = ServiceItem.objects.filter(id=parent_id).values_list("is_delete", flat=True).first()

        data = {
            'sku_id': p['sku_id'],
            'start_time': tzlc(p['start_time']),
            'end_time': tzlc(p['end_time']),
            "price": p['price'],
            "name": p['name'],
            "sku_rank": p['sku_rank'],
            "price_type": p['price_type'],
        }
        if parent_id and is_delete_judg == False:
            data['parent_id'] = parent_id

        new_sku.append(data)
    res['new_sku_list'] = new_sku
    new_specialitems = s.get_new_sku_special_rank_for_es()
    res['new_sku_special'] = [{
        'id': special_id,
        'item_id': special_info['item_id'],
        'sku_id': special_info['sku_id'],
        'position': special_info['position'],
        'has_pos': special_info['has_pos'],
    } for special_id, special_info in new_specialitems.items()]

    if len(res['new_sku_special']) > 0:
        for _, special_info in new_specialitems.items():
            res['floor_id'].extend(special_info.get("floor_id", []))

    if len(fresh_tag_name_set) > 0:
        res["fresh_closure_tags"] = list(fresh_tag_name_set)
    else:
        res["fresh_closure_tags"] = ["not_found"]
        # redis_name = "doris:new2_fresh_tags:no_fresh_tag_service_set"
        # redis_client.sadd(redis_name, s.id)

    # 广告
    res['advertise_position'], res['advertise_searchwords'], res['advertise_info'] = \
        get_advertise_info(s)

    res['query_pv'] = []
    res['max_query_pv'] = []
    dby = (datetime.datetime.now() - datetime.timedelta(days=2)).strftime('%Y%m%d')  # day before yesterday
    for stat in ServiceStat.objects.filter(service_id=s.id).filter(stat_date=dby).filter(max_pv=0):
        res['query_pv'].append(
            {
                'query': stat.query,
                'pv': stat.pv,
            }
        )
        max_stat = ServiceStat.objects.get(query=stat.query, max_pv__gt=0, stat_date=dby)
        res['max_query_pv'].append(
            {
                'query': max_stat.query,
                'pv': max_stat.max_pv,
            }
        )
    # 购买过的用户
    res['ordered_user_ids'] = list(set(
        Order.objects.filter(service=s, status__in=ORDER_BOUGHT_STATUS).values_list('user_id', flat=True)
    ))

    # doris_data = get_service_stat(s.id)
    # tag_heats = doris_data.get('tag_heat')
    # if tag_heats:
    #    res["tag_heat"] = tag_heats

    res['service_type'] = s.service_type
    res['gift_rank'] = s.get_gift_rank_for_es()
    # 机构罚单下沉
    punishment = Punishment.get_punishment_by_doctor_id(s.doctor.id).get('service', None)
    if punishment and punishment.get('type', None) in ['limit', ]:
        res['org_sink_start_time'] = tzlc(punishment['start_time'])
        res['org_sink_end_time'] = tzlc(punishment['end_time'])
        res["org_sink_start_time_long"] = int(time.mktime(tzlc(punishment['start_time']).timetuple()))
        res["org_sink_end_time_long"] = int(time.mktime(tzlc(punishment['end_time']).timetuple()))
    # 美购医生的商户医生id
    res['merchant_doctor_id'] = doctor_merchant_map([s.doctor_id])[s.doctor_id]

    # add nearby city tags
    res['nearby_city_tags'] = []
    if s.doctor and s.doctor.hospital and s.doctor.hospital.city:
        cts = get_nearby_city_tag(s.doctor.hospital.city_id)
        res['nearby_city_tags'] = cts

    # 是否出价

    invoker = get_rpc_remote_invoker()
    rpc_client = invoker['artemis/cpc/is_promote'](service_id=instance.id)
    res['is_promote'] = rpc_client.unwrap()

    return res
